示例#1
0
// ---------------------------------------------------------------------------
int main(int argc, char* argv[]) {
  // load settings
  Settings_Load("play.conf");

  // initialize signal handlers
  signal(SIGINT, (sig_t)cleanup);
  signal(SIGPIPE, (sig_t)broken_pipe);
  atexit(exit_func);
  
  player = Settings_Get("program", "player");
  strcpy(current_song, Settings_Get("path", "current_song"));
  buffer_size = atol(Settings_Get("program", "buffer"));
  
  // reset current song
  FILE* song_file = fopen(current_song, "w");
  fprintf(song_file, "%s\n", " - ");
  fclose(song_file);
    
  // save program name and url to play
  url = argv[1];
  path = argv[0];
  
  // start the stream
  start_stream();
  
  // if done, cleanup
  Settings_Unload();
  return 0;
}
// ---------------------------------------------------------------------------
int main(int argc, char* argv[]) {
	// initialize signal handlers
	signal(SIGINT, (sig_t)cleanup);
	signal(SIGHUP, (sig_t)next_song);

	// load settings
	Settings_Load("play.conf");
	
	// start playing
	if(is_mp3(argv[1])) {
		start_player(Settings_Get("program", "player"), argv[1]);
	} else if(is_playlist(argv[1])) {
		// get path
		int i;
		for(i = strlen(argv[1]) - 1; i >= 0; i--) {
		  if(argv[1][i] == '/') {
		    strcpy(root_path, argv[1]);
		    root_path[i] = '\0';
		    break;
		  }
		}
		//printf("playlist\r\n");
		play_playlist(Settings_Get("program", "player"), argv[1]);
	}
	
	// done playing, reset id3 info
	FILE* f = fopen(Settings_Get("path", "current_song"), "w");
	fprintf(f, "(no artist) - (no title)\r\n");
	fclose(f);
	
	Settings_Unload();
	
	return 0;
}
// ---------------------------------------------------------------------------
void dump_id3tag(char* file) {
	char buffer[512];
	sprintf(buffer, "id3v2 -R \"%s\" | grep TPE1 | cut -b 7- | tr -d \"\\n\" > \"%s\"", file, Settings_Get("path", "current_song"));
	system(buffer);
	sprintf(buffer, "echo -n \" - \" >> \"%s\"", Settings_Get("path", "current_song"));
	system(buffer);
	sprintf(buffer, "id3v2 -R \"%s\" | grep TIT2 | cut -b 7- >> \"%s\"", file, Settings_Get("path", "current_song"));
	system(buffer);
}
// ---------------------------------------------------------------------------
void resetMetaInfo() {
 // reset current song
 FILE* f = fopen(Settings_Get("files", "song"), "w");
 fprintf(f, " - ");
 fclose(f);
 f = fopen(Settings_Get("files", "current_station"), "w");
 fprintf(f, "\n");
 fclose(f);
 f = fopen(Settings_Get("files", "station_details"), "w");
 fprintf(f, "\n");
 fclose(f);
}
void doScan() {
  char buffer[128];
  
  // scan for wifi networks
  ignore_result(system(Settings_Get("programs", "wifi_scan")));
  
  FILE* f = fopen(Settings_Get("files", "wifi_networks"), "r");
  while(fgets(buffer, 128, f) != NULL) {
    char* name = trim(buffer);
    Menu_AddItem(menu_wifi_scan, name); 
  }
  fclose(f);
  
}
TsbHandler::TsbHandler()
{
    FNLOG(DL_MSP_MPLAYER);

    // Initializing the tsb availablility based on number of tuners from Unified settings.

    char tunerSettingbuffer[10] = {0};
    tSettingsAttributes attr;
    Settings_Get(NULL, "ciscoSg/media/numTuners", tunerSettingbuffer, (size_t) 3, &attr);
    dlog(DL_MSP_MPLAYER, DLOGL_ERROR, "%s[%d] TUNER COUNT FROM Unified Settings=%s", __FUNCTION__, __LINE__, tunerSettingbuffer);
    sscanf(tunerSettingbuffer, "%d", &mTsbCount);

    dlog(DL_MSP_MPLAYER, DLOGL_ERROR, "%s[%d] TSB COUNT=%d", __FUNCTION__, __LINE__, mTsbCount);

    mTsbInfo = new tsb_info((int)mTsbCount);

    for (int i = 0; i < mTsbInfo->tsb_count; i++)
    {
        mTsbInfo->tsb_availability[i] = true;
    }

    // Initialising the mutex that protects Mediaplayer shared resources
    pthread_mutexattr_t mta;
    pthread_mutexattr_init(&mta);
    pthread_mutexattr_settype(&mta, PTHREAD_MUTEX_RECURSIVE);
    pthread_mutex_init(&m_TsbHandlerMutex, &mta);
}
// ---------------------------------------------------------------------------
void stopMusic() {
  // stop music
  char cmd[128];
  sprintf(cmd, "%s &", Settings_Get("programs", "stop"));
  ignore_result(system(cmd));
  resetMetaInfo(); 
}
// ---------------------------------------------------------------------------
void parseCurrentStation() {
  // check if station is in station list
  strcpy(NowPlaying_CSInfo, "\n");
  FILE* f = fopen(Settings_Get("files", "station_details"), "r");
  if(f != NULL) {
    ignore_result(fgets(NowPlaying_CSInfo, 512, f));
    fclose(f);
  }
  
  NowPlaying_IsFavorite = 0;
  
  // if info is available, check if station is in station list
  if(strlen(NowPlaying_CSInfo) > 3) {
    int i;
    // remove newline
    for(i = 0; i < strlen(NowPlaying_CSInfo); i++) {
      if(NowPlaying_CSInfo[i] == '\r' || NowPlaying_CSInfo[i] == '\n') {
	NowPlaying_CSInfo[i] = '\0';
	break;
      }
    }
    
    // save current station details
    ArrayList* cur_info = AList_Split(NowPlaying_CSInfo, "|");
    NowPlaying_CurStation.name = (char*)AList_Get(cur_info, 0);
    NowPlaying_CurStation.url = (char*)AList_Get(cur_info, 1);
    NowPlaying_CurStation.genre = (char*)AList_Get(cur_info, 2);
    
    // check if in favorite list
    ArrayList* stations = readStations();
    for(i = 0; i < AList_Length(stations); i++) {
      StationInfo* info = AList_Get(stations, i);
      if(strcmp(info->url, (char*)AList_Get(cur_info, 1)) == 0) {
	NowPlaying_IsFavorite = 1;
	break;
      }
    }  
    freeStations(stations);
    AList_Destroy(stations);
    AList_Destroy(cur_info);
    
  }
}
// ---------------------------------------------------------------------------
void draw_NowPlaying() {
  char buffer[512];
  int idx;

  Screen_DrawBorder(_lng(NOW_PLAYING_TITLE));
  
  GLCDD_Rect r;
  
  FILE* f = fopen(SONG_FILE, "r");
  if(f == NULL) return;
  ignore_result(fgets(buffer, 512, f));
  fclose(f);
 
  // split songname - artist
  int i, found = 0;
  for(i = 0; i < strlen(buffer); i++) {
   if(buffer[i] == ' ' && buffer[i+1] == '-' && buffer[i+2] == ' ') {
     buffer[i+1] = 0;
     found = 1;
     break;
   }
  }
  if(!found) i = -3;
 
  r.x = 6;
  r.y = 14;
  r.w = SCREEN_W - 12;
  r.h = -1;
  idx = i + 3 + (NowPlaying_Sel == 1 ? NowPlaying_ScrollOffset : 0);
  // limit scrolling
  if(NowPlaying_Sel == 1) {
    if(GLCDD_StringWidth(fnt_dejavu_9b, &buffer[idx]) + r.x < r.w) {
      NowPlaying_ScrollDir *= -1; 
      if(idx > i + 3) idx--;
    }
    else if(NowPlaying_ScrollOffset < 0) {
      NowPlaying_ScrollDir *= -1;
      idx++;
    }
  }
  // draw title
  if(strlen(&buffer[idx]) > 1) GLCDD_Print(fnt_dejavu_9b, &r, &buffer[idx]); else GLCDD_Print(fnt_dejavu_9b, &r, _lng(NO_TITLE));
  
  r.y = 29;
  idx = (NowPlaying_Sel == 2 ? NowPlaying_ScrollOffset : 0);
  // limit scrolling
  if(NowPlaying_Sel == 2) {
    if(GLCDD_StringWidth(fnt_dejavu_9, &buffer[idx]) + r.x < r.w) {
      NowPlaying_ScrollDir *= -1; 
      if(idx > 0) idx--;
    }
    else if(NowPlaying_ScrollOffset < 0) {
      NowPlaying_ScrollDir *= -1;
      idx++;
    }
  }
  // draw artist
  if(strlen(&buffer[idx]) > 1) GLCDD_Print(fnt_dejavu_9, &r, &buffer[idx]); else GLCDD_Print(fnt_dejavu_9, &r, _lng(NO_ARTIST));
  
 
  // get station
  f = fopen(CURRENT_STATION_FILE, "r");
  if(f == NULL) return;
  ignore_result(fgets(buffer, 512, f));
  fclose(f);
 
  r.y = 44;
  idx = (NowPlaying_Sel == 3 ? NowPlaying_ScrollOffset : 0);
  // limit scroling
  if(NowPlaying_Sel == 3) {
    if(GLCDD_StringWidth(fnt_dejavu_9, &buffer[idx]) + r.x < r.w) {
      NowPlaying_ScrollDir *= -1; 
      if(idx > 0) idx--;
    }
    else if(NowPlaying_ScrollOffset < 0) {
      NowPlaying_ScrollDir *= -1;
      idx++;
    }
  }
  // draw station
  if(strlen(buffer) <= 2) GLCDD_Print(fnt_dejavu_9, &r, _lng(NO_STATION)); else GLCDD_Print(fnt_dejavu_9, &r, &buffer[idx]);
  
  // draw scrolling text if line is selected
  if(!NowPlaying_ShowMenu) {
    int8_t rotary = IO_GetRotaryValue();
    if(rotary != 0) {
      NowPlaying_ScrollOffset = 0;
      NowPlaying_ScrollDir = 1;
    }
    NowPlaying_Sel += rotary;
    if(NowPlaying_Sel < 0) NowPlaying_Sel = 0;
    if(NowPlaying_Sel >= 4) NowPlaying_Sel = 3;
    
    GLCDD_Invert(4, 12 + (NowPlaying_Sel - 1) * 15, SCREEN_W - 4, 12 + 2 + GLCDD_FontHeight(fnt_dejavu_9) + (NowPlaying_Sel - 1) * 15);
    
    if(NowPlaying_Sel != 0) NowPlaying_ScrollOffset += NowPlaying_ScrollDir;
  }
  
  
  // we play from usb and can therefore skip the song
  if(strncmp(buffer, _lng(USB), strlen(_lng(USB))) == 0) {
   GLCDD_RectRounded(SCREEN_W - 36, SCREEN_H - 14, 32, 10, 1);
   fnt_dejavu_9->color = 1;
   r.x = SCREEN_W - 29;
   r.y = SCREEN_H - 13;
   r.w = 28;
   r.h = -1;
   GLCDD_Print(fnt_dejavu_9, &r, _lng(NEXT));
   fnt_dejavu_9->color = 0;
   
   if(IO_GetButton(0)) {
      char cmd[64];
      sprintf(cmd, "%s &", Settings_Get("programs", "next_song"));
      ignore_result(system(cmd));
   }
  } else {
    // if no station is played, don't show menu
    if(strlen(buffer) <= 2) return; 
    
    // we play a station, enable context menu
    if(!NowPlaying_ShowMenu && IO_GetButton(0)) {
     createContextMenu();
     NowPlaying_ShowMenu = 1; 
    }
    
    if(NowPlaying_ShowMenu) Menu_Draw(menu_now_playing, 32, 16);
    
    int selection = Menu_IsChosen(menu_now_playing);
    if(selection != -1) {
      if(selection == 1) { 
	// snooze
	Screen_Goto(SCREEN_SNOOZE);
      }      
      if(selection == 2) { // add as favorite
	printf("add station '%s' as favorite\r\n", NowPlaying_CurStation.name);
	// add to favorite list
	ArrayList* stations = readStations();
	AList_Add(stations, &NowPlaying_CurStation);
	writeStations(stations);
	AList_Delete(stations, AList_Length(stations) - 1);
	freeStations(stations);
	AList_Destroy(stations);
      }
      
      NowPlaying_ShowMenu = 0; 
      Screen_ForceRedraw();
    }
  }
}
示例#10
0
// ---------------------------------------------------------------------------
int main(int argc, char* argv[]) {
 signal(SIGINT, (sig_t)cleanup);

 // load settings file
 char* settings_file = NULL;
 int settings = 0;
 if(argc == 2) {
   settings_file = argv[1];
   settings = Settings_Load(argv[1]);
 } 
 if(!settings) {
   settings_file = "default.conf";
   if(!Settings_Load("default.conf")) {
      printf("%s\r\n", _lng(ERROR_LOADING_SETTINGS));
      return 0;
   }
 }

 // load settings
 FW_VERSION = Settings_Get("gui", "version");
 SONG_FILE = Settings_Get("files", "song");
 CURRENT_STATION_FILE = Settings_Get("files", "current_station");
 STATIONS_FILE = Settings_Get("files", "stations");
 USB_PATH = Settings_Get("files", "usb");
 
 // check for running instance
 char* single_instance_cmd = Settings_Get("programs", "check_running");
 ignore_result(system(single_instance_cmd));
 FILE *running = fopen("fw.running", "r");
 if(running == NULL) {
   printf("Cannot check if firmware is running, aborting.\r\n");
   exit(0);
 }
 if(fgetc(running) >= '2') {
   fclose(running);
   printf("Firmware is already running!\r\nExiting...\r\n");
   exit(0);
 } else {
   fclose(running);
 }
 

 if(strcmp(Settings_Get("hardware", "io"), "sim") == 0) IO_SetSimulate(1);
 if(strcmp(Settings_Get("hardware", "lcd"), "sim") == 0) GLCDD_SetSimulate(1);
 else if(strcmp(Settings_Get("hardware", "lcd"), "bmp") == 0) GLCDD_SetSimulate(2);
  
 GLCDD_Init();
 IO_Init();

 Language_Init(Settings_Get("gui", "language"));
 Screen_Init(silkscreen_8);
 
 Screen screen = SCREEN_MAIN;
 
 // create fonts
 fnt_dejavu_9 = createFont(dejavu_9);
 fnt_dejavu_9b = createFont(dejavu_9_b);
 fnt_silkscreen_8 = createFont(silkscreen_8);
 
 // register screens
 Screen_Add(SCREEN_MAIN, init_Main, draw_Main, exit_Main);
 Screen_Add(SCREEN_NOW_PLAYING, init_NowPlaying, draw_NowPlaying, exit_NowPlaying);
 Screen_Add(SCREEN_STATIONS, init_Stations, draw_Stations, exit_Stations);
 Screen_Add(SCREEN_INFO, NULL, draw_Info, NULL);
 Screen_Add(SCREEN_USB, init_USB, draw_USB, NULL);
 Screen_Add(SCREEN_SHUTDOWN, init_Shutdown, draw_Shutdown, NULL);
 Screen_Add(SCREEN_SETTINGS, init_Settings, draw_Settings, exit_Settings);
 Screen_Add(SCREEN_WIFI_SCAN, init_WifiScan, draw_WifiScan, exit_WifiScan);
 Screen_Add(SCREEN_WIFI_AUTH, init_WifiAuth, draw_WifiAuth, NULL);
 Screen_Add(SCREEN_WIFI_CONNECT, init_WifiConnect, draw_WifiConnect, NULL);
 Screen_Add(SCREEN_LANGUAGE, init_Language, draw_Language, exit_Language);
 Screen_Add(SCREEN_VOLUME, init_Volume, draw_Volume, NULL);
 Screen_Add(SCREEN_SHOUTCAST, init_Shoutcast, draw_Shoutcast, exit_Shoutcast);
 Screen_Add(SCREEN_SHOUTCAST_LIST, init_ShoutcastList, draw_ShoutcastList, exit_ShoutcastList);
 Screen_Add(SCREEN_SHOUTCAST_GENRE, init_ShoutcastGenre, draw_ShoutcastGenre, exit_ShoutcastGenre);
 Screen_Add(SCREEN_SHOUTCAST_SEARCH, init_ShoutcastSearch, draw_ShoutcastSearch, NULL);
 Screen_Add(SCREEN_MANAGE_STATION, init_ManageStation, draw_ManageStation, exit_ManageStation);
 Screen_Add(SCREEN_SNOOZE, init_Snooze, draw_Snooze, exit_Snooze);
 Screen_Add(SCREEN_TIMEOUT, init_Timeout, draw_Timeout, NULL);
 Screen_SetRefreshTimeout(SCREEN_INFO, 2);
 Screen_SetRefreshTimeout(SCREEN_MAIN, 10);
 Screen_SetRefreshTimeout(SCREEN_NOW_PLAYING, 1);
 Screen_SetRefreshTimeout(SCREEN_STATIONS, 10);
 Screen_SetRefreshTimeout(SCREEN_USB, 1);
 Screen_SetRefreshTimeout(SCREEN_SHUTDOWN, 10);
 Screen_SetRefreshTimeout(SCREEN_WIFI_SCAN, 1); 
 Screen_SetRefreshTimeout(SCREEN_WIFI_AUTH, 10);
 Screen_SetRefreshTimeout(SCREEN_WIFI_CONNECT, 1);
 Screen_SetRefreshTimeout(SCREEN_LANGUAGE, 10);
 Screen_SetRefreshTimeout(SCREEN_VOLUME, 10);
 Screen_SetRefreshTimeout(SCREEN_SHOUTCAST, 10);
 Screen_SetRefreshTimeout(SCREEN_SHOUTCAST_LIST, 10);
 Screen_SetRefreshTimeout(SCREEN_SHOUTCAST_GENRE, 10);
 Screen_SetRefreshTimeout(SCREEN_SHOUTCAST_SEARCH, 10);
 Screen_SetRefreshTimeout(SCREEN_MANAGE_STATION, 10);
 Screen_SetRefreshTimeout(SCREEN_SNOOZE, 10);
 Screen_SetRefreshTimeout(SCREEN_TIMEOUT, 10);
 Screen_ShowLoadingScreen(SCREEN_USB, 1);
 Screen_ShowLoadingScreen(SCREEN_VOLUME, 1);
 Screen_ShowLoadingScreen(SCREEN_SHOUTCAST_LIST, 1);
 Screen_ShowLoadingScreen(SCREEN_SHOUTCAST_GENRE, 1);
 
  
 // reset song info
 resetMetaInfo();
 
 // start ui
 Screen_Goto(SCREEN_MAIN);
 
 // background light
 GLCDD_BacklightTimeout(atoi(Settings_Get("hardware", "timeout")));
 int keep_light_when_playing = 0;
 if(strcmp(Settings_Get("gui", "keep_light_when_playing"), "true") == 0) keep_light_when_playing = 1;
 GLCDD_BacklightReset();
 
 uint64_t last_io = 0;
 
 while(1) {

#ifndef SIMULATE
  if(getTimeMillisecond() - last_io >= 25) {
    IO_Get();
    last_io = getTimeMillisecond();
  }
#else
  IO_Get();
#endif
  if(IO_HasChanged()) {
    Screen_ForceRedraw();
    GLCDD_BacklightReset();
  }
  
  screen = Screen_GetActive();
  
  // ---------------------------------------------------------------------------
  if(screen == SCREEN_MAIN) {
    int selection = Menu_IsChosen(menu_main);
    if(selection == 0) {
      // goto now playing screen
      Screen_Goto(SCREEN_NOW_PLAYING);
    } else if(selection == 1) {
      // goto stations screen
      Screen_Goto(SCREEN_STATIONS);	
    } else if(selection == 2) {
      // goto shoutcast browser
      Screen_Goto(SCREEN_SHOUTCAST);
    } else if(selection == 3) {
      // goto usb screen
      Screen_Goto(SCREEN_USB);
    } else if(selection == 4) {
      // goto info screen
      Screen_Goto(SCREEN_SETTINGS);
    }
  }
  // ---------------------------------------------------------------------------
  else if(screen == SCREEN_INFO) {
    if(IO_GetButton(0)) {
      Screen_Goto(SCREEN_SETTINGS);
    }
  }
  // ---------------------------------------------------------------------------
  else if(screen == SCREEN_STATIONS) {
    int selection = Menu_IsChosen(menu_stations);
    if(selection != -1) {
      // start station
      playStation(Menu_GetItemTag(menu_stations, selection));
    }
    
    // add station as favorite
    if(IO_GetButtonLong(3)) asFavorite(1);
    if(IO_GetButtonLong(4)) asFavorite(2);
    if(IO_GetButtonLong(5)) asFavorite(3);
    if(IO_GetButtonLong(6)) asFavorite(4);
  }
  // ---------------------------------------------------------------------------
  else if(screen == SCREEN_NOW_PLAYING) {
    // if at now playing screen, backlight is always on
    if(keep_light_when_playing) GLCDD_BacklightReset(); 
  }
  // ---------------------------------------------------------------------------
  else if(screen == SCREEN_SETTINGS) {
      int selection = Menu_IsChosen(menu_settings);
      if(selection == 0) {
	// goto info screen
	Screen_Goto(SCREEN_INFO);
      } else if(selection == 1) {
	// goto wifi scanning screen
	Screen_Goto(SCREEN_WIFI_SCAN);
      } else if(selection == 2) {
	// goto language selection
	Screen_Goto(SCREEN_LANGUAGE);
      } else if(selection == 3) {
	// goto volume adjustment
	Screen_Goto(SCREEN_VOLUME);
      } else if(selection == 4) {
	// goto backlight timeout
	Screen_Goto(SCREEN_TIMEOUT);
      } else if(selection == 5) {
	// goto station manager
	Screen_Goto(SCREEN_MANAGE_STATION);
      } else if(selection == 6) {
	// restart firmware
	// stop all music
	stopMusic();
	// kill all streams
	ignore_result(system(Settings_Get("programs", "killall")));
	// restart self
	execv(argv[0], argv);
      } else if(selection == 7) {
	// shutdown
	Screen_Goto(SCREEN_SHUTDOWN); 
      }
  }
  // ---------------------------------------------------------------------------
  else if(screen == SCREEN_WIFI_SCAN) {
      int selection = Menu_IsChosen(menu_wifi_scan);
      if(selection != -1) {
	// save ssid
	Settings_Add("wifi", "ssid", Menu_GetItemText(menu_wifi_scan, selection));
	// go to authentification
	Screen_Goto(SCREEN_WIFI_AUTH);
      }
  }
  // ---------------------------------------------------------------------------
  else if(screen == SCREEN_WIFI_AUTH) {
      if(Keyboard_IsConfirmed()) {
	// connect to wifi network
	Settings_Add("wifi", "pwd", Keyboard_GetText());
	printf("Connecting to '%s' with key '%s'\r\n", Settings_Get("wifi", "ssid"), Settings_Get("wifi", "pwd"));
	Screen_Goto(SCREEN_WIFI_CONNECT);
      }
  }
  // ---------------------------------------------------------------------------
  else if(screen == SCREEN_LANGUAGE) {
      // change language
      int selection = Menu_IsChosen(menu_language);
      if(selection != -1) {
	char disp[64];
	int i;
	strcpy(disp, Menu_GetItemText(menu_language, selection));
	for(i = strlen(disp) - 1; i >= 0; i--) {
	  if(disp[i] == ')') disp[i] = 0;
	  if(disp[i] == '(') {
	   i++;
	   break;
	  }
	}
	Settings_Add("gui", "language", &disp[i]);
	Language_Cleanup();
	Language_Init(&disp[i]);
	Settings_Save(settings_file);
	Screen_Goto(SCREEN_SETTINGS);
      }
  }
  // ---------------------------------------------------------------------------
  else if(screen == SCREEN_VOLUME) {
      if(IO_GetButton(0)) {
	// go back to settings
	Screen_Goto(SCREEN_SETTINGS);
      }
  }
  // ---------------------------------------------------------------------------
  else if(screen == SCREEN_SHOUTCAST) {
      int selection = Menu_IsChosen(menu_shoutcast);
      if(selection == 0) {
	// go to shoutcast top stations
	setShoutcastListUrl(Settings_Get("shoutcast", "list_url"));
	printf("'%s'\r\n", Settings_Get("shoutcast", "list_url"));
	setStationsParentGenre("X");
	setCurrentGenre(" ");
	Screen_Goto(SCREEN_SHOUTCAST_LIST);
      } 
      else if(selection == 1) { 
	// random station
	setShoutcastListUrl(Settings_Get("shoutcast", "random_url"));
	setStationsParentGenre("X");
	setCurrentGenre(" ");
	Screen_Goto(SCREEN_SHOUTCAST_LIST);
      }
      else if(selection == 2) {
	// go to genre list
	setShoutcastGenreParent("0");
	Screen_Goto(SCREEN_SHOUTCAST_GENRE);
      }
      else if(selection == 3) {
	// go to station search
	Screen_Goto(SCREEN_SHOUTCAST_SEARCH);
      }
  }
  // ---------------------------------------------------------------------------
  else if(screen == SCREEN_SHOUTCAST_GENRE) {
      int selection = Menu_IsChosen(menu_genres);
      if(selection != -1) {
	if(selection == 0) { // back
	  if(strcmp(getShoutcastGenreParent(), "0") == 0) { // main genres
	    Screen_Goto(SCREEN_SHOUTCAST);
	  } else { // sub genre -> go back to main genres
	    setShoutcastGenreParent("0");
	    Screen_Goto(SCREEN_SHOUTCAST_GENRE);
	  }
	} else { // list stations or sub genre
	  ShoutcastGenre* info = getChosenGenre((int)Menu_GetItemTag(menu_genres, selection));
	  // show sub genres
	  if(info->has_children) {
	    setStationsParentGenre(info->id);
	    setShoutcastGenreParent(info->id);
	    Screen_Goto(SCREEN_SHOUTCAST_GENRE);
	  } else { // show stations
	    char buffer[128];
	    sprintf(buffer, Settings_Get("shoutcast", "stations_by_genre_url"), info->name);
	    setShoutcastListUrl(buffer);
	    setCurrentGenre(info->name);
	    Screen_Goto(SCREEN_SHOUTCAST_LIST);
	  }
	}
      }
  }
  // ---------------------------------------------------------------------------
  else if(screen == SCREEN_SHOUTCAST_LIST) {
      if(Menu_GetAutoIO(menu_station_list)) {
	int selection = Menu_IsChosen(menu_station_list);
	if(selection != -1) {
	  if(selection == 0) { // back
	      if(strcmp(getStationsParentGenre(), "X") == 0) { // go to shoutcast menu
		Screen_Goto(SCREEN_SHOUTCAST); 
	      } else { // go to genre list
		setShoutcastGenreParent(getStationsParentGenre());
		Screen_Goto(SCREEN_SHOUTCAST_GENRE);
	      }
	  } else { // show play/as_favorite/cancel menu
	      Menu_SetAutoIO(menu_station_list, 0);
	      Screen_ForceRedraw();
	  }
	}
      } else {
	int selection = Menu_IsChosen(menu_play_fav);
	if(selection != -1) {
	  Menu_SetAutoIO(menu_station_list, 1);
	  Screen_ForceRedraw();
	  
	  if(selection == 0) { // play
	      ShoutcastStation* info = getChosenStation((int)Menu_GetItemTag(menu_station_list, Menu_GetSelectedItem(menu_station_list)));
	      StationInfo* station = parseShoutcastList(info);
	      station->genre = getCurrentGenre();
	      playStation(station);
	      free(station->url);
	      free(station);
	  }
	  else if(selection == 1) { // add to station list
	      ShoutcastStation* sc_stat = getChosenStation((int)Menu_GetItemTag(menu_station_list, Menu_GetSelectedItem(menu_station_list)));
	      StationInfo* stat = parseShoutcastList(sc_stat);
	      
	      StationInfo* info = (StationInfo*)malloc(sizeof(StationInfo));
	      info->tag = '\0';
	      info->name = stat->name;
	      info->url = stat->url;
	      info->genre = getCurrentGenre();
	      
	      ArrayList* stations = readStations();
	      AList_Add(stations, info);
	      writeStations(stations);
	      AList_Delete(stations, AList_Length(stations) - 1);
	      freeStations(stations);
	      AList_Destroy(stations);
	      free(stat->url);
	      free(stat);
	      free(info);
	  }
	  else if(selection == 2) { // cancel
	    // do nothing
	  } 
	}
      }
  }
  // ---------------------------------------------------------------------------
  else if(screen == SCREEN_SHOUTCAST_SEARCH) {
    if(Keyboard_IsConfirmed()) {
      char buffer[256];
      sprintf(buffer, Settings_Get("shoutcast", "search_url"), Keyboard_GetText());
      setShoutcastListUrl(buffer);
      setStationsParentGenre("X");
      setCurrentGenre(" ");
      Screen_Goto(SCREEN_SHOUTCAST_LIST);
    }
  }
  // ---------------------------------------------------------------------------
  else if(screen == SCREEN_MANAGE_STATION) {
      if(Menu_GetAutoIO(menu_m_station)) { // handle station list menu
	int selection = Menu_IsChosen(menu_m_station);
	if(selection != -1) { // show menu
	  Menu_SetAutoIO(menu_m_station, 0);
	  Menu_ScrollTo(menu_m_menu, 0);
	  Screen_ForceRedraw();
	}
      } else {
	if(Menu_GetAutoIO(menu_m_menu)) { // handle station menu
	    int selection = Menu_IsChosen(menu_m_menu);
	    
	    if(selection == 0) {
	      // do nothing (cancel)
	    }
	    else if(selection == 1) {
	      // move -> handled below
	    }
	    else if(selection == 2) {
	      deleteStation(Menu_GetSelectedItem(menu_m_station));
	      Screen_Goto(SCREEN_MANAGE_STATION);
	    }
	    
	    // close menu
	    if(selection != -1) {
	      if(selection == 1) { // move -> disable all menus
		Menu_SetAutoIO(menu_m_menu, 0);
		Menu_SetTitleTag(menu_m_station, Menu_GetSelectedItem(menu_m_station), '*');
		Screen_ForceRedraw();
	      } else {
		Menu_SetAutoIO(menu_m_station, 1);
		Screen_ForceRedraw();
	      }
	    }
	}
	
	else { // moving stations
	  if(IO_GetButton(0)) { // we are done
	    Menu_SetTitleTag(menu_m_station, Menu_GetSelectedItem(menu_m_station), 0);
	    ArrayList* new_stations = AList_Create();
	    int i;
	    for(i = 0; i < Menu_GetItems(menu_m_station); i++) {
	      StationInfo* info = Menu_GetItemTag(menu_m_station, i);
	      AList_Add(new_stations, info);
	    }
	    writeStations(new_stations);
	    AList_Destroy(new_stations);
	    
	    Menu_SetAutoIO(menu_m_menu, 1);
	    Menu_SetAutoIO(menu_m_station, 1);
	    Screen_ForceRedraw();
	  }
	  else {
	   int8_t rotary = IO_GetRotaryValue();
	   if(rotary != 0) {
	      int index = Menu_GetSelectedItem(menu_m_station);
	      int new_index = index + ((rotary > 0) ? 1 : -1);
	      Menu_SwapItems(menu_m_station, index, new_index); 
	      Menu_Scroll(menu_m_station, (rotary > 0) ? 1 : -1);
	   }
	  }
	  
	}
	
      }
  }
  // ---------------------------------------------------------------------------
  else if(screen == SCREEN_TIMEOUT) {
     if(IO_GetButton(0)) {
      // go back to settings
      char buffer[8];
      sprintf(buffer, "%d", Timeout_Get());
      Settings_Add("hardware", "timeout", buffer);
      Settings_Save(settings_file);
      GLCDD_BacklightTimeout(Timeout_Get());      
      Screen_Goto(SCREEN_SETTINGS); 
    }     
  }
  // ---------------------------------------------------------------------------

  // home button
  if(IO_GetButton(1)) Screen_Goto(SCREEN_MAIN);
  
  // play/stop button
  if(IO_GetButton(2)) {
    if(screen != SCREEN_USB) {
      // stop music
      stopMusic();
    } else {
      // play folder
      int i;
      FILE* f = fopen("/tmp/playlist1.m3u", "w");
      for(i = 0; i < Menu_GetItems(menu_usb); i++) {
	// a file, add it to the list
	if((int)Menu_GetItemTag(menu_usb, i) == 0) {
	  fprintf(f, "%s/%s\r\n", usb_root, Menu_GetItemText(menu_usb, i));
	}
      }
      fclose(f);
      char cmd[128];
      sprintf(cmd, "%s /tmp/playlist1.m3u > /tmp/playlist.m3u", Settings_Get("programs", "shuffle"));
      ignore_result(system(cmd));
      
      playUSB("/tmp/playlist.m3u");
    }
  }
  
  // end of snooze time
  if(checkSnoozeStop()) {
   // stop the music
   stopMusic();
   // go to main screen
   Screen_Goto(SCREEN_MAIN);
  }
  
  // (1) button
  if(IO_GetButton(3)) playFavorite(1);
  // (2) button
  if(IO_GetButton(4)) playFavorite(2);
  // (3) button
  if(IO_GetButton(5)) playFavorite(3);
  // (4) button
  if(IO_GetButton(6)) playFavorite(4);
  
  Screen_Draw();

  GLCDD_BacklightUpdate();
  
  usleep(100);
//sleep(1);
 
 }
 
 // really no need to cleanup, as firmware runs as long as device is powered
 // plus, the operating system frees all resources anyway
 
}