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 1.0
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 charset_close();
31 if( mpc )
32 {
33 if( mpc_error(mpc) )
34 fprintf(stderr,"Error: %s\n", mpc_error_str(mpc));
35 mpc_close(mpc);
36 }
37 g_free(options.host);
38 g_free(options.password);
39 if( timer )
40 g_timer_destroy(timer);
41 }
43 void
44 catch_sigint( int sig )
45 {
46 printf( "\nExiting...\n");
47 exit(EXIT_SUCCESS);
48 }
50 int
51 main(int argc, const char *argv[])
52 {
53 options_t *options;
54 struct sigaction act;
55 gboolean connected;
57 /* initialize options */
58 options = options_init();
60 /* read configuration */
61 read_rc_file(NULL, options);
63 /* parse command line options */
64 options_parse(argc, argv);
66 /* initialize local charset */
67 if( charset_init() )
68 exit(EXIT_FAILURE);
70 /* setup signal behavior - SIGINT */
71 sigemptyset( &act.sa_mask );
72 act.sa_flags = 0;
73 act.sa_handler = catch_sigint;
74 if( sigaction( SIGINT, &act, NULL )<0 )
75 {
76 perror("signal");
77 exit(EXIT_FAILURE);
78 }
79 /* setup signal behavior - SIGWINCH */
80 sigemptyset( &act.sa_mask );
81 act.sa_flags = 0;
82 act.sa_handler = screen_resized;
83 if( sigaction( SIGWINCH, &act, NULL )<0 )
84 {
85 perror("sigaction()");
86 exit(EXIT_FAILURE);
87 }
88 /* setup signal behavior - SIGTERM */
89 sigemptyset( &act.sa_mask );
90 act.sa_flags = 0;
91 act.sa_handler = catch_sigint;
92 if( sigaction( SIGTERM, &act, NULL )<0 )
93 {
94 perror("sigaction()");
95 exit(EXIT_FAILURE);
96 }
98 /* set xterm title */
99 if( g_getenv("DISPLAY") )
100 printf("%c]0;%s%c", '\033', PACKAGE " version " VERSION, '\007');
102 /* install exit function */
103 atexit(exit_and_cleanup);
105 /* connect to our music player daemon */
106 mpc = mpc_connect(options->host, options->port, options->password);
107 if( mpc_error(mpc) )
108 exit(EXIT_FAILURE);
110 /* initialize curses */
111 screen_init();
113 /* initialize timer */
114 timer = g_timer_new();
116 connected = TRUE;
117 while( connected || options->reconnect )
118 {
119 static gdouble t = G_MAXDOUBLE;
121 if( connected && t>=MPD_UPDATE_TIME )
122 {
123 mpc_update(mpc);
124 if( mpc_error(mpc) == MPD_ERROR_ACK )
125 {
126 screen_status_printf("%s", mpc_error_str(mpc));
127 mpd_clearError(mpc->connection);
128 mpd_finishCommand(mpc->connection);
129 }
130 else if( mpc_error(mpc) )
131 {
132 screen_status_printf("Lost connection to %s", options->host);
133 connected = FALSE;
134 doupdate();
135 mpd_clearError(mpc->connection);
136 mpd_closeConnection(mpc->connection);
137 mpc->connection = NULL;
138 }
139 else
140 mpd_finishCommand(mpc->connection);
141 g_timer_start(timer);
142 }
144 if( connected )
145 {
146 command_t cmd;
148 screen_update(mpc);
149 if( (cmd=get_keyboard_command()) != CMD_NONE )
150 {
151 screen_cmd(mpc, cmd);
152 if( cmd==CMD_VOLUME_UP || cmd==CMD_VOLUME_DOWN)
153 /* make shure we dont update the volume yet */
154 g_timer_start(timer);
155 }
156 }
157 else if( options->reconnect )
158 {
159 sleep(MPD_RECONNECT_TIMEOUT);
160 screen_status_printf("Connecting to %s... [Press Ctrl-C to abort]",
161 options->host);
162 if( mpc_reconnect(mpc,
163 options->host,
164 options->port,
165 options->password) == 0 )
166 {
167 screen_status_printf("Connected to %s!", options->host);
168 connected = TRUE;
169 }
170 doupdate();
171 }
173 t = g_timer_elapsed(timer, NULL);
174 }
176 exit(EXIT_FAILURE);
177 }