/******************** Song ingo retrival ************************************/ static int getSong(void) { mpd_Status *status; mpd_InfoEntity *info; /* Get status */ mpd_sendStatusCommand(D.conn); if (error()) return 0; status = mpd_getStatus(D.conn); if (error()) return 0; pdie_on(!status, "get status"); mpd_nextListOkCommand(D.conn); if (error()) { mpd_freeStatus(status); return 0; } /* Copy status */ D.cur.state = status->state; D.cur.songid = status->songid; D.cur.pos = status->elapsedTime; D.cur.len = status->totalTime; mpd_freeStatus(status); /* Same song, return */ if (D.cur.songid == D.old.songid) { return 1; } if (D.info) { mpd_freeInfoEntity(D.info); D.info = 0; } /* Get song */ mpd_sendCurrentSongCommand(D.conn); if (error()) { return 0; } info = mpd_getNextInfoEntity(D.conn); if (error()) { return 0; } if (!info) { return D.cur.state == MPD_STATUS_STATE_PLAY || D.cur.state == MPD_STATUS_STATE_PAUSE; } if (info->type != MPD_INFO_ENTITY_TYPE_SONG) { mpd_freeInfoEntity(info); return 0; } D.info = info; return 1; }
/* ================= MPD_Status - show info about currently playing song ================= */ void MPD_Status(void) { mpd_Status *status; mpd_InfoEntity *entity = NULL; mpd_Song *song = 0; char title[MP3_MAXSONGTITLE]; if(!MP3_Status()) return; mpd_sendStatusCommand(conn); if( (status = mpd_getStatus(conn)) == NULL) { Com_Printf("MPD: %s\n", conn->errorStr); mpd_finishCommand(conn); return; } mpd_finishCommand(conn); if( status->state == MPD_STATUS_STATE_STOP) { /* Playback stopped */ Com_Printf("MPD: not playing\n"); mpd_freeStatus(status); return; } if( status->state == MPD_STATUS_STATE_PLAY || MPD_STATUS_STATE_PAUSE ) { mpd_sendCurrentSongCommand(conn); while((entity = mpd_getNextInfoEntity(conn))) { if(entity->type != MPD_INFO_ENTITY_TYPE_SONG) { mpd_freeInfoEntity(entity); continue; } song = entity->info.song; if(song->title == NULL || song->artist == NULL) Com_sprintf(title, sizeof(title), "%s [%i:%02i]", (song->title) ? song->title : song->file, status->totalTime / 60, status->totalTime % 60); else Com_sprintf(title, sizeof(title), "%s - %s [%i:%02i]", song->artist, song->title, status->totalTime / 60, status->totalTime % 60); COM_MakePrintable(title); Com_Printf("%s\n", title); mpd_freeInfoEntity(entity); break; } mpd_finishCommand(conn); } mpd_freeStatus(status); }
int cmd_volume ( int argc, char ** argv, mpd_Connection * conn ) { struct int_value_change ch; if(argc==1) { if(!parse_int_value_change(argv[0], &ch)) DIE("\"%s\" is not an integer\n", argv[0]); } else { mpd_Status *status; status = getStatus(conn); printf("volume:%3i%c \n",status->volume,'%'); mpd_freeStatus(status); return 0; } if (ch.is_relative) mpd_sendVolumeCommand(conn,ch.value); else mpd_sendSetvolCommand(conn,ch.value); my_finishCommand(conn); return 1; }
int cmd_playlist(mpd_unused int argc, mpd_unused char **argv, mpd_Connection *conn) { mpd_InfoEntity * entity; mpd_Status * status; int count = 0; mpd_sendStatusCommand(conn); printErrorAndExit(conn); status = mpd_getStatus(conn); printErrorAndExit(conn); mpd_finishCommand(conn); mpd_sendPlaylistInfoCommand(conn,-1); printErrorAndExit(conn); while((entity = mpd_getNextInfoEntity(conn))) { if(entity->type==MPD_INFO_ENTITY_TYPE_SONG) { struct mpd_song *song = entity->info.song; printf("%s%i) ", (status->song == count)?">":" ", 1+count); pretty_print_song(song); printf("\n"); count++; } mpd_freeInfoEntity(entity); } my_finishCommand(conn); mpd_freeStatus(status); return 0; }
int cmd_play ( int argc, char ** argv, mpd_Connection * conn ) { int song; int i; if(0==argc) song = MPD_PLAY_AT_BEGINNING; else { mpd_Status *status; for(i=0;i<argc-1;i++) printf("skipping: %s\n",argv[i]); if(!parse_songnum(argv[i], &song)) DIE("error parsing song numbers from: %s\n",argv[i]); song--; /* This is necessary, otherwise mpc will output the wrong playlist number */ status = getStatus(conn); i = status->playlistLength; mpd_freeStatus(status); if(song >= i) DIE("song number greater than playlist length.\n"); } mpd_sendPlayCommand(conn,song); my_finishCommand(conn); return 1; }
static int mpdclient_playlist_update(void *data) { mpd_Status * status; mpd_InfoEntity *entity; int i; mpd_sendCommandListOkBegin(conn); mpd_sendStatusCommand(conn); mpd_sendPlChangesCommand(conn, cur_playlist); mpd_sendCommandListEnd(conn); if((status = mpd_getStatus(conn))==NULL) { fprintf(stderr,"%s\n",conn->errorStr); mpd_closeConnection(conn); return 1; } cur_playlist = status->playlist; cur_song = status->songid; mpd_nextListOkCommand(conn); evas_event_freeze(evas); while((entity = mpd_getNextInfoEntity(conn))) { if(entity->type!=MPD_INFO_ENTITY_TYPE_SONG) { mpd_freeInfoEntity(entity); continue; } music_song_insert(entity->info.song); mpd_freeInfoEntity(entity); } for (i = status->playlistLength; i < music_song_count(); i++) { music_song_remove(i); } if (status->state == MPD_STATUS_STATE_PLAY || status->state == MPD_STATUS_STATE_PAUSE) { music_song_update(status->song, status->totalTime); } else { music_song_update(-1, 0); } layout_update(status->state == MPD_STATUS_STATE_PLAY, status->volume); evas_event_thaw(evas); mpd_finishCommand(conn); mpd_freeStatus(status); return 1; }
int cmd_crop(mpd_unused int argc, mpd_unused char **argv, mpd_Connection *conn) { mpd_Status *status = getStatus( conn ); int length = ( status->playlistLength - 1 ); if( status->playlistLength == 0 ) { mpd_freeStatus(status); DIE( "You have to have a playlist longer than 1 song in length to crop" ); } else if( status->state == 3 || status->state == 2 ) { /* If playing or paused */ mpd_sendCommandListBegin( conn ); printErrorAndExit( conn ); while( length >= 0 ) { if( length != status->song ) { mpd_sendDeleteCommand( conn, length ); printErrorAndExit( conn ); } length--; } mpd_sendCommandListEnd( conn ); my_finishCommand( conn ); mpd_freeStatus( status ); return ( 0 ); } else { mpd_freeStatus(status); DIE( "You need to be playing to crop the playlist\n" ); } }
MPDStatus MPDConnection::status() { if (!isConnected()) return MPDStatus(); Q_ASSERT(d->connection); mpd_call(MPDConnection::status, Status); mpd_Status *status = mpd_getStatus(d->connection); if (!finishCommand() || !status) return MPDStatus(); MPDStatus ret(status); mpd_freeStatus(status); return ret; }
static char *MPD_SongTitle ( void ) { mpd_Status *status; mpd_InfoEntity *entity = NULL; mpd_Song *song = 0; static char title[MP3_MAXSONGTITLE]; title[0] = 0; if(!MP3_Status()) return title; mpd_sendCommandListOkBegin(conn); mpd_sendStatusCommand(conn); mpd_sendCurrentSongCommand(conn); mpd_sendCommandListEnd(conn); if( (status = mpd_getStatus(conn)) == NULL) { return title; } mpd_nextListOkCommand(conn); while((entity = mpd_getNextInfoEntity(conn))) { if(entity->type != MPD_INFO_ENTITY_TYPE_SONG) { mpd_freeInfoEntity(entity); continue; } song = entity->info.song; if(song->title == NULL || song->artist == NULL) Com_sprintf(title, sizeof(title), "%s [%i:%02i]", song->file, status->totalTime / 60, status->totalTime % 60); else Com_sprintf(title, sizeof(title), "%s - %s [%i:%02i]", song->artist, song->title, status->totalTime / 60, status->totalTime % 60); COM_MakePrintable(title); mpd_freeInfoEntity(entity); break; } mpd_freeStatus(status); mpd_finishCommand(conn); return title; }
int mpd_status_queue_update(MpdObj *mi) { if(!mpd_check_connected(mi)) { debug_printf(DEBUG_INFO,"not connected\n"); return MPD_NOT_CONNECTED; } if(mi->status != NULL) { mpd_freeStatus(mi->status); mi->status = NULL; } return MPD_OK; }
int cmd_current(mpd_unused int argc, mpd_unused char ** argv, mpd_Connection *conn) { mpd_Status * status; mpd_InfoEntity * entity; mpd_sendCommandListOkBegin(conn); printErrorAndExit(conn); mpd_sendStatusCommand(conn); printErrorAndExit(conn); mpd_sendCurrentSongCommand(conn); printErrorAndExit(conn); mpd_sendCommandListEnd(conn); printErrorAndExit(conn); status = mpd_getStatus(conn); printErrorAndExit(conn); if (status->state == MPD_STATUS_STATE_PLAY || status->state == MPD_STATUS_STATE_PAUSE) { mpd_nextListOkCommand(conn); printErrorAndExit(conn); while((entity = mpd_getNextInfoEntity(conn))) { struct mpd_song *song = entity->info.song; if(entity->type!=MPD_INFO_ENTITY_TYPE_SONG) { mpd_freeInfoEntity(entity); continue; } pretty_print_song(song); printf("\n"); mpd_freeInfoEntity(entity); break; } printErrorAndExit(conn); mpd_finishCommand(conn); printErrorAndExit(conn); } mpd_freeStatus(status); return 0; }
void mpd_free(MpdObj *mi) { debug_printf(DEBUG_INFO, "destroying MpdObj object\n"); if(mi->connected) { /* disconnect */ debug_printf(DEBUG_WARNING, "Connection still running, disconnecting\n"); mpd_disconnect(mi); } if(mi->hostname) { free(mi->hostname); } if(mi->password) { free(mi->password); } if(mi->error_msg) { free(mi->error_msg); } if(mi->connection) { /* obsolete */ mpd_closeConnection(mi->connection); } if(mi->status) { mpd_freeStatus(mi->status); } if(mi->stats) { mpd_freeStats(mi->stats); } if(mi->CurrentSong) { mpd_freeSong(mi->CurrentSong); } mpd_free_queue_ob(mi); mpd_server_free_commands(mi); free(mi); }
int cmd_consume ( int argc, char ** argv, mpd_Connection * conn ) { int mode; if(argc==1) { mode = get_boolean(argv[0]); if (mode < 0) return -1; } else { mpd_Status * status; status = getStatus(conn); mode = !status->consume; mpd_freeStatus(status); } mpd_sendConsumeCommand(conn,mode); my_finishCommand(conn); return 1; }
/* ================= MPD_SetVol - set volume ================= */ void MPD_SetVol(void) { mpd_Status *status; if(!MP3_Status()) return; if(Cmd_Argc() < 2) { mpd_sendStatusCommand(conn); if( (status = mpd_getStatus(conn)) == NULL) { Com_Printf("MPD: %s\n", conn->errorStr); } else { Com_Printf("MPD: volume %i\%\n", status->volume); mpd_freeStatus(status); } mpd_finishCommand(conn); } else {
int cmd_crossfade ( int argc, char ** argv, mpd_Connection * conn ) { int seconds; if(argc==1) { if(!parse_int(argv[0], &seconds) || seconds<0) DIE("\"%s\" is not 0 or positive integer\n",argv[0]); mpd_sendCrossfadeCommand(conn,seconds); my_finishCommand(conn); } else { mpd_Status * status; status = getStatus(conn); printf("crossfade: %i\n",status->crossfade); mpd_freeStatus(status); printErrorAndExit(conn); } return 0; }
int cmd_repeat ( int argc, char ** argv, mpd_Connection * conn ) { int mode; if(argc==1) { mode = get_boolean(argv[0]); if (mode < 0) return -1; } else { mpd_Status * status; status = getStatus(conn); mode = !status->repeat; mpd_freeStatus(status); } mpd_sendRepeatCommand(conn,mode); printErrorAndExit(conn); my_finishCommand(conn); printErrorAndExit(conn); return 1; }
int mpd_status_update(MpdObj *mi) { ChangedStatusType what_changed=0; if(!mpd_check_connected(mi)) { debug_printf(DEBUG_INFO,"not connected\n"); return MPD_NOT_CONNECTED; } if(mpd_lock_conn(mi)) { debug_printf(DEBUG_ERROR,"lock failed\n"); return MPD_LOCK_FAILED; } if(mi->status != NULL) { mpd_freeStatus(mi->status); mi->status = NULL; } mpd_sendStatusCommand(mi->connection); mi->status = mpd_getStatus(mi->connection); if(mi->status == NULL) { debug_printf(DEBUG_ERROR,"Failed to grab status from mpd\n"); mpd_unlock_conn(mi); return MPD_STATUS_FAILED; } if(mpd_unlock_conn(mi)) { debug_printf(DEBUG_ERROR, "Failed to unlock"); return MPD_LOCK_FAILED; } /* * check for changes */ /* first save the old status */ memcpy(&(mi->OldState), &(mi->CurrentState), sizeof(MpdServerState)); /* playlist change */ if(mi->CurrentState.playlistid != mi->status->playlist) { /* print debug message */ debug_printf(DEBUG_INFO, "Playlist has changed!"); /* We can't trust the current song anymore. so we remove it */ /* tags might have been updated */ if(mi->CurrentSong != NULL) { mpd_freeSong(mi->CurrentSong); mi->CurrentSong = NULL; } /* set MPD_CST_PLAYLIST to be changed */ what_changed |= MPD_CST_PLAYLIST; if(mi->CurrentState.playlistLength == mi->status->playlistLength) { // what_changed |= MPD_CST_SONGID; } /* save new id */ mi->CurrentState.playlistid = mi->status->playlist; } if(mi->CurrentState.storedplaylistid != mi->status->storedplaylist) { /* set MPD_CST_QUEUE to be changed */ what_changed |= MPD_CST_STORED_PLAYLIST; /* save new id */ mi->CurrentState.storedplaylistid = mi->status->storedplaylist; } /* state change */ if(mi->CurrentState.state != mi->status->state) { what_changed |= MPD_CST_STATE; mi->CurrentState.state = mi->status->state; } if(mi->CurrentState.songid != mi->status->songid) { /* print debug message */ debug_printf(DEBUG_INFO, "Songid has changed %i %i!", mi->OldState.songid, mi->status->songid); what_changed |= MPD_CST_SONGID; /* save new songid */ mi->CurrentState.songid = mi->status->songid; } if(mi->CurrentState.songpos != mi->status->song) { /* print debug message */ debug_printf(DEBUG_INFO, "Songpos has changed %i %i!", mi->OldState.songpos, mi->status->song); what_changed |= MPD_CST_SONGPOS; /* save new songid */ mi->CurrentState.songpos = mi->status->song; } if(mi->CurrentState.nextsongid != mi->status->nextsongid || mi->CurrentState.nextsongpos != mi->status->nextsong) { what_changed |= MPD_CST_NEXTSONG; /* save new songid */ mi->CurrentState.nextsongpos = mi->status->nextsong; mi->CurrentState.nextsongid = mi->status->nextsongid; } if(mi->CurrentState.single != mi->status->single) { what_changed |= MPD_CST_SINGLE_MODE; mi->CurrentState.single = mi->status->single; } if(mi->CurrentState.consume != mi->status->consume) { what_changed |= MPD_CST_CONSUME_MODE; mi->CurrentState.consume = mi->status->consume; } if(mi->CurrentState.repeat != mi->status->repeat) { what_changed |= MPD_CST_REPEAT; mi->CurrentState.repeat = mi->status->repeat; } if(mi->CurrentState.random != mi->status->random) { what_changed |= MPD_CST_RANDOM; mi->CurrentState.random = mi->status->random; } if(mi->CurrentState.volume != mi->status->volume) { what_changed |= MPD_CST_VOLUME; mi->CurrentState.volume = mi->status->volume; } if(mi->CurrentState.xfade != mi->status->crossfade) { what_changed |= MPD_CST_CROSSFADE; mi->CurrentState.xfade = mi->status->crossfade; } if(mi->CurrentState.totaltime != mi->status->totalTime) { what_changed |= MPD_CST_TOTAL_TIME; mi->CurrentState.totaltime = mi->status->totalTime; } if(mi->CurrentState.elapsedtime != mi->status->elapsedTime) { what_changed |= MPD_CST_ELAPSED_TIME; mi->CurrentState.elapsedtime = mi->status->elapsedTime; } /* Check if bitrate changed, happens with vbr encodings. */ if(mi->CurrentState.bitrate != mi->status->bitRate) { what_changed |= MPD_CST_BITRATE; mi->CurrentState.bitrate = mi->status->bitRate; } /* The following 3 probly only happen on a song change, or is it possible in one song/stream? */ /* Check if the sample rate changed */ if(mi->CurrentState.samplerate != mi->status->sampleRate) { what_changed |= MPD_CST_AUDIOFORMAT; mi->CurrentState.samplerate = mi->status->sampleRate; } /* check if the sampling depth changed */ if(mi->CurrentState.bits != mi->status->bits) { what_changed |= MPD_CST_AUDIOFORMAT; mi->CurrentState.bits = mi->status->bits; } /* Check if the amount of audio channels changed */ if(mi->CurrentState.channels != mi->status->channels) { what_changed |= MPD_CST_AUDIOFORMAT; mi->CurrentState.channels = mi->status->channels; } if(mi->status->error) { what_changed |= MPD_CST_SERVER_ERROR; strcpy(mi->CurrentState.error,mi->status->error); mpd_sendClearErrorCommand(mi->connection); mpd_finishCommand(mi->connection); } else { mi->CurrentState.error[0] ='\0'; } /* Check if the updating changed, * If it stopped, also update the stats for the new db-time. */ if(mi->CurrentState.updatingDb != mi->status->updatingDb ) { what_changed |= MPD_CST_UPDATING; if(!mi->status->updatingDb) { mpd_stats_update_real(mi, &what_changed); } mi->CurrentState.updatingDb = mi->status->updatingDb; } mi->CurrentState.playlistLength = mi->status->playlistLength; /* Detect changed outputs */ if(!mi->has_idle) { if(mi->num_outputs >0 ) { mpd_OutputEntity *output = NULL; mpd_sendOutputsCommand(mi->connection); while (( output = mpd_getNextOutput(mi->connection)) != NULL) { if(mi->num_outputs < output->id) { mi->num_outputs++; mi->output_states = realloc(mi->output_states,mi->num_outputs*sizeof(int)); mi->output_states[mi->num_outputs] = output->enabled; what_changed |= MPD_CST_OUTPUT; } if(mi->output_states[output->id] != output->enabled) { mi->output_states[output->id] = output->enabled; what_changed |= MPD_CST_OUTPUT; } mpd_freeOutputElement(output); } mpd_finishCommand(mi->connection); } else { /* if no outputs, lets fetch them */ mpd_server_update_outputs(mi); if(mi->num_outputs == 0) { assert("No outputs defined? that cannot be\n"); } what_changed |= MPD_CST_OUTPUT; } }else { char *name; int update_stats = 0; mpd_sendGetEventsCommand(mi->connection); while((name = mpd_getNextEvent(mi->connection))){ if(strcmp(name, "output") == 0){ what_changed |= MPD_CST_OUTPUT; }else if (strcmp(name, "database") == 0) { if((what_changed&MPD_CST_DATABASE) == 0) { update_stats = 1; } what_changed |= MPD_CST_DATABASE; }else if (strcmp(name, "stored_playlist")==0) { what_changed |= MPD_CST_STORED_PLAYLIST; }else if (strcmp(name, "tag") == 0) { what_changed |= MPD_CST_PLAYLIST; }else if (strcmp (name, "sticker") == 0) { what_changed |= MPD_CST_STICKER; } free(name); } mpd_finishCommand(mi->connection); if(update_stats) { mpd_stats_update_real(mi, &what_changed); } } /* Run the callback */ if((mi->the_status_changed_callback != NULL) && what_changed) { mi->the_status_changed_callback( mi, what_changed, mi->the_status_changed_signal_userdata ); } /* We could have lost connection again during signal handling... so before we return check again if we are connected */ if(!mpd_check_connected(mi)) { return MPD_NOT_CONNECTED; } return MPD_OK; }
int mpd_disconnect(MpdObj *mi) { /* lock */ mpd_lock_conn(mi); debug_printf(DEBUG_INFO, "disconnecting\n"); if(mi->connection) { mpd_closeConnection(mi->connection); mi->connection = NULL; } if(mi->status) { mpd_freeStatus(mi->status); mi->status = NULL; } if(mi->stats) { mpd_freeStats(mi->stats); mi->stats = NULL; } if(mi->CurrentSong) { mpd_freeSong(mi->CurrentSong); mi->CurrentSong = NULL; } mi->CurrentState.playlistid = -1; mi->CurrentState.queueid = -2; mi->CurrentState.storedplaylistid = -1; mi->CurrentState.state = -1; mi->CurrentState.songid = -1; mi->CurrentState.songpos = -1; mi->CurrentState.dbUpdateTime = 0; mi->CurrentState.updatingDb = 0; mi->CurrentState.repeat = -1; mi->CurrentState.random = -1; mi->CurrentState.volume = -2; mi->CurrentState.xfade = -1; mi->CurrentState.totaltime = 0; mi->CurrentState.elapsedtime = 0; mi->CurrentState.bitrate = 0; mi->CurrentState.samplerate = 0; mi->CurrentState.channels = 0; mi->CurrentState.bits = 0; mi->CurrentState.playlistLength = 0; mi->CurrentState.error[0] = '\0'; /* search stuff */ mi->search_type = MPD_SEARCH_TYPE_NONE; /* no need to initialize, but set it to anything anyway*/ mi->search_field = MPD_TAG_ITEM_ARTIST; memcpy(&(mi->OldState), &(mi->CurrentState) , sizeof(MpdServerState)); mpd_free_queue_ob(mi); mpd_server_free_commands(mi); /*don't reset errors */ /* Remove this signal, we don't actually disconnect */ if(mi->connected) { /* set disconnect flag */ mi->connected = FALSE; if(mi->the_connection_changed_callback != NULL) { mi->the_connection_changed_callback( mi, FALSE, mi->the_connection_changed_signal_userdata ); } } debug_printf(DEBUG_INFO, "Disconnect completed\n"); return MPD_OK; }
int cmd_del ( int argc, char ** argv, mpd_Connection * conn ) { int i,j; char * s; char * t; char * t2; int range[2]; int songsDeleted = 0; int plLength = 0; char * songsToDel; mpd_Status * status; status = getStatus(conn); plLength = status->playlistLength; songsToDel = malloc(plLength); memset(songsToDel,0,plLength); for(i=0;i<argc;i++) { if(argv[i][0]=='#') s = &(argv[i][1]); else s = argv[i]; range[0] = strtol(s,&t,10); /* If argument is 0 current song and we're not stopped */ if(range[0] == 0 && strlen(s) == 1 && \ (status->state == MPD_STATUS_STATE_PLAY || status->state == MPD_STATUS_STATE_PAUSE)) range[0] = status->song+1; if(s==t) DIE("error parsing song numbers from: %s\n",argv[i]); else if(*t=='-') { range[1] = strtol(t+1,&t2,10); if(t+1==t2 || *t2!='\0') DIE("error parsing range from: %s\n",argv[i]); } else if(*t==')' || *t=='\0') range[1] = range[0]; else DIE("error parsing song numbers from: %s\n",argv[i]); if(range[0]<=0 || range[1]<=0) { if (range[0]==range[1]) DIE("song number must be positive: %i\n",range[0]); else DIE("song numbers must be positive: %i to %i\n",range[0],range[1]); } if(range[1]<range[0]) DIE("song range must be from low to high: %i to %i\n",range[0],range[1]); if(range[1]>plLength) DIE("song number does not exist: %i\n",range[1]); for(j=range[0];j<=range[1];j++) songsToDel[j-1] = 1; } mpd_sendCommandListBegin(conn); printErrorAndExit(conn); for(i=0;i<plLength;i++) { if(songsToDel[i]) { mpd_sendDeleteCommand(conn,i-songsDeleted); printErrorAndExit(conn); songsDeleted++; } } mpd_sendCommandListEnd(conn); my_finishCommand(conn); mpd_freeStatus(status); free(songsToDel); return 0; }
int cmd_seek(mpd_unused int argc, mpd_unused char **argv, mpd_Connection *conn) { mpd_Status * status; char * arg = argv[0]; char * test; int seekchange; int total_secs; int seekto; int rel = 0; status = getStatus(conn); if(status->state==MPD_STATUS_STATE_STOP) DIE("not currently playing\n"); /* Detect +/- if exists point to the next char */ if(*arg == '+') rel = 1; else if(*arg == '-') rel = -1; if(rel != 0) arg++; /* If seeking by percent */ if( arg[strlen(arg)-1] == '%' ) { double perc; /* Remove the % */ arg[ strlen(arg) - 1 ] = '\0'; /* percent seek, strtod is needed for percent with decimals */ perc = strtod(arg,&test); if(( *test!='\0' ) || (!rel && (perc<0 || perc>100)) || (rel && perc>abs(100))) DIE("\"%s\" is not an number between 0 and 100\n",arg); seekchange = perc*status->totalTime/100+0.5; } else { /* If seeking by absolute seek time */ if( strchr( arg, ':' )) { char * sec_ptr; char * min_ptr; char * hr_ptr; int hr = 0; int min = 0; int sec = 0; /* Take the seconds off the end of arg */ sec_ptr = strrchr( arg, ':' ); /* Remove ':' and move the pointer one byte up */ * sec_ptr = '\0'; ++sec_ptr; /* If hour is in the argument, else just point to the arg */ if(( min_ptr = strrchr( arg, ':' ))) { /* Remove ':' and move the pointer one byte up */ * min_ptr = '\0'; ++min_ptr; /* If the argument still exists, it's the hour */ if( arg != NULL ) { hr_ptr = arg; hr = strtol( hr_ptr, &test, 10 ); if( *test != '\0' || ( ! rel && hr < 0 )) DIE("\"%s\" is not a positive number\n", sec_ptr); } } else { min_ptr = arg; } /* Change the pointers to a integer */ sec = strtol( sec_ptr, &test, 10 ); if( *test != '\0' || ( ! rel && sec < 0 )) DIE("\"%s\" is not a positive number\n", sec_ptr); min = strtol( min_ptr, &test, 10 ); if( *test != '\0' || ( ! rel && min < 0 )) DIE("\"%s\" is not a positive number\n", min_ptr); /* If mins exist, check secs. If hrs exist, check mins */ if( min && strlen(sec_ptr) != 2 ) DIE("\"%s\" is not two digits\n", sec_ptr); else if( hr && strlen(min_ptr) != 2 ) DIE("\"%s\" is not two digits\n", min_ptr); /* Finally, make sure they're not above 60 if higher unit exists */ if( min && sec > 60 ) DIE("\"%s\" is greater than 60\n", sec_ptr); else if( hr && min > 60 ) DIE("\"%s\" is greater than 60\n", min_ptr); total_secs = ( hr * 3600 ) + ( min * 60 ) + sec; } else { /* absolute seek (in seconds) */ total_secs = strtol( arg, &test, 10 ); /* get the # of seconds */ if( *test != '\0' || ( ! rel && total_secs < 0 )) DIE("\"%s\" is not a positive number\n", arg); } seekchange = total_secs; } /* This detects +/- and is necessary due to the parsing of HH:MM:SS numbers*/ if(rel == 1) { seekto = status->elapsedTime + seekchange; } else if (rel == -1) { seekto = status->elapsedTime - seekchange; } else { seekto = seekchange; } if(seekto > status->totalTime) DIE("Seek amount would seek past the end of the song\n"); mpd_sendSeekIdCommand(conn,status->songid,seekto); printErrorAndExit(conn); my_finishCommand(conn); printErrorAndExit(conn); mpd_freeStatus(status); printErrorAndExit(conn); return 1; }
int mpd_status_update(MpdObj *mi) { ChangedStatusType what_changed=0; if(!mpd_check_connected(mi)) { debug_printf(DEBUG_INFO,"Where not connected\n"); return MPD_NOT_CONNECTED; } if(mpd_lock_conn(mi)) { debug_printf(DEBUG_ERROR,"lock failed\n"); return MPD_LOCK_FAILED; } if(mi->status != NULL) { mpd_freeStatus(mi->status); mi->status = NULL; } mpd_sendStatusCommand(mi->connection); mi->status = mpd_getStatus(mi->connection); if(mi->status == NULL) { debug_printf(DEBUG_ERROR,"Failed to grab status from mpd\n"); mpd_unlock_conn(mi); return MPD_STATUS_FAILED; } if(mpd_unlock_conn(mi)) { debug_printf(DEBUG_ERROR, "Failed to unlock"); return MPD_LOCK_FAILED; } /* * check for changes */ /* first save the old status */ memcpy(&(mi->OldState), &(mi->CurrentState), sizeof(MpdServerState)); /* playlist change */ if(mi->CurrentState.playlistid != mi->status->playlist) { /* print debug message */ debug_printf(DEBUG_INFO, "Playlist has changed!"); /* We can't trust the current song anymore. so we remove it */ /* tags might have been updated */ if(mi->CurrentSong != NULL) { mpd_freeSong(mi->CurrentSong); mi->CurrentSong = NULL; } /* set MPD_CST_PLAYLIST to be changed */ what_changed |= MPD_CST_PLAYLIST; /* save new id */ mi->CurrentState.playlistid = mi->status->playlist; } /* state change */ if(mi->CurrentState.state != mi->status->state) { what_changed |= MPD_CST_STATE; mi->CurrentState.state = mi->status->state; } if(mi->CurrentState.songid != mi->status->songid) { /* print debug message */ debug_printf(DEBUG_INFO, "Song has changed %i %i!", mi->OldState.songid, mi->status->songid); what_changed |= MPD_CST_SONGID; /* save new songid */ mi->CurrentState.songid = mi->status->songid; } if(mi->CurrentState.songpos != mi->status->song) { /* print debug message */ debug_printf(DEBUG_INFO, "Song has changed %i %i!", mi->OldState.songpos, mi->status->song); what_changed |= MPD_CST_SONGPOS; /* save new songid */ mi->CurrentState.songpos = mi->status->song; } if(mi->CurrentState.repeat != mi->status->repeat) { what_changed |= MPD_CST_REPEAT; mi->CurrentState.repeat = mi->status->repeat; } if(mi->CurrentState.random != mi->status->random) { what_changed |= MPD_CST_RANDOM; mi->CurrentState.random = mi->status->random; } if(mi->CurrentState.volume != mi->status->volume) { what_changed |= MPD_CST_VOLUME; mi->CurrentState.volume = mi->status->volume; } if(mi->CurrentState.xfade != mi->status->crossfade) { what_changed |= MPD_CST_CROSSFADE; mi->CurrentState.xfade = mi->status->crossfade; } if(mi->CurrentState.totaltime != mi->status->totalTime) { what_changed |= MPD_CST_TOTAL_TIME; mi->CurrentState.totaltime = mi->status->totalTime; } if(mi->CurrentState.elapsedtime != mi->status->elapsedTime) { what_changed |= MPD_CST_ELAPSED_TIME; mi->CurrentState.elapsedtime = mi->status->elapsedTime; } /* Check if bitrate changed, happens with vbr encodings. */ if(mi->CurrentState.bitrate != mi->status->bitRate) { what_changed |= MPD_CST_BITRATE; mi->CurrentState.bitrate = mi->status->bitRate; } /* The following 3 probly only happen on a song change, or is it possible in one song/stream? */ /* Check if the sample rate changed */ if(mi->CurrentState.samplerate != mi->status->sampleRate) { what_changed |= MPD_CST_AUDIOFORMAT; mi->CurrentState.samplerate = mi->status->sampleRate; } /* check if the sampling depth changed */ if(mi->CurrentState.bits != mi->status->bits) { what_changed |= MPD_CST_AUDIOFORMAT; mi->CurrentState.bits = mi->status->bits; } /* Check if the amount of audio channels changed */ if(mi->CurrentState.channels != mi->status->channels) { what_changed |= MPD_CST_AUDIOFORMAT; mi->CurrentState.channels = mi->status->channels; } /* Check if the updating changed, * If it stopped, also update the stats for the new db-time. */ if(mi->CurrentState.updatingDb != mi->status->updatingDb ) { what_changed |= MPD_CST_UPDATING; if(!mi->status->updatingDb) { mpd_stats_update_real(mi, &what_changed); } mi->CurrentState.updatingDb = mi->status->updatingDb; } /* Run the callback */ if((mi->the_status_changed_callback != NULL) && what_changed) { mi->the_status_changed_callback( mi, what_changed, mi->the_status_changed_signal_userdata ); } /* We could have lost connection again during signal handling... so before we return check again if we are connected */ if(!mpd_check_connected(mi)) { return MPD_NOT_CONNECTED; } return MPD_OK; }
static void *update_mpd_thread(void *arg) { static mpd_Connection *conn = NULL; mpd_Status *status; mpd_InfoEntity *entity; timed_thread *me = *(timed_thread **)arg; const char *emptystr = ""; while (1) { if (!conn) conn = mpd_newConnection(mpd_host, mpd_port, 10); if (*mpd_password) { mpd_sendPasswordCommand(conn, mpd_password); mpd_finishCommand(conn); } timed_thread_lock(me); if (conn->error || conn == NULL) { NORM_ERR("MPD error: %s\n", conn->errorStr); mpd_closeConnection(conn); conn = 0; clear_mpd(); mpd_info.status = "MPD not responding"; timed_thread_unlock(me); if (timed_thread_test(me, 0)) { timed_thread_exit(me); } continue; } mpd_sendStatusCommand(conn); if ((status = mpd_getStatus(conn)) == NULL) { NORM_ERR("MPD error: %s\n", conn->errorStr); mpd_closeConnection(conn); conn = 0; clear_mpd(); mpd_info.status = "MPD not responding"; timed_thread_unlock(me); if (timed_thread_test(me, 0)) { timed_thread_exit(me); } continue; } mpd_finishCommand(conn); if (conn->error) { // fprintf(stderr, "%s\n", conn->errorStr); mpd_closeConnection(conn); conn = 0; timed_thread_unlock(me); if (timed_thread_test(me, 0)) { timed_thread_exit(me); } continue; } mpd_info.vol = status->volume; if (status->random == 0) { mpd_info.random = "Off"; } else if (status->random == 1) { mpd_info.random = "On"; } else { mpd_info.random = ""; } if (status->repeat == 0) { mpd_info.repeat = "Off"; } else if (status->repeat == 1) { mpd_info.repeat = "On"; } else { mpd_info.repeat = ""; } /* if (status->error) { printf("error: %s\n", status->error); } */ switch (status->state) { case MPD_STATUS_STATE_PLAY: mpd_info.status = "Playing"; break; case MPD_STATUS_STATE_STOP: mpd_info.status = "Stopped"; break; case MPD_STATUS_STATE_PAUSE: mpd_info.status = "Paused"; break; default: mpd_info.status = ""; clear_mpd(); break; } if (status->state == MPD_STATUS_STATE_PLAY || status->state == MPD_STATUS_STATE_PAUSE) { mpd_info.is_playing = 1; mpd_info.bitrate = status->bitRate; mpd_info.progress = (float) status->elapsedTime / status->totalTime; mpd_info.elapsed = status->elapsedTime; mpd_info.length = status->totalTime; } else { mpd_info.progress = 0; mpd_info.is_playing = 0; mpd_info.elapsed = 0; } if (conn->error) { // fprintf(stderr, "%s\n", conn->errorStr); mpd_closeConnection(conn); conn = 0; timed_thread_unlock(me); if (timed_thread_test(me, 0)) { timed_thread_exit(me); } continue; } mpd_sendCurrentSongCommand(conn); while ((entity = mpd_getNextInfoEntity(conn))) { mpd_Song *song = entity->info.song; if (entity->type != MPD_INFO_ENTITY_TYPE_SONG) { mpd_freeInfoEntity(entity); continue; } #define SONGSET(x) { \ free(mpd_info.x); \ if(song->x) \ mpd_info.x = strmdup(song->x); \ else \ mpd_info.x = strmdup(emptystr); \ } SONGSET(artist); SONGSET(albumartist); SONGSET(album); SONGSET(title); SONGSET(date); SONGSET(track); SONGSET(name); SONGSET(file); #undef SONGSET if (entity != NULL) { mpd_freeInfoEntity(entity); entity = NULL; } } mpd_finishCommand(conn); if (conn->error) { // fprintf(stderr, "%s\n", conn->errorStr); mpd_closeConnection(conn); conn = 0; timed_thread_unlock(me); if (timed_thread_test(me, 0)) { timed_thread_exit(me); } continue; } timed_thread_unlock(me); if (conn->error) { // fprintf(stderr, "%s\n", conn->errorStr); mpd_closeConnection(conn); conn = 0; if (timed_thread_test(me, 0)) { timed_thread_exit(me); } continue; } mpd_freeStatus(status); /* if (conn) { mpd_closeConnection(conn); conn = 0; } */ if (timed_thread_test(me, 0)) { timed_thread_exit(me); } continue; } /* never reached */ }
static void _mpdule_update_song (Instance * inst) { mpd_Connection *mpd; Evas_Object *mpdule; Evas_Object *o_popup; if (!inst->mpd) return; mpd = inst->mpd; mpdule = inst->mpdule; o_popup = inst->o_popup; mpd_sendStatusCommand (mpd); if (mpd->error == 0) { mpd_Status *status = mpd_getStatus (mpd); if (status) { if (status->state == MPD_STATUS_STATE_UNKNOWN) { edje_object_part_text_set (mpdule, "mpdule.status", D_ ("Unknown")); edje_object_part_text_set (o_popup, "mpdule.status", D_ ("Unknown")); } else if (status->state == MPD_STATUS_STATE_STOP) { edje_object_part_text_set (mpdule, "mpdule.status", D_ ("Stopped")); edje_object_part_text_set (o_popup, "mpdule.status", D_ ("Stopped")); } else if (status->state == MPD_STATUS_STATE_PLAY) { edje_object_part_text_set (mpdule, "mpdule.status", D_ ("Playing")); edje_object_part_text_set (o_popup, "mpdule.status", D_ ("Playing")); } else if (status->state == MPD_STATUS_STATE_PAUSE) { edje_object_part_text_set (mpdule, "mpdule.status", D_ ("Paused")); edje_object_part_text_set (o_popup, "mpdule.status", D_ ("Paused")); } if (status->state > MPD_STATUS_STATE_STOP) { mpd_sendCurrentSongCommand (mpd); mpd_InfoEntity *entity = NULL; while ((entity = mpd_getNextInfoEntity (mpd))) { if (entity->type == MPD_INFO_ENTITY_TYPE_SONG && entity->info.song->id == status->songid) { mpd_Song *song = entity->info.song; if (song->artist) { edje_object_part_text_set (mpdule, "mpdule.artist", song->artist); edje_object_part_text_set (o_popup, "mpdule.artist", song->artist); } else { edje_object_part_text_set (mpdule, "mpdule.artist", ""); edje_object_part_text_set (o_popup, "mpdule.artist", ""); } if (song->title) { edje_object_part_text_set (mpdule, "mpdule.title", song->title); edje_object_part_text_set (o_popup, "mpdule.title", song->title); } else { edje_object_part_text_set (mpdule, "mpdule.title", ""); edje_object_part_text_set (o_popup, "mpdule.title", ""); } if (song->album) { edje_object_part_text_set (mpdule, "mpdule.album", song->album); edje_object_part_text_set (o_popup, "mpdule.album", song->album); } else { edje_object_part_text_set (mpdule, "mpdule.album", ""); edje_object_part_text_set (o_popup, "mpdule.album", ""); } if (song->track) { edje_object_part_text_set (mpdule, "mpdule.track", song->track); edje_object_part_text_set (o_popup, "mpdule.track", song->track); } else { edje_object_part_text_set (mpdule, "mpdule.track", ""); edje_object_part_text_set (o_popup, "mpdule.track", ""); } if (song->date) { edje_object_part_text_set (mpdule, "mpdule.date", song->date); edje_object_part_text_set (o_popup, "mpdule.date", song->date); } else { edje_object_part_text_set (mpdule, "mpdule.date", ""); edje_object_part_text_set (o_popup, "mpdule.date", ""); } if (song->genre) { edje_object_part_text_set (mpdule, "mpdule.genre", song->genre); edje_object_part_text_set (o_popup, "mpdule.genre", song->genre); } else { edje_object_part_text_set (mpdule, "mpdule.genre", ""); edje_object_part_text_set (o_popup, "mpdule.genre", ""); } if (song->composer) { edje_object_part_text_set (mpdule, "mpdule.composer", song->composer); edje_object_part_text_set (o_popup, "mpdule.composer", song->composer); } else { edje_object_part_text_set (mpdule, "mpdule.composer", ""); edje_object_part_text_set (o_popup, "mpdule.composer", ""); } if (song->time) { //char * songtime; //sprintf(songtime, "%i", song->time); //edje_object_part_text_set (mpdule, "mpdule.time", songtime); //edje_object_part_text_set (o_popup, "mpdule.time", songtime); } else { edje_object_part_text_set (mpdule, "mpdule.time", ""); edje_object_part_text_set (o_popup, "mpdule.time", ""); } if (song->file) { edje_object_part_text_set (mpdule, "mpdule.file", song->file); edje_object_part_text_set (o_popup, "mpdule.file", song->file); } else { edje_object_part_text_set (mpdule, "mpdule.file", ""); edje_object_part_text_set (o_popup, "mpdule.file", ""); } } mpd_freeInfoEntity (entity); } } mpd_freeStatus (status); } } else { _mpdule_disconnect (inst); _mpdule_connect (inst); } }