/* A Gui in gtk+ for MuSE - Multiple Streaming Engine * Copyright (C) 2002-2004 nightolo * * 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 #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include GtkWidget *createbbox(GtkWidget *bbox) { GtkWidget *ice, *clame, *addch, *help, *vumeters, *scheduler; GtkWidget *tmpwid; ice = clame = addch = help = vumeters = NULL; bbox=gtk_hbutton_box_new(); gtk_button_box_set_child_size(GTK_BUTTON_BOX(bbox), 7, 10); gtk_hbutton_box_set_spacing_default(0); gtk_hbutton_box_set_layout_default(GTK_BUTTONBOX_START); ice = createpixmap(window, ice, stream_xpm, _("Let's stream!"), FALSE); g_signal_connect(G_OBJECT(ice), "clicked", G_CALLBACK(ice_window), NULL); gtk_container_add(GTK_CONTAINER(bbox), ice); addch = createpixmap(window, addch, newch_xpm, _("Add Channel"), FALSE); g_signal_connect_swapped(G_OBJECT(addch), "clicked", G_CALLBACK(createch), NULL); gtk_container_add(GTK_CONTAINER(bbox), addch); /* il talk sarebbe da mettere solo come hotkey mic = createpixmap(window, mic, stock_mic_xpm, _("Talk"), TRUE); g_signal_connect(G_OBJECT(mic), "clicked", G_CALLBACK(gcb_set_talk), NULL); gtk_container_add(GTK_CONTAINER(bbox), mic); */ linein = createpixmap(window, linein, mic_xpm, _("Line In"), TRUE); g_signal_connect(G_OBJECT(linein), "clicked", G_CALLBACK(gcb_set_linein), NULL); gtk_container_add(GTK_CONTAINER(bbox), linein); speakout = createpixmap(window, speakout, speaker_xpm, _("Speaker"), TRUE); g_signal_connect(G_OBJECT(speakout), "clicked", G_CALLBACK(gcb_set_speakout), NULL); gtk_container_add(GTK_CONTAINER(bbox), speakout); vumeters = createpixmap(window, vumeters, vu_xpm, _("Vumeters"), FALSE); g_signal_connect(G_OBJECT(vumeters), "clicked", G_CALLBACK(vumeters_new), NULL); gtk_container_add(GTK_CONTAINER(bbox), vumeters); #ifdef HAVE_SCHEDULER tmpwid = gtk_image_new_from_stock(GTK_STOCK_INDEX, GTK_ICON_SIZE_BUTTON); scheduler = gtk_button_new(); gtk_container_add(GTK_CONTAINER(scheduler), tmpwid); set_tip(scheduler, "Radio Scheduler"); g_signal_connect(G_OBJECT(scheduler), "clicked", G_CALLBACK(rsched_new), NULL); gtk_container_add(GTK_CONTAINER(bbox), scheduler); #endif help = createpixmap(window, help, about_xpm, _("Hall of Fame"), FALSE); g_signal_connect(G_OBJECT(help), "clicked", G_CALLBACK(about_win), NULL); gtk_container_add(GTK_CONTAINER(bbox), help); return bbox; } void createtab(GtkWidget **tab) { *tab=gtk_table_new(3, 2, FALSE); gtk_table_set_row_spacings(GTK_TABLE(*tab), 5); gtk_table_set_col_spacings(GTK_TABLE(*tab), 5); /* gtk_container_add(GTK_CONTAINER(vbox), *tab); */ } void pack_new(void) { GtkWidget *tmpbox; pack1.id = 1; pack1.hbox = gtk_hbox_new(FALSE, 0); pack1.adj = gtk_adjustment_new(0.0, 0.0, 1.0, 0.01, 0.01, 0.0); tmpbox = gtk_hbox_new(FALSE, 0); pack1.hscale = gtk_hscale_new(GTK_ADJUSTMENT(pack1.adj)); g_signal_connect(G_OBJECT(pack1.adj), "value_changed", G_CALLBACK(cfade_set), (void *) &pack1); gtk_scale_set_digits(GTK_SCALE(pack1.hscale), 2); gtk_box_pack_start(GTK_BOX(tmpbox), pack1.hscale, TRUE, TRUE, 0); gtk_box_pack_start(GTK_BOX(vbox), pack1.hbox, TRUE, TRUE, 0); gtk_box_pack_start(GTK_BOX(vbox), tmpbox, FALSE, FALSE, 0); pack2.id = 3; pack2.hbox = gtk_hbox_new(FALSE, 0); pack2.adj = gtk_adjustment_new(0.0, 0.0, 1.0, 0.01, 0.01, 0.0); pack2.hscale = gtk_hscale_new(GTK_ADJUSTMENT(pack2.adj)); tmpbox = gtk_hbox_new(FALSE, 0); g_signal_connect(G_OBJECT(pack2.adj), "value_changed", G_CALLBACK(cfade_set), (void *) &pack2); gtk_scale_set_digits(GTK_SCALE(pack2.hscale), 2); gtk_box_pack_start(GTK_BOX(tmpbox), pack2.hscale, TRUE, TRUE, 0); gtk_box_pack_start(GTK_BOX(vbox), pack2.hbox, TRUE, TRUE, 0); gtk_box_pack_start(GTK_BOX(vbox), tmpbox, FALSE, FALSE, 0); pack3.id = 6; pack3.hbox = gtk_hbox_new(FALSE, 0); pack3.adj = gtk_adjustment_new(0.0, 0.0, 1.0, 0.01, 0.01, 0.0); pack3.hscale = gtk_hscale_new(GTK_ADJUSTMENT(pack3.adj)); tmpbox = gtk_hbox_new(FALSE, 0); g_signal_connect(G_OBJECT(pack3.adj), "value_changed", G_CALLBACK(cfade_set), (void *) &pack3); gtk_scale_set_digits(GTK_SCALE(pack3.hscale), 2); gtk_box_pack_start(GTK_BOX(tmpbox), pack3.hscale, TRUE, TRUE, 0); gtk_box_pack_start(GTK_BOX(vbox), pack3.hbox, TRUE, TRUE, 0); gtk_box_pack_start(GTK_BOX(vbox), tmpbox, FALSE, FALSE, 0); } void cfade_set(GtkWidget *w, struct pack *p) { struct gchan *tmp1, *tmp2; float value; gchar tmp[4]; // func(_("cfade_set get data for pos %u"), p->id); tmp1 = (struct gchan *) list_get_data(listachan, 0, p->id); tmp2 = (struct gchan *) list_get_data(listachan, 0, p->id+1); value = GTK_ADJUSTMENT(p->adj)->value; mixer->crossfade(tmp1->idx-1, 1.0-value, tmp2->idx-1, value); g_signal_handler_block(G_OBJECT(tmp1->adjvol), tmp1->volid); g_signal_handler_block(G_OBJECT(tmp2->adjvol), tmp2->volid); gtk_adjustment_set_value(GTK_ADJUSTMENT(tmp1->adjvol), value); snprintf(tmp, sizeof(tmp), "%d", (int) ((1.0-GTK_ADJUSTMENT(tmp1->adjvol)->value)*100)); gtk_label_set_text(GTK_LABEL(tmp1->vol_lab), (gchar *) tmp); gtk_adjustment_set_value(GTK_ADJUSTMENT(tmp2->adjvol), 1.0-value); snprintf(tmp, sizeof(tmp), "%d", (int) ((1.0-GTK_ADJUSTMENT(tmp2->adjvol)->value)*100)); gtk_label_set_text(GTK_LABEL(tmp2->vol_lab), (gchar *) tmp); g_signal_handler_unblock(G_OBJECT(tmp1->adjvol), tmp1->volid); g_signal_handler_unblock(G_OBJECT(tmp2->adjvol), tmp2->volid); } void putstatusbar(void) { statusbar = gtk_statusbar_new(); contextid = gtk_statusbar_get_context_id(GTK_STATUSBAR(statusbar), _("_The_ status bar")); /* g_signal_connect(GTK_OBJECT(statusbar), "button_press_event", (GtkSignalFunc) status_window, NULL);*/ gtk_box_pack_start(GTK_BOX(vbox), statusbar, FALSE, FALSE, 0); } GtkWidget *createpixmap(GtkWidget *w, GtkWidget *but, gchar **pippo, gchar *tip, bool istoggled) { /* create and return button with pixmap */ GtkWidget *image; GtkTooltips *tooltip; GdkPixmap *pixmap; GdkBitmap *mask; GtkStyle *style; style=gtk_widget_get_style(w); gtk_widget_realize(w); pixmap=gdk_pixmap_create_from_xpm_d(w->window, &mask, &style->bg[GTK_STATE_NORMAL], pippo); image = gtk_image_new_from_pixmap(pixmap, mask); if(!istoggled) but=gtk_button_new(); else but=gtk_toggle_button_new(); gtk_container_add(GTK_CONTAINER(but), image); tooltip = gtk_tooltips_new(); gtk_tooltips_set_tip(GTK_TOOLTIPS(tooltip), but, tip, NULL); return but; } void win_error(gchar *text) { GtkWidget *dialog; dialog = gtk_message_dialog_new(NULL, GTK_DIALOG_MODAL, GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE, text); gtk_dialog_run(GTK_DIALOG(dialog)); gtk_widget_destroy(dialog); } void win_warning(gchar *text) { GtkWidget *dialog; dialog = gtk_message_dialog_new(NULL, GTK_DIALOG_MODAL, GTK_MESSAGE_WARNING, GTK_BUTTONS_CLOSE, text); gtk_dialog_run(GTK_DIALOG(dialog)); gtk_widget_destroy(dialog); } void win_profile_save(GtkWidget *item, void *i) { GtkWidget *winsave, *hbox, *tmpwid, *vbox1; gchar title[30]; bool encoder = true; gchar *tmp; gint result; tmp = (gchar *) g_object_get_data(G_OBJECT(item), "type"); if(tmp[0] == 'i') { encoder = false; strncpy(title, _("Save an Icecast profile"), sizeof(title)); } else if(tmp[0] == 'l') strncpy(title, _("Save a Lame profile"), sizeof(title)); else if(tmp[0] == 'o') strncpy(title, _("Save an Ogg/Vorbis profile"), sizeof(title)); winsave = gtk_dialog_new_with_buttons(title, NULL, /* parent window */ GTK_DIALOG_MODAL, GTK_STOCK_OK, GTK_RESPONSE_ACCEPT, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, NULL); gtk_container_set_border_width(GTK_CONTAINER(winsave), 12); hbox = gtk_hbox_new(FALSE, 6); gtk_container_add(GTK_CONTAINER(GTK_DIALOG(winsave)->vbox), hbox); tmpwid = gtk_image_new_from_stock(GTK_STOCK_DIALOG_QUESTION, GTK_ICON_SIZE_DIALOG); gtk_box_pack_start(GTK_BOX(hbox), tmpwid, FALSE, FALSE, 6); vbox1 = gtk_vbox_new(FALSE, 6); gtk_box_pack_start(GTK_BOX(hbox), vbox1, FALSE, FALSE, 6); tmpwid = gtk_label_new(_("Profile Name")); gtk_box_pack_start(GTK_BOX(vbox1), tmpwid, FALSE, FALSE, 6); /* FIXME: insert a gtk combo here */ profentry = gtk_entry_new(); gtk_box_pack_start(GTK_BOX(vbox1), profentry, FALSE, FALSE, 6); gtk_widget_show_all(winsave); result = gtk_dialog_run(GTK_DIALOG(winsave)); switch(result) { case GTK_RESPONSE_ACCEPT: if(encoder) gcb_enc_save((struct encdata *) i); else gcb_ice_save((struct icedata *) i); break; case GTK_RESPONSE_CANCEL: break; } gtk_widget_destroy(winsave); } void win_profile_remove(GtkWidget *item, void *i) { GtkWidget *winsave, *hbox, *tmpwid, *vbox1; gchar title[30]; bool encoder = true; gchar *tmp; gint result; tmp = (gchar *) g_object_get_data(G_OBJECT(item), "type"); if(tmp[0] == 'i') { encoder = false; strncpy(title, _("Remove an Icecast profile"), sizeof(title)); } else if(tmp[0] == 'l') strncpy(title, _("Remove a Lame profile"), sizeof(title)); else if(tmp[0] == 'o') strncpy(title, _("Remove a Ogg/Vorbis profile"), sizeof(title)); winsave = gtk_dialog_new_with_buttons(title, NULL, /* parent window */ GTK_DIALOG_MODAL, GTK_STOCK_OK, GTK_RESPONSE_ACCEPT, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, NULL); gtk_container_set_border_width(GTK_CONTAINER(winsave), 12); hbox = gtk_hbox_new(FALSE, 6); gtk_container_add(GTK_CONTAINER(GTK_DIALOG(winsave)->vbox), hbox); tmpwid = gtk_image_new_from_stock(GTK_STOCK_DIALOG_QUESTION, GTK_ICON_SIZE_DIALOG); gtk_box_pack_start(GTK_BOX(hbox), tmpwid, FALSE, FALSE, 6); vbox1 = gtk_vbox_new(FALSE, 6); gtk_box_pack_start(GTK_BOX(hbox), vbox1, FALSE, FALSE, 6); tmpwid = gtk_label_new(_("Profile Name")); gtk_box_pack_start(GTK_BOX(vbox1), tmpwid, FALSE, FALSE, 6); /* FIXME: insert a gtkcombo here */ /* profentry = gtk_entry_new(); gtk_box_pack_start(GTK_BOX(vbox1), profentry, FALSE, FALSE, 6); */ gtk_widget_show_all(winsave); result = gtk_dialog_run(GTK_DIALOG(winsave)); switch(result) { case GTK_RESPONSE_ACCEPT: /*if(encoder) gcb_enc_save((struct encdata *) i); else gcb_ice_save((struct icedata *) i); break;*/ case GTK_RESPONSE_CANCEL: break; } gtk_widget_destroy(winsave); } void set_tip(GtkWidget *w, gchar *tip) { GtkTooltips *tooltip; tooltip = gtk_tooltips_new(); gtk_tooltips_set_tip(GTK_TOOLTIPS(tooltip), w, tip, NULL); } void gcb_set_speakout(GtkWidget *w) { bool res = false; if(GTK_TOGGLE_BUTTON(w)->active) res = mixer->set_lineout(true); else mixer->set_lineout(false); if(!res) gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(w), FALSE); } void gcb_set_linein(GtkWidget *w) { bool res = false; if(GTK_TOGGLE_BUTTON(w)->active) res = mixer->set_live(true); else mixer->set_live(false); if(!res) gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(w), FALSE); } void gcb_set_talk(GtkWidget *w) { unsigned int i; float voltmp[MAX_CHANNELS]; struct gchan *c = NULL; if(GTK_TOGGLE_BUTTON(w)->active) { for(i = 0; i < MAX_CHANNELS; i++) { c = (struct gchan *) list_get_data(listachan, i+1, 0); if(c) { storevol[i]= GTK_ADJUSTMENT(c->adjvol)->value; if(storevol[i] < TALK_VOLUME) voltmp[i]=0.0; else voltmp[i]= TALK_VOLUME; gtk_adjustment_set_value(GTK_ADJUSTMENT(c->adjvol), voltmp[i]); } } mixer->set_all_volumes(&voltmp[0]); } else { for(i = 0; i < MAX_CHANNELS; i++) { c = (struct gchan *) list_get_data(listachan, i+1, 0); if(c) gtk_adjustment_set_value(GTK_ADJUSTMENT(c->adjvol), storevol[i]); } mixer->set_all_volumes(&storevol[0]); } } void gcb_exit(GtkWidget *w, GdkEvent *s) { state=false; //leave time for threads to stop, otherwise SIGSEGV might sometimes jsleep(1,0); }