Code

fix unused parameter warnings
[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 "config.h"
22 #include "ncmpc.h"
23 #include "mpdclient.h"
24 #include "support.h"
25 #include "options.h"
26 #include "conf.h"
27 #include "command.h"
28 #include "src_lyrics.h"
29 #include "screen.h"
30 #include "screen_utils.h"
31 #include "strfsong.h"
32 #include "gcc.h"
34 #include <stdlib.h>
35 #include <unistd.h>
36 #include <signal.h>
37 #include <string.h>
39 #define BUFSIZE 1024
41 static mpdclient_t   *mpd = NULL;
42 static gboolean connected = FALSE;
43 static GTimer      *timer = NULL;
45 static const gchar *
46 error_msg(const gchar *msg)
47 {
48   gchar *p;
50   if( (p=strchr(msg, '}' )) == NULL )
51     return msg;
52   while( p && *p && (*p=='}' || *p==' ') )
53     p++;
55   return p;
56 }
58 static void
59 error_callback(mpd_unused mpdclient_t *c, gint error, const gchar *msg)
60 {
61         error = error & 0xFF;
62         D("Error [%d:%d]> \"%s\"\n", error, GET_ACK_ERROR_CODE(error), msg);
63         switch (error) {
64         case MPD_ERROR_CONNPORT:
65         case MPD_ERROR_NORESPONSE:
66                 break;
67         case MPD_ERROR_ACK:
68                 screen_status_printf("%s", error_msg(msg));
69                 screen_bell();
70                 break;
71         default:
72                 screen_status_printf("%s", msg);
73                 screen_bell();
74                 doupdate();
75                 connected = FALSE;
76         }
77 }
79 static void
80 update_xterm_title(void)
81 {
82   static char title[BUFSIZE];
83   char tmp[BUFSIZE];
84   mpd_Status *status = NULL;
85   mpd_Song *song = NULL;
87   if( mpd )
88     {
89       status = mpd->status;
90       song = mpd->song;
91     }
93   if(options.xterm_title_format && status && song && IS_PLAYING(status->state))
94     {
95       strfsong(tmp, BUFSIZE, options.xterm_title_format, song);
96     }
97   else
98     g_strlcpy(tmp, PACKAGE " version " VERSION, BUFSIZE);
100   if( strncmp(title,tmp,BUFSIZE) )
101     {
102       g_strlcpy(title, tmp, BUFSIZE);
103       set_xterm_title("%s", title);
104     }
107 static void
108 exit_and_cleanup(void)
110   screen_exit();
111   set_xterm_title("");
112   printf("\n");
113   if( mpd )
114     {
115       mpdclient_disconnect(mpd);
116       mpd = mpdclient_free(mpd);
117     }
118   g_free(options.host);
119   g_free(options.password);
120   g_free(options.list_format);
121   g_free(options.status_format);
122   g_free(options.scroll_sep);
123   if( timer )
124     g_timer_destroy(timer);
127 static void
128 catch_sigint(mpd_unused int sig)
130         printf("\n%s\n", _("Exiting..."));
131         exit(EXIT_SUCCESS);
135 static void
136 catch_sigcont(mpd_unused int sig)
138         D("catch_sigcont()\n");
139 #ifdef ENABLE_RAW_MODE
140         reset_prog_mode(); /* restore tty modes */
141         refresh();
142 #endif
143         screen_resize();
146 void
147 sigstop(void)
149   def_prog_mode();  /* save the tty modes */
150   endwin();         /* end curses mode temporarily */
151   kill(0, SIGSTOP); /* issue SIGSTOP */
154 #ifndef NDEBUG
155 void 
156 D(const char *format, ...)
158   if( options.debug )
159     {
160       gchar *msg;
161       va_list ap;
162   
163       va_start(ap,format);
164       msg = g_strdup_vprintf(format,ap);
165       va_end(ap);
166       fprintf(stderr, "%s", msg);
167       g_free(msg);
168     }
170 #endif
172 int
173 main(int argc, const char *argv[])
175         struct sigaction act;
176         const char *charset = NULL;
177         gboolean key_error;
179 #ifdef HAVE_LOCALE_H
180         /* time and date formatting */
181         setlocale(LC_TIME,"");
182         /* care about sorting order etc */
183         setlocale(LC_COLLATE,"");
184         /* charset */
185         setlocale(LC_CTYPE,"");
186         /* initialize charset conversions */
187         charset_init(g_get_charset(&charset));
188         D("charset: %s\n", charset);
189 #endif
191         /* initialize i18n support */
192 #ifdef ENABLE_NLS
193         setlocale(LC_MESSAGES, "");
194         bindtextdomain(GETTEXT_PACKAGE, LOCALE_DIR);
195         bind_textdomain_codeset(GETTEXT_PACKAGE, charset);
196         textdomain(GETTEXT_PACKAGE);
197 #endif
199         /* initialize options */
200         options_init();
202         /* parse command line options - 1 pass get configuration files */
203         options_parse(argc, argv);
205         /* read configuration */
206         read_configuration(&options);
208         /* check key bindings */
209         key_error = check_key_bindings(NULL, NULL, 0);
211         /* parse command line options - 2 pass */
212         options_parse(argc, argv);
214         /* setup signal behavior - SIGINT */
215         sigemptyset( &act.sa_mask );
216         act.sa_flags    = 0;
217         act.sa_handler = catch_sigint;
218         if( sigaction(SIGINT, &act, NULL)<0 ) {
219                 perror("signal");
220                 exit(EXIT_FAILURE);
221         }
223         /* setup signal behavior - SIGTERM */
224         sigemptyset( &act.sa_mask );
225         act.sa_flags    = 0;
226         act.sa_handler = catch_sigint;
227         if( sigaction(SIGTERM, &act, NULL)<0 ) {
228                 perror("sigaction()");
229                 exit(EXIT_FAILURE);
230         }
232         /* setup signal behavior - SIGCONT */
233         sigemptyset( &act.sa_mask );
234         act.sa_flags    = 0;
235         act.sa_handler = catch_sigcont;
236         if( sigaction(SIGCONT, &act, NULL)<0 ) {
237                 perror("sigaction(SIGCONT)");
238                 exit(EXIT_FAILURE);
239         }
241         /* setup signal behaviour - SIGHUP*/
242         sigemptyset( &act.sa_mask );
243         act.sa_flags    = 0;
244         act.sa_handler = catch_sigint;
245         if( sigaction(SIGHUP, &act, NULL)<0 ) {
246                 perror("sigaction(SIGHUP)");
247                 exit(EXIT_FAILURE);
248         }
250         /* install exit function */
251         atexit(exit_and_cleanup);
253         ncurses_init();
255         src_lyr_init ();
257         /* connect to our music player daemon */
258         mpd = mpdclient_new();
260         if (mpdclient_connect(mpd,
261                               options.host,
262                               options.port,
263                               10.0,
264                               options.password))
265                 exit(EXIT_FAILURE);
267         /* if no password is used, but the mpd wants one, the connection
268            might be established but no status information is avaiable */
269         mpdclient_update(mpd);
270         if (!mpd->status)
271                 screen_auth(mpd);
273         if (!mpd->status)
274                 exit(EXIT_FAILURE);
276         connected = TRUE;
277         D("Connected to MPD version %d.%d.%d\n",
278           mpd->connection->version[0],
279           mpd->connection->version[1],
280           mpd->connection->version[2]);
282         /* quit if mpd is pre 0.11.0 - song id not supported by mpd */
283         if( MPD_VERSION_LT(mpd, 0,11,0) ) {
284                 fprintf(stderr,
285                         _("Error: MPD version %d.%d.%d is to old (0.11.0 needed).\n"),
286                         mpd->connection->version[0],
287                         mpd->connection->version[1],
288                         mpd->connection->version[2]);
289                 exit(EXIT_FAILURE);
290         }
292         /* initialize curses */
293         screen_init(mpd);
294         /* install error callback function */
295         mpdclient_install_error_callback(mpd, error_callback);
297         /* initialize timer */
298         timer = g_timer_new();
300         connected = TRUE;
301         while (connected || options.reconnect) {
302                 static gdouble t = G_MAXDOUBLE;
304                 if( key_error ) {
305                         char buf[BUFSIZE];
307                         key_error=check_key_bindings(NULL, buf, BUFSIZE);
308                         screen_status_printf("%s", buf);
309                 }
311                 if( connected && (t>=MPD_UPDATE_TIME || mpd->need_update) ) {
312                         mpdclient_update(mpd);
313                         g_timer_start(timer);
314                 }
316                 if( connected ) {
317                         command_t cmd;
319                         screen_update(mpd);
320                         if( (cmd=get_keyboard_command()) != CMD_NONE )
321                                 {
322                                         screen_cmd(mpd, cmd);
323                                         if( cmd==CMD_VOLUME_UP || cmd==CMD_VOLUME_DOWN)
324                                                 /* make shure we dont update the volume yet */
325                                                 g_timer_start(timer);
326                                 }
327                         else
328                                 screen_idle(mpd);
329                 } else if( options.reconnect ) {
330                         screen_status_printf(_("Connecting to %s...  [Press %s to abort]"),
331                                              options.host, get_key_names(CMD_QUIT,0) );
333                         if( get_keyboard_command_with_timeout(MPD_RECONNECT_TIME)==CMD_QUIT)
334                                 exit(EXIT_SUCCESS);
336                         if (mpdclient_connect(mpd,
337                                               options.host, options.port,
338                                               1.5,
339                                               options.password) == 0) {
340                                 screen_status_printf(_("Connected to %s!"), options.host);
341                                 connected = TRUE;
342                         }
344                         doupdate();
345                 }
347                 if (options.enable_xterm_title)
348                         update_xterm_title();
350                 t = g_timer_elapsed(timer, NULL);
351         }
352         exit(EXIT_FAILURE);