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);
112 /* read configuration */
113 read_configuration(options);
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);
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);
226 }