1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <unistd.h>
4 #include <signal.h>
5 #include <glib.h>
7 #include "config.h"
8 #include "libmpdclient.h"
9 #include "support.h"
10 #include "mpc.h"
11 #include "options.h"
12 #include "command.h"
13 #include "screen.h"
14 #include "conf.h"
16 /* time in seconds between mpd updates (double) */
17 #define MPD_UPDATE_TIME 0.5
19 /* timout in seconds before trying to reconnect (int) */
20 #define MPD_RECONNECT_TIMEOUT 3
23 static mpd_client_t *mpc = NULL;
24 static GTimer *timer = NULL;
26 void
27 exit_and_cleanup(void)
28 {
29 screen_exit();
30 printf("\n");
31 charset_close();
32 if( mpc )
33 {
34 if( mpc_error(mpc) )
35 fprintf(stderr,"Error: %s\n", mpc_error_str(mpc));
36 mpc_close(mpc);
37 }
38 g_free(options.host);
39 g_free(options.password);
40 if( timer )
41 g_timer_destroy(timer);
42 }
44 void
45 catch_sigint( int sig )
46 {
47 printf( "\nExiting...\n");
48 exit(EXIT_SUCCESS);
49 }
51 int
52 main(int argc, const char *argv[])
53 {
54 options_t *options;
55 struct sigaction act;
56 gboolean connected;
58 /* initialize options */
59 options = options_init();
61 /* read configuration */
62 read_configuration(options);
64 /* check key bindings */
65 if( check_key_bindings() )
66 {
67 fprintf(stderr, "Confusing key bindings - exiting!\n");
68 exit(EXIT_FAILURE);
69 }
71 /* parse command line options */
72 options_parse(argc, argv);
74 /* initialize local charset */
75 if( charset_init() )
76 exit(EXIT_FAILURE);
78 /* setup signal behavior - SIGINT */
79 sigemptyset( &act.sa_mask );
80 act.sa_flags = 0;
81 act.sa_handler = catch_sigint;
82 if( sigaction( SIGINT, &act, NULL )<0 )
83 {
84 perror("signal");
85 exit(EXIT_FAILURE);
86 }
87 /* setup signal behavior - SIGWINCH */
88 sigemptyset( &act.sa_mask );
89 act.sa_flags = 0;
90 act.sa_handler = screen_resized;
91 if( sigaction( SIGWINCH, &act, NULL )<0 )
92 {
93 perror("sigaction()");
94 exit(EXIT_FAILURE);
95 }
96 /* setup signal behavior - SIGTERM */
97 sigemptyset( &act.sa_mask );
98 act.sa_flags = 0;
99 act.sa_handler = catch_sigint;
100 if( sigaction( SIGTERM, &act, NULL )<0 )
101 {
102 perror("sigaction()");
103 exit(EXIT_FAILURE);
104 }
106 /* set xterm title */
107 if( g_getenv("DISPLAY") )
108 printf("%c]0;%s%c", '\033', PACKAGE " version " VERSION, '\007');
110 /* install exit function */
111 atexit(exit_and_cleanup);
113 /* connect to our music player daemon */
114 mpc = mpc_connect(options->host, options->port, options->password);
115 if( mpc_error(mpc) )
116 exit(EXIT_FAILURE);
118 /* initialize curses */
119 screen_init();
121 /* initialize timer */
122 timer = g_timer_new();
124 connected = TRUE;
125 while( connected || options->reconnect )
126 {
127 static gdouble t = G_MAXDOUBLE;
129 if( connected && t>=MPD_UPDATE_TIME )
130 {
131 mpc_update(mpc);
132 if( mpc_error(mpc) == MPD_ERROR_ACK )
133 {
134 screen_status_printf("%s", mpc_error_str(mpc));
135 mpd_clearError(mpc->connection);
136 mpd_finishCommand(mpc->connection);
137 }
138 else if( mpc_error(mpc) )
139 {
140 screen_status_printf("Lost connection to %s", options->host);
141 connected = FALSE;
142 doupdate();
143 mpd_clearError(mpc->connection);
144 mpd_closeConnection(mpc->connection);
145 mpc->connection = NULL;
146 }
147 else
148 mpd_finishCommand(mpc->connection);
149 g_timer_start(timer);
150 }
152 if( connected )
153 {
154 command_t cmd;
156 screen_update(mpc);
157 if( (cmd=get_keyboard_command()) != CMD_NONE )
158 {
159 screen_cmd(mpc, cmd);
160 if( cmd==CMD_VOLUME_UP || cmd==CMD_VOLUME_DOWN)
161 /* make shure we dont update the volume yet */
162 g_timer_start(timer);
163 }
164 }
165 else if( options->reconnect )
166 {
167 sleep(MPD_RECONNECT_TIMEOUT);
168 screen_status_printf("Connecting to %s... [Press Ctrl-C to abort]",
169 options->host);
170 if( mpc_reconnect(mpc,
171 options->host,
172 options->port,
173 options->password) == 0 )
174 {
175 screen_status_printf("Connected to %s!", options->host);
176 connected = TRUE;
177 }
178 doupdate();
179 }
181 t = g_timer_elapsed(timer, NULL);
182 }
184 exit(EXIT_FAILURE);
185 }