darkice/darkice-gui/trunk/interface.c

396 lines
12 KiB
C

/* Darksnow - A GUI for darkice
* Copyright (C) 2004-2005 Rafael Diniz <rafael@riseup.net>
*
* This source code is free software; you can redistribute it and/or
* modify it under the terms of the GNU Public License as published
* by the Free Software Foundation; either version 2 of the License,
* or (at your option) any later version.
*
* This source code 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.
* Please refer to the GNU Public License for more details.
*
* You should have received a copy of the GNU Public License along with
* this source code; if not, write to:
* Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <libintl.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <dirent.h>
#include <signal.h>
#ifndef __GLOBAL_H__
#include "global.h"
#endif
#ifndef __CONSTANTS_H__
#include "constants.h"
#endif
#ifndef __GTK_H__
#include <gtk/gtk.h>
#endif
#ifndef __CONFIG_FILES_H__
#include "config_files.h"
#endif
#ifndef __INTERFACE_H__
#include "interface.h"
#endif
#ifdef FUNNY
#define FUN 1
#else
#define FUN 0
#endif
/* callback that start darkice */
void dark_start( GtkWidget *widget, gpointer data) {
char *darkice_verbosity;
char command[128], foo, dark_output[128];
/* if the first caracter of shared area is 1, means that the streaming is running and we cannot start another darkice */
sscanf((char *) shared_area, "%c", &foo);
if (foo == '1')
return;
/* call the function that load the values from widgets and save to the darksnow config file */
darksnow_config_store(1, NULL);
/* call the function that translate the darksnow config file to the darkice config file */
darksnow2darkice_cfg();
darkice_verbosity = (char *) gtk_entry_get_text ( GTK_ENTRY(GTK_COMBO(combo_verbosity)->entry));
strcpy(command,"darkice");
strcat(command," -v ");
strcat(command, darkice_verbosity);
strcat(command," -c ");
strcat(command, darkice_cfg);
strcat(command," > ");
strcat(command, darksnow_temp);
if ((pid = fork()) == -1) {
printf("Fork error! God save the queen!\n");
gtk_main_quit();
}
if (!pid) {
/* streaming started */
sprintf ((char *) shared_area, "11");
system(command);
/* if the system() returns, this means that the streaming stopped */
sprintf ((char *) shared_area, "01");
_exit(-1);
}
strcpy(dark_output, gettext("--> Command <--\n"));
strcat(dark_output, command);
strcat(dark_output, gettext("\n--> Darkice output <--\n") );
gtk_text_buffer_set_text (buffer, dark_output , strlen(dark_output));
/* print the darkice output for the first time */
usleep(200000);
text_box_loop (1);
}
/* callback that stop darkice */
void dark_stop( GtkWidget *widget, gpointer data ){
char out[32];
system("killall darkice &> /dev/null");
strcpy(out, gettext("Darkice off") );
gtk_text_buffer_set_text (buffer, out, strlen(out));
}
void dark_put_in_box ( GtkWidget *widget, gpointer data ) {
FILE *f_darksnow_cfg;
char *darksnow_path;
char foo[256] = {0};
char server[256] = {0};
char port[128] = {0};
char mountpoint[128] = {0};
char pass[128] = {0};
char remotedump[256] = {0};
char localdump[256] = {0};
char adddate;
char radioname[128] = {0};
char description[256] = {0};
char url[256] = {0};
char genre[128] = {0};
char icecast[128] = {0};
char format[128] = {0};
char bitrate[128] = {0};
char bitratemode[128] = {0};
char samplerate[128] = {0};
char quality[128] = {0};
char bitspersample[128] = {0};
char channel[128] = {0};
char buffersize[128] = {0};
char device[128] = {0};
char public[128] = {0};
char verbosity[8] = {0};
DIR *directory;
darksnow_path = (char *) gtk_file_selection_get_filename (GTK_FILE_SELECTION (file_open));
if ( (directory = opendir(darksnow_path))) {
printf("Error: %s is a directory\n", darksnow_path);
closedir (directory);
return;
}
if (!(f_darksnow_cfg = fopen(darksnow_path, "r"))) {
printf("Error: Cannot open %s\n", darksnow_path);
return;
}
fscanf(f_darksnow_cfg, "%[^=]=%[^\n]\n", foo, server);
fscanf(f_darksnow_cfg, "%[^=]=%[^\n]\n", foo, port);
fscanf(f_darksnow_cfg, "%[^=]=%[^\n]\n", foo, mountpoint);
fscanf(f_darksnow_cfg, "%[^=]=%[^\n]\n", foo, pass);
fscanf(f_darksnow_cfg, "%[^=]=%[^\n]\n", foo, radioname);
fscanf(f_darksnow_cfg, "%[^=]=%[^\n]\n", foo, description);
fscanf(f_darksnow_cfg, "%[^=]=%[^\n]\n", foo, url);
fscanf(f_darksnow_cfg, "%[^=]=%[^\n]\n", foo, genre);
fscanf(f_darksnow_cfg, "%[^=]=%[^\n]\n", foo, icecast);
fscanf(f_darksnow_cfg, "%[^=]=%[^\n]\n", foo, format);
fscanf(f_darksnow_cfg, "%[^=]=%[^\n]\n", foo, bitrate);
fscanf(f_darksnow_cfg, "%[^=]=%[^\n]\n", foo, bitratemode);
fscanf(f_darksnow_cfg, "%[^=]=%[^\n]\n", foo, samplerate);
fscanf(f_darksnow_cfg, "%[^=]=%[^\n]\n", foo, quality);
fscanf(f_darksnow_cfg, "%[^=]=%[^\n]\n", foo, bitspersample);
fscanf(f_darksnow_cfg, "%[^=]=%[^\n]\n", foo, channel);
fscanf(f_darksnow_cfg, "%[^=]=%[^\n]\n", foo, buffersize);
fscanf(f_darksnow_cfg, "%[^=]=%[^\n]\n", foo, device);
fscanf(f_darksnow_cfg, "%[^=]=%[^\n]\n", foo, public);
fscanf(f_darksnow_cfg, "%[^=]=%[^\n]\n", foo, verbosity);
fscanf(f_darksnow_cfg, "%[^=]=%[^\n]\n", foo, remotedump);
fscanf(f_darksnow_cfg, "%[^=]=%[^\n]\n", foo, localdump);
fscanf(f_darksnow_cfg, "%[^=]=%c\n", foo, &adddate);
gtk_entry_set_text ( (GtkEntry *) entry_server, server);
gtk_entry_set_text ( (GtkEntry *) entry_port, port);
gtk_entry_set_text ( (GtkEntry *) entry_mountpoint, mountpoint);
gtk_entry_set_text ( (GtkEntry *) entry_pass, pass);
gtk_entry_set_text ( (GtkEntry *) entry_radioname, radioname);
gtk_entry_set_text ( (GtkEntry *) entry_description, description);
gtk_entry_set_text ( (GtkEntry *) entry_url, url);
gtk_entry_set_text ( (GtkEntry *) entry_genre, genre);
gtk_entry_set_text ( (GtkEntry *) entry_server, server);
gtk_entry_set_text ( (GtkEntry *) entry_remotedump, remotedump);
gtk_entry_set_text ( (GtkEntry *) entry_localdump, localdump);
gtk_entry_set_text ( GTK_ENTRY(GTK_COMBO(combo_icecast)->entry), icecast);
gtk_entry_set_text ( GTK_ENTRY(GTK_COMBO(combo_format)->entry), format);
gtk_entry_set_text ( GTK_ENTRY(GTK_COMBO(combo_bitrate)->entry), bitrate);
gtk_entry_set_text ( GTK_ENTRY(GTK_COMBO(combo_bitratemode)->entry), bitratemode);
gtk_entry_set_text ( GTK_ENTRY(GTK_COMBO(combo_samplerate)->entry), samplerate);
gtk_entry_set_text ( GTK_ENTRY(GTK_COMBO(combo_quality)->entry), quality);
gtk_entry_set_text ( GTK_ENTRY(GTK_COMBO(combo_bitspersample)->entry), bitspersample);
gtk_entry_set_text ( GTK_ENTRY(GTK_COMBO(combo_channel)->entry), channel);
gtk_entry_set_text ( GTK_ENTRY(GTK_COMBO(combo_buffersize)->entry), buffersize);
gtk_entry_set_text ( GTK_ENTRY(GTK_COMBO(combo_device)->entry), device);
gtk_entry_set_text ( GTK_ENTRY(GTK_COMBO(combo_public)->entry), public);
gtk_entry_set_text ( GTK_ENTRY(GTK_COMBO(combo_verbosity)->entry), verbosity);
if (adddate == '1')
gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON (checkbutton_adddate), TRUE);
else
gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON (checkbutton_adddate), FALSE);
fclose(f_darksnow_cfg);
gtk_widget_hide(file_open);
}
void dark_write_config ( GtkWidget *widget, gpointer data ) {
char *darksnow_path;
darksnow_path = (char *) gtk_file_selection_get_filename (GTK_FILE_SELECTION (file_save));
if (darksnow_config_store (0, darksnow_path))
gtk_widget_hide(file_save);
}
void dark_about ( GtkWidget *widget, gpointer data ) {
gtk_widget_show (dialog_about);
}
void dark_localdump (GtkWidget *widget, gpointer data){
gtk_entry_set_text ( (GtkEntry *) entry_localdump, (char *) gtk_file_selection_get_filename (GTK_FILE_SELECTION (file_localdump)) );
gtk_widget_hide (file_localdump);
}
void clean_text_view_memory(){
GtkTextIter start_iter, end_iter;
gtk_text_buffer_get_bounds (buffer, &start_iter, &end_iter);
gtk_text_iter_forward_lines (&start_iter, 6);
gtk_text_iter_backward_lines (&end_iter, 6);
gtk_text_buffer_delete(buffer, &start_iter, &end_iter);
}
gboolean status_loop (gboolean foo) {
char status[3];
static int alarm_id = 0;
/** This checks if the status of the transmission if ON or OFF, using the shared area **/
sscanf((char *) shared_area, "%s", status);
/* if the update label flag is on */
if (status[1] == '1') {
/** streaming stopped **/
if (status [0] == '0') {
gtk_label_set_text(GTK_LABEL (label_status), gettext("Streaming Status: Stopped"));
text_box_loop(1);
if (alarm_id)
g_source_remove(alarm_id);
}
/** streaming started **/
else {
gtk_label_set_text(GTK_LABEL (label_status), gettext("Streaming Status: Started"));
text_box_loop(0);
alarm_id = g_timeout_add (4000, (GSourceFunc) text_box_loop, 0);
}
strncpy((char *) shared_area+1, "0", 1);
}
/* I need nothing from child, just do this to prevent <defunct> processes */
waitpid(pid, NULL, WNOHANG);
return TRUE;
}
#define BUFFER_SIZE 16384
gboolean text_box_loop (int option) {
char dark_output[BUFFER_SIZE];
char status[3];
int i;
static int bytes_written = 0;
sscanf((char *) shared_area, "%s", status);
if (status[0] == '1' || option == 1) {
while ( (i = read (darkice_fd, dark_output, BUFFER_SIZE - 1)) && i > 0 ) {
dark_output[i] = 0;
gtk_text_buffer_insert_at_cursor (buffer, dark_output, strlen(dark_output));
bytes_written = bytes_written + i;
/* 32 * BUFFER_SIZE = */
if (bytes_written > 524288){
clean_text_view_memory();
bytes_written = 0;
}
}
}
return TRUE;
}
/* callback que chama a funcao de saida do programa, eh issu mermo, mata tudo mermaum!! */
gboolean delete_event(GtkWidget *widget, GdkEvent *event, gpointer data) {
system("killall darkice &> /dev/null");
gtk_main_quit ();
return FALSE;
}
/* callback that exit without killing darkice */
gboolean delete_event_nd (GtkWidget *widget, GdkEvent *event, gpointer data) {
char foo;
sscanf((char *) shared_area, "%c", &foo);
if (foo == '1')
kill(pid,SIGTERM);
gtk_main_quit ();
return FALSE;
}
gboolean main_quit (GtkWidget *widget, GdkEvent *event, gpointer data) {
char status = '0';
sscanf ((char *) shared_area, "%c", &status);
/* if darkice is running, ask for killing it */
if (status == '1') {
gtk_widget_show (button_yes_darkkill);
gtk_widget_show (button_no_darkkill);
gtk_widget_show (label_darkkill);
gtk_widget_show (dialog_darkkill);
}
else
delete_event_nd(NULL, NULL, NULL);
return FALSE;
}
/* function that is called when darkice is not found */
void darkice_not_found() {
char bar[192];
/* sets up the darkice not found dialog */
if (!FUN)
sprintf(bar, gettext("Darkice not found!\nDownload darkice at http://darkice.sf.net/"));
else
sprintf(bar, gettext("Don't you know you should have the fucking\ndarkice to run this shit!!\nGet it at http://darkice.sf.net/\n"));
dialog_darkdep = gtk_dialog_new ();
label_darkdep = gtk_label_new ( bar );
button_darkdep = gtk_button_new_with_label ( gettext("Close"));
gtk_window_set_title(GTK_WINDOW (dialog_darkdep), gettext("Error"));
gtk_widget_set_size_request (GTK_WIDGET (dialog_darkdep), 350, 200);
gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog_darkdep)->action_area), button_darkdep, TRUE, TRUE, 0);
gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog_darkdep)->vbox), label_darkdep, TRUE, TRUE, 0);
g_signal_connect (G_OBJECT (dialog_darkdep), "delete_event",G_CALLBACK (delete_event), NULL);
g_signal_connect (G_OBJECT (button_darkdep), "clicked",G_CALLBACK (delete_event), NULL);
gtk_widget_show (button_darkdep);
gtk_widget_show (label_darkdep);
gtk_widget_show (dialog_darkdep);
gtk_main ();
}
void dark_detail (GtkWidget *widget, gpointer data) {
if (show_detail) {
show_detail = 0;
gtk_button_set_label (GTK_BUTTON(button_detail), gettext("Show Details"));
gtk_widget_hide (scroll_text);
gtk_widget_hide (text);
gtk_window_resize (GTK_WINDOW(window), SIZE_X, SIZE_Y);
}
else{
show_detail = 1;
gtk_button_set_label (GTK_BUTTON(button_detail), gettext("Hide Details"));
gtk_widget_show (text);
gtk_widget_show (scroll_text);
gtk_window_resize (GTK_WINDOW(window), SIZE_X, SIZE_Y+110);
}
}