Code

Major cleanup of the mpd client code (mpc->mpdclient)
[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 <glib.h>
27 #include "config.h"
28 #include "ncmpc.h"
29 #include "mpdclient.h"
30 #include "support.h"
31 #include "options.h"
32 #include "command.h"
33 #include "screen.h"
34 #include "conf.h"
36 static mpdclient_t   *mpd = NULL;
37 static gboolean connected = FALSE;
38 static GTimer      *timer = NULL;
40 static void
41 error_callback(mpdclient_t *c, int error, char *msg)
42 {
43   D("error_callback> error=%d errorCode=%d errorAt=%d\n", 
44     error, c->connection->errorCode, c->connection->errorAt);
45   D("error_callback> \"%s\"\n", msg);
46   switch(error)
47     {
48     case MPD_ERROR_ACK:
49       screen_status_printf("%s", msg);
50       break;
51     default:
52       screen_status_printf(_("Lost connection to %s"), options.host);
53       connected = FALSE;
54     }
55   doupdate();
56 }
58 void
59 exit_and_cleanup(void)
60 {
61   screen_exit();
62   printf("\n");
63   if( mpd )
64     {
65       mpdclient_disconnect(mpd);
66       mpd = mpdclient_free(mpd);
67     }
68   g_free(options.host);
69   g_free(options.password);
70   if( timer )
71     g_timer_destroy(timer);
72 }
74 void
75 catch_sigint( int sig )
76 {
77   printf("\n%s\n", _("Exiting..."));
78   exit(EXIT_SUCCESS);
79 }
81 int 
82 main(int argc, const char *argv[])
83 {
84   options_t *options;
85   struct sigaction act;
86   const char *charset = NULL;
88 #ifdef HAVE_LOCALE_H
89   /* time and date formatting */
90   setlocale(LC_TIME,"");
91   /* charset */
92   setlocale(LC_CTYPE,"");
93   /* initialize charset conversions */
94   charset_init(g_get_charset(&charset));
95   D("charset: %s\n", charset);
96 #endif
98   /* initialize i18n support */
99 #ifdef ENABLE_NLS
100   setlocale(LC_MESSAGES, "");
101   bindtextdomain(GETTEXT_PACKAGE, LOCALE_DIR);
102   bind_textdomain_codeset(GETTEXT_PACKAGE, charset);
103   textdomain(GETTEXT_PACKAGE);
104 #endif
106   /* initialize options */
107   options = options_init();
109   /* parse command line options - 1 pass get configuration files */
110   options_parse(argc, argv);
111   
112   /* read configuration */
113   read_configuration(options);
114   
115   /* check key bindings */
116   if( check_key_bindings() )
117     {
118       fprintf(stderr, _("Confusing key bindings - exiting!\n"));
119       exit(EXIT_FAILURE);
120     }
122   /* parse command line options - 2 pass */
123   options_parse(argc, argv);
125   /* setup signal behavior - SIGINT */
126   sigemptyset( &act.sa_mask );
127   act.sa_flags    = 0;
128   act.sa_handler = catch_sigint;
129   if( sigaction( SIGINT, &act, NULL )<0 )
130     {
131       perror("signal");
132       exit(EXIT_FAILURE);
133     }
134   /* setup signal behavior - SIGTERM */
135   sigemptyset( &act.sa_mask );
136   act.sa_flags    = 0;
137   act.sa_handler = catch_sigint;
138   if( sigaction( SIGTERM, &act, NULL )<0 )
139     {
140       perror("sigaction()");
141       exit(EXIT_FAILURE);
142     }
144   /* set xterm title */
145   if( g_getenv("DISPLAY") )
146     printf("%c]0;%s%c", '\033', PACKAGE " version " VERSION, '\007');
148   /* install exit function */
149   atexit(exit_and_cleanup);
151   /* connect to our music player daemon */
152   mpd = mpdclient_new();
153   if( mpdclient_connect(mpd, 
154                         options->host, 
155                         options->port, 
156                         10.0, 
157                         options->password) )
158     {
159       exit(EXIT_FAILURE);
160     }
161   connected = TRUE;
162   D("Connected to MPD version %d.%d.%d\n",
163     mpd->connection->version[0],
164     mpd->connection->version[1],
165     mpd->connection->version[2]);
167   /* initialize curses */
168   screen_init(mpd);
170   /* install error callback function */
171   mpdclient_install_error_callback(mpd, error_callback);
173   /* initialize timer */
174   timer = g_timer_new();
176   connected = TRUE;
177   while( connected || options->reconnect )
178     {
179       static gdouble t = G_MAXDOUBLE;
181       if( connected && (t>=MPD_UPDATE_TIME || mpd->need_update) )
182         {
183           mpdclient_update(mpd);
184           g_timer_start(timer);
185         }
187       if( connected )
188         {
189           command_t cmd;
191           screen_update(mpd);
192           if( (cmd=get_keyboard_command()) != CMD_NONE )
193             {
194               screen_cmd(mpd, cmd);
195               if( cmd==CMD_VOLUME_UP || cmd==CMD_VOLUME_DOWN)
196                 /* make shure we dont update the volume yet */
197                 g_timer_start(timer);
198             }
199           else
200             screen_idle(mpd);
201         }
202       else if( options->reconnect )
203         {
204           screen_status_printf(_("Connecting to %s...  [Press %s to abort]"), 
205                                options->host, get_key_names(CMD_QUIT,0) );
206           doupdate();
208           if( get_keyboard_command_with_timeout(MPD_RECONNECT_TIME)==CMD_QUIT)
209             exit(EXIT_SUCCESS);
210           
211           if( mpdclient_connect(mpd,
212                                 options->host,
213                                 options->port, 
214                                 1.0,
215                                 options->password) == 0 )
216             {
217               screen_status_printf(_("Connected to %s!"), options->host);
218               doupdate();
219               connected = TRUE;
220             }     
221         }
223       t = g_timer_elapsed(timer, NULL);
224     }
225   exit(EXIT_FAILURE);