Code

Updated error handling
[ncmpc.git] / src / main.c
1 /* 
2  * $Id$
3  *
4  * (c) 2004 by Kalle Wallin <kaw@linux.se>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18  *
19  */
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <unistd.h>
24 #include <signal.h>
25 #include <string.h>
26 #include <glib.h>
28 #include "config.h"
29 #include "ncmpc.h"
30 #include "mpdclient.h"
31 #include "support.h"
32 #include "options.h"
33 #include "command.h"
34 #include "screen.h"
35 #include "conf.h"
37 static mpdclient_t   *mpd = NULL;
38 static gboolean connected = FALSE;
39 static GTimer      *timer = NULL;
41 static gchar *
42 error_msg(gchar *msg)
43 {
44   gchar *p;
46   if( (p=strchr(msg, '}' )) == NULL )
47     return msg;
48   while( p && *p && (*p=='}' || *p==' ') )
49     p++;
51   return p;
52 }
54 static void
55 error_callback(mpdclient_t *c, gint error, gchar *msg)
56 {
57   gint code = GET_ACK_ERROR_CODE(error);
59   error = error & 0xFF;
60   D("Error [%d:%d]> \"%s\"\n", error, c->connection->errorCode, msg);
61   switch(error)
62     {
63     case MPD_ERROR_CONNPORT:
64     case MPD_ERROR_NORESPONSE:
65       break;
66     case MPD_ERROR_ACK:
67       screen_status_printf("%s", error_msg(msg));
68       beep();
69       break;
70     default:
71       screen_status_printf("%s", msg);
72       doupdate();
73       beep();
74       connected = FALSE;
75     }
76 }
78 void
79 exit_and_cleanup(void)
80 {
81   screen_exit();
82   printf("\n");
83   if( mpd )
84     {
85       mpdclient_disconnect(mpd);
86       mpd = mpdclient_free(mpd);
87     }
88   g_free(options.host);
89   g_free(options.password);
90   if( timer )
91     g_timer_destroy(timer);
92 }
94 void
95 catch_sigint( int sig )
96 {
97   printf("\n%s\n", _("Exiting..."));
98   exit(EXIT_SUCCESS);
99 }
101 int 
102 main(int argc, const char *argv[])
104   options_t *options;
105   struct sigaction act;
106   const char *charset = NULL;
108 #ifdef HAVE_LOCALE_H
109   /* time and date formatting */
110   setlocale(LC_TIME,"");
111   /* charset */
112   setlocale(LC_CTYPE,"");
113   /* initialize charset conversions */
114   charset_init(g_get_charset(&charset));
115   D("charset: %s\n", charset);
116 #endif
118   /* initialize i18n support */
119 #ifdef ENABLE_NLS
120   setlocale(LC_MESSAGES, "");
121   bindtextdomain(GETTEXT_PACKAGE, LOCALE_DIR);
122   bind_textdomain_codeset(GETTEXT_PACKAGE, charset);
123   textdomain(GETTEXT_PACKAGE);
124 #endif
126   /* initialize options */
127   options = options_init();
129   /* parse command line options - 1 pass get configuration files */
130   options_parse(argc, argv);
131   
132   /* read configuration */
133   read_configuration(options);
134   
135   /* check key bindings */
136   if( check_key_bindings() )
137     {
138       fprintf(stderr, _("Confusing key bindings - exiting!\n"));
139       exit(EXIT_FAILURE);
140     }
142   /* parse command line options - 2 pass */
143   options_parse(argc, argv);
145   /* setup signal behavior - SIGINT */
146   sigemptyset( &act.sa_mask );
147   act.sa_flags    = 0;
148   act.sa_handler = catch_sigint;
149   if( sigaction( SIGINT, &act, NULL )<0 )
150     {
151       perror("signal");
152       exit(EXIT_FAILURE);
153     }
154   /* setup signal behavior - SIGTERM */
155   sigemptyset( &act.sa_mask );
156   act.sa_flags    = 0;
157   act.sa_handler = catch_sigint;
158   if( sigaction( SIGTERM, &act, NULL )<0 )
159     {
160       perror("sigaction()");
161       exit(EXIT_FAILURE);
162     }
164   /* set xterm title */
165   if( g_getenv("DISPLAY") )
166     printf("%c]0;%s%c", '\033', PACKAGE " version " VERSION, '\007');
168   /* install exit function */
169   atexit(exit_and_cleanup);
171   /* connect to our music player daemon */
172   mpd = mpdclient_new();
173   if( mpdclient_connect(mpd, 
174                         options->host, 
175                         options->port, 
176                         10.0, 
177                         options->password) )
178     {
179       exit(EXIT_FAILURE);
180     }
181   connected = TRUE;
182   D("Connected to MPD version %d.%d.%d\n",
183     mpd->connection->version[0],
184     mpd->connection->version[1],
185     mpd->connection->version[2]);
187   /* initialize curses */
188   screen_init(mpd);
190   /* install error callback function */
191   mpdclient_install_error_callback(mpd, error_callback);
193   /* initialize timer */
194   timer = g_timer_new();
196   connected = TRUE;
197   while( connected || options->reconnect )
198     {
199       static gdouble t = G_MAXDOUBLE;
201       if( connected && (t>=MPD_UPDATE_TIME || mpd->need_update) )
202         {
203           mpdclient_update(mpd);
204           g_timer_start(timer);
205         }
207       if( connected )
208         {
209           command_t cmd;
211           screen_update(mpd);
212           if( (cmd=get_keyboard_command()) != CMD_NONE )
213             {
214               screen_cmd(mpd, cmd);
215               if( cmd==CMD_VOLUME_UP || cmd==CMD_VOLUME_DOWN)
216                 /* make shure we dont update the volume yet */
217                 g_timer_start(timer);
218             }
219           else
220             screen_idle(mpd);
221         }
222       else if( options->reconnect )
223         {
224           screen_status_printf(_("Connecting to %s...  [Press %s to abort]"), 
225                                options->host, get_key_names(CMD_QUIT,0) );
227           if( get_keyboard_command_with_timeout(MPD_RECONNECT_TIME)==CMD_QUIT)
228             exit(EXIT_SUCCESS);
229           
230           if( mpdclient_connect(mpd,
231                                 options->host,
232                                 options->port, 
233                                 1.5,
234                                 options->password) == 0 )
235             {
236               screen_status_printf(_("Connected to %s!"), options->host);
237               connected = TRUE;
238             }     
239           doupdate();
240         }
242       t = g_timer_elapsed(timer, NULL);
243     }
244   exit(EXIT_FAILURE);