f2a0e3d29a729e2016a7a5b035dceaf51c558ce4
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 "conf.h"
34 #include "command.h"
35 #include "screen.h"
36 #include "screen_utils.h"
38 #define BUFSIZE 256
40 static mpdclient_t *mpd = NULL;
41 static gboolean connected = FALSE;
42 static GTimer *timer = NULL;
44 static gchar *
45 error_msg(gchar *msg)
46 {
47 gchar *p;
49 if( (p=strchr(msg, '}' )) == NULL )
50 return msg;
51 while( p && *p && (*p=='}' || *p==' ') )
52 p++;
54 return p;
55 }
57 static void
58 error_callback(mpdclient_t *c, gint error, gchar *msg)
59 {
60 gint code = GET_ACK_ERROR_CODE(error);
62 error = error & 0xFF;
63 D("Error [%d:%d]> \"%s\"\n", error, code, msg);
64 switch(error)
65 {
66 case MPD_ERROR_CONNPORT:
67 case MPD_ERROR_NORESPONSE:
68 break;
69 case MPD_ERROR_ACK:
70 screen_status_printf("%s", error_msg(msg));
71 screen_bell();
72 break;
73 default:
74 screen_status_printf("%s", msg);
75 screen_bell();
76 doupdate();
77 connected = FALSE;
78 }
79 }
81 void
82 exit_and_cleanup(void)
83 {
84 screen_exit();
85 printf("\n");
86 if( mpd )
87 {
88 mpdclient_disconnect(mpd);
89 mpd = mpdclient_free(mpd);
90 }
91 g_free(options.host);
92 g_free(options.password);
93 g_free(options.list_format);
94 g_free(options.status_format);
95 if( timer )
96 g_timer_destroy(timer);
97 }
99 void
100 catch_sigint( int sig )
101 {
102 printf("\n%s\n", _("Exiting..."));
103 exit(EXIT_SUCCESS);
104 }
106 int
107 main(int argc, const char *argv[])
108 {
109 options_t *options;
110 struct sigaction act;
111 const char *charset = NULL;
112 gboolean key_error;
114 #ifdef HAVE_LOCALE_H
115 /* time and date formatting */
116 setlocale(LC_TIME,"");
117 /* charset */
118 setlocale(LC_CTYPE,"");
119 /* initialize charset conversions */
120 charset_init(g_get_charset(&charset));
121 D("charset: %s\n", charset);
122 #endif
124 /* initialize i18n support */
125 #ifdef ENABLE_NLS
126 setlocale(LC_MESSAGES, "");
127 bindtextdomain(GETTEXT_PACKAGE, LOCALE_DIR);
128 bind_textdomain_codeset(GETTEXT_PACKAGE, charset);
129 textdomain(GETTEXT_PACKAGE);
130 #endif
132 /* initialize options */
133 options = options_init();
135 /* parse command line options - 1 pass get configuration files */
136 options_parse(argc, argv);
138 /* read configuration */
139 read_configuration(options);
141 /* check key bindings */
142 key_error = check_key_bindings(NULL, 0);
144 /* parse command line options - 2 pass */
145 options_parse(argc, argv);
147 /* setup signal behavior - SIGINT */
148 sigemptyset( &act.sa_mask );
149 act.sa_flags = 0;
150 act.sa_handler = catch_sigint;
151 if( sigaction( SIGINT, &act, NULL )<0 )
152 {
153 perror("signal");
154 exit(EXIT_FAILURE);
155 }
156 /* setup signal behavior - SIGTERM */
157 sigemptyset( &act.sa_mask );
158 act.sa_flags = 0;
159 act.sa_handler = catch_sigint;
160 if( sigaction( SIGTERM, &act, NULL )<0 )
161 {
162 perror("sigaction()");
163 exit(EXIT_FAILURE);
164 }
166 /* set xterm title */
167 #ifdef DEBUG
168 options->enable_xterm_title = 1;
169 set_xterm_title(PACKAGE " version " VERSION);
170 #endif
172 /* install exit function */
173 atexit(exit_and_cleanup);
175 /* connect to our music player daemon */
176 mpd = mpdclient_new();
177 if( mpdclient_connect(mpd,
178 options->host,
179 options->port,
180 10.0,
181 options->password) )
182 {
183 exit(EXIT_FAILURE);
184 }
185 connected = TRUE;
186 D("Connected to MPD version %d.%d.%d\n",
187 mpd->connection->version[0],
188 mpd->connection->version[1],
189 mpd->connection->version[2]);
191 if( !MPD_VERSION(mpd, 0,11,0) )
192 {
193 fprintf(stderr, "MPD version %d.%d.%d is to old (0.11.0 needed).\n",
194 mpd->connection->version[0],
195 mpd->connection->version[1],
196 mpd->connection->version[2]);
197 exit(EXIT_FAILURE);
198 }
200 /* initialize curses */
201 screen_init(mpd);
203 /* install error callback function */
204 mpdclient_install_error_callback(mpd, error_callback);
206 /* initialize timer */
207 timer = g_timer_new();
209 connected = TRUE;
210 while( connected || options->reconnect )
211 {
212 static gdouble t = G_MAXDOUBLE;
214 if( key_error )
215 {
216 char buf[BUFSIZE];
218 key_error=check_key_bindings(buf, BUFSIZE);
219 screen_status_printf("%s", buf);
220 }
222 if( connected && (t>=MPD_UPDATE_TIME || mpd->need_update) )
223 {
224 mpdclient_update(mpd);
225 g_timer_start(timer);
226 }
228 if( connected )
229 {
230 command_t cmd;
232 screen_update(mpd);
233 if( (cmd=get_keyboard_command()) != CMD_NONE )
234 {
235 screen_cmd(mpd, cmd);
236 if( cmd==CMD_VOLUME_UP || cmd==CMD_VOLUME_DOWN)
237 /* make shure we dont update the volume yet */
238 g_timer_start(timer);
239 }
240 else
241 screen_idle(mpd);
242 }
243 else if( options->reconnect )
244 {
245 screen_status_printf(_("Connecting to %s... [Press %s to abort]"),
246 options->host, get_key_names(CMD_QUIT,0) );
248 if( get_keyboard_command_with_timeout(MPD_RECONNECT_TIME)==CMD_QUIT)
249 exit(EXIT_SUCCESS);
251 if( mpdclient_connect(mpd,
252 options->host,
253 options->port,
254 1.5,
255 options->password) == 0 )
256 {
257 screen_status_printf(_("Connected to %s!"), options->host);
258 connected = TRUE;
259 }
260 doupdate();
261 }
263 t = g_timer_elapsed(timer, NULL);
264 }
265 exit(EXIT_FAILURE);
266 }