// FLTK callback functions for butt
//
// Copyright 2007 by Daniel Noethen.
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2, or (at your option)
// any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
#include <errno.h>
#include <unistd.h>
#include <signal.h>
#include <time.h>
#ifndef _WIN32
#include <sys/wait.h>
#endif
#include <FL/Fl_Native_File_Chooser.H>
#include <FL/fl_ask.H>
#include <FL/Fl_File_Chooser.H>
#include <FL/Fl_Color_Chooser.H>
#include "cfg.h"
#include "butt.h"
#include "port_audio.h"
#include "timer.h"
#include "shoutcast.h"
#include "lame_encode.h"
#include "fl_callbacks.h"
#include "strfuncs.h"
#include "config.h"
flgui *fl_g = new flgui();
int display_info = STREAM_TIME;
void button_connect_cb()
{
if(connected)
return;
int (*xc_connect)() = NULL;
int rv;
int dummy = 0;
char text_buf[256];
if(cfg.main.num_of_srv < 1)
{
print_info("There must be at least one server defined.\n"
"Click on the red button right to the LCD to\n"
"add a server", 1);
return;
}
if(cfg.srv[cfg.selected_srv]->type == SHOUTCAST)
xc_connect = &sc_connect;
if(cfg.srv[cfg.selected_srv]->type == ICECAST)
{
#if HAVE_LIBSHOUT
xc_connect = &ic_connect;
#else
print_info("butt compiled without icecast support", 1);
return;
#endif
}
if(!strcmp(cfg.audio.codec, "ogg") && (cfg.audio.bitrate < 48))
{
print_info("ogg doesn't seem to support bitrates \n"
"lower than 48kbit",1);
return;
}
if(!strcmp(cfg.audio.codec, "ogg") && (cfg.srv[cfg.selected_srv]->type == SHOUTCAST))
{
print_info("ShoutCast doesn't support ogg", 1);
return;
}
if(cfg.main.num_of_srv < 1)
{
print_info("There must be at least one server defined.\n"
"Click on the red button right to the LCD to\n"
"add a server", 1);
return;
}
if(cfg.srv[cfg.selected_srv]->type == SHOUTCAST)
snprintf(text_buf, sizeof(text_buf), "Connecting to %s:%u (%u) ...",
cfg.srv[cfg.selected_srv]->addr,
cfg.srv[cfg.selected_srv]->port+1,
cfg.srv[cfg.selected_srv]->port);
else
snprintf(text_buf, sizeof(text_buf), "Connecting to %s:%u ...",
cfg.srv[cfg.selected_srv]->addr,
cfg.srv[cfg.selected_srv]->port);
print_info(text_buf, 0);
try_to_connect = 1;
while((rv = xc_connect()))
{
if( (rv == 2) || (try_to_connect == 0) )
{
try_to_connect = 0; //invalid password or the user has pressed the stop button
return;
}
switch(dummy)
{
case 0:
print_lcd("connecting", 10, 0, 1);
dummy++;
break;
case 1:
case 2:
case 3:
print_lcd(".", 1, 0, 0);
dummy++;
break;
case 4:
dummy = 0;
break;
default:
dummy++;
}
Fl::check();
}
if(connected)
{
print_info("connected", 0);
//the user may not change the sound device while streaming
fl_g->choice_cfg_dev->deactivate();
//the sames applies to the codecs
fl_g->radio_cfg_codec_mp3->deactivate();
fl_g->radio_cfg_codec_ogg->deactivate();
//Changing any audio settings while streaming does not work with ogg :(
if(!strcmp(cfg.audio.codec, "ogg"))
{
fl_g->choice_cfg_bitrate->deactivate();
fl_g->choice_cfg_samplerate->deactivate();
fl_g->radio_cfg_channel_mono->deactivate();
fl_g->radio_cfg_channel_stereo->deactivate();
}
fl_g->xrun->value(0);
fl_g->lcd->clear();
fl_g->lcd->print((const uchar*)"info: idle", 10);
pa_new_frames = 0;
//timer_init(&stream_time);
if(!recording)//We dont need to start this timeout if recording is running
Fl::add_timeout(0.1, &check_time);
Fl::add_timeout(0.05, &check_xrun);
Fl::add_timeout(0.1, &check_if_disconnected);
snd_start_stream();
if(record && cfg.rec.start_rec)
{
snd_start_rec();
timer_init(&rec_time);
}
display_info = STREAM_TIME;
}
}
void button_cfg_cb()
{
if(fl_g->window_cfg->shown())
{
fl_g->window_cfg->hide();
fl_g->button_cfg->label("@>");
Fl::remove_timeout(&check_cfg_win_pos);
}
else
{
/*
* This is a bit stupid. Well, its Win32...
* We need to place the cfg window a bit more to the right, otherwise
* the main und the cfg window would overlap
*/
#ifdef _WIN32
fl_g->window_cfg->position(fl_g->window_main->x() +
fl_g->window_main->w()+7,
fl_g->window_main->y());
#else
fl_g->window_cfg->position(fl_g->window_main->x() +
fl_g->window_main->w(),
fl_g->window_main->y());
#endif
fl_g->window_cfg->show();
fl_g->button_cfg->label("@<");
fill_cfg_widgets();
if(cfg.gui.attach)
Fl::add_timeout(0.1, &check_cfg_win_pos);
}
}
void button_add_srv_add_cb()
{
int i;
//error checking
if(strlen(fl_g->input_add_srv_name->value()) == 0)
{
fl_alert("No name specified");
return;
}
if(strlen(fl_g->input_add_srv_addr->value()) == 0)
{
fl_alert("No address specified");
return;
}
if(strlen(fl_g->input_add_srv_pwd->value()) == 0)
{
fl_alert("No password specified");
return;
}
if(strlen(fl_g->input_add_srv_port->value()) == 0)
{
fl_alert("No port specified");
return;
}
else if(( atoi(fl_g->input_add_srv_port->value()) > 65535) ||
(atoi(fl_g->input_add_srv_port->value()) < 0) )
{
fl_alert("Invalid portnumber\nThe portnumber may range from 0 to 65535");
return;
}
i = cfg.main.num_of_srv;
cfg.main.num_of_srv++;
cfg.srv = (server_t**)realloc(cfg.srv, cfg.main.num_of_srv * sizeof(server_t*));
cfg.srv[i] = (server_t*)malloc(sizeof(server_t));
cfg.srv[i]->name = (char*)malloc(strlen(fl_g->input_add_srv_name->value())+1);
strcpy(cfg.srv[i]->name, fl_g->input_add_srv_name->value());
cfg.srv[i]->addr = (char*)malloc(strlen(fl_g->input_add_srv_addr->value())+1);
strcpy(cfg.srv[i]->addr, fl_g->input_add_srv_addr->value());
cfg.srv[i]->pwd = (char*)malloc(strlen(fl_g->input_add_srv_pwd->value())+1);
strcpy(cfg.srv[i]->pwd, fl_g->input_add_srv_pwd->value());
cfg.srv[i]->port = (unsigned int)atoi(fl_g->input_add_srv_port->value());
if(fl_g->radio_add_srv_icecast->value())
{
cfg.srv[i]->mount = (char*)malloc(strlen(fl_g->input_add_srv_mount->value())+1);
strcpy(cfg.srv[i]->mount, fl_g->input_add_srv_mount->value());
}
if(fl_g->radio_add_srv_shoutcast->value())
cfg.srv[i]->type = SHOUTCAST;
if(fl_g->radio_add_srv_icecast->value())
cfg.srv[i]->type = ICECAST;
if(cfg.main.num_of_srv > 1)
{
cfg.main.srv_ent = (char*)realloc(cfg.main.srv_ent,
strlen(cfg.main.srv_ent) +
strlen(cfg.srv[i]->name) +2);
sprintf(cfg.main.srv_ent, "%s;%s", cfg.main.srv_ent, cfg.srv[i]->name);
}
else
{