1 |
/* |
2 |
* callbacks.c Copyright © 2009 by Benoît Rouits <brouits@free.fr> |
3 |
* Published under the terms of the GNU General Public License v2 (GPLv2). |
4 |
* |
5 |
* This program is free software; you can redistribute it and/or |
6 |
* modify it under the terms of the GNU General Public License |
7 |
* as published by the Free Software Foundation; either version 2 |
8 |
* of the License, or (at your option) any later version. |
9 |
* |
10 |
* This program is distributed in the hope that it will be useful, |
11 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
12 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
13 |
* GNU General Public License for more details. |
14 |
* |
15 |
* You should have received a copy of the GNU General Public License |
16 |
* along with this program; if not, write to the Free Software |
17 |
* Foundation, Inc., 51 Franklin Street, Fifth Floor, |
18 |
* Boston, MA 02110-1301, USA. |
19 |
* |
20 |
* see the COPYING file included in the jackie package or |
21 |
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt for the full licence |
22 |
* |
23 |
*/ |
24 |
|
25 |
#include <unistd.h> |
26 |
#include <gtk/gtk.h> |
27 |
#include <fluidsynth.h> |
28 |
#include <libintl.h> |
29 |
#include <locale.h> |
30 |
#include "utils.h" |
31 |
#include "type.h" |
32 |
#include "menu.h" |
33 |
#include "about.h" |
34 |
#include "version.h" |
35 |
#define _(string) gettext (string) |
36 |
|
37 |
/* handler for the volume button drag */ |
38 |
void volume_on_event (GtkWidget* instance, gdouble value, gpointer app_data) { |
39 |
AppData* d = (AppData*) app_data; |
40 |
fluid_synth_set_gain(d->synth,value*10.0); |
41 |
instance = NULL; |
42 |
app_data = NULL; |
43 |
} |
44 |
|
45 |
/* handler for left-button click */ |
46 |
void status_icon_on_left_click(GtkStatusIcon* instance, gpointer app_data) { |
47 |
AppData* d = (AppData*) app_data; |
48 |
GtkVolumeButton* volume; |
49 |
GtkWidget* popup; |
50 |
double curvol; |
51 |
|
52 |
if (!d->synth) /* fluidsynth not started */ |
53 |
return; |
54 |
volume = GTK_VOLUME_BUTTON(gtk_volume_button_new()); |
55 |
curvol = (fluid_synth_get_gain(d->synth)/10.0); |
56 |
gtk_scale_button_set_value(GTK_SCALE_BUTTON(volume), curvol/10.0); |
57 |
popup = gtk_scale_button_get_popup(GTK_SCALE_BUTTON(volume)); |
58 |
gtk_window_set_position(GTK_WINDOW(popup), GTK_WIN_POS_MOUSE); |
59 |
g_signal_connect(G_OBJECT(volume), "value-changed", G_CALLBACK(volume_on_event), app_data); |
60 |
g_signal_connect_swapped(popup, "leave-notify-event", G_CALLBACK(gtk_widget_destroy), popup); |
61 |
gtk_widget_show_all(popup); |
62 |
instance = app_data = NULL; |
63 |
} |
64 |
|
65 |
/* handler for right-button click */ |
66 |
void status_icon_on_right_click(GtkStatusIcon* instance, guint button, guint activate_time, gpointer app_data) { |
67 |
AppData* d = (AppData*) app_data; |
68 |
|
69 |
if (app_data) |
70 |
menu_show (GTK_MENU(d->right_menu), button, activate_time); |
71 |
instance = NULL; |
72 |
} |
73 |
|
74 |
int midi_ev_cb (void *data, fluid_midi_event_t *event) { |
75 |
/* printf("event type: %d\n", fluid_midi_event_get_type(event)); */ |
76 |
/* FIXME print something on tooltip ? */ |
77 |
data = NULL; |
78 |
event = NULL; |
79 |
return 0; |
80 |
} |
81 |
|
82 |
/* handler for the "Play" menu item */ |
83 |
void menu_item_on_startstop(GtkMenuItem* instance, gpointer app_data) { |
84 |
AppData* d = (AppData*) app_data; |
85 |
gchar* temp; |
86 |
guint id; |
87 |
|
88 |
if (!d->synth) { /* is stopped : start it */ |
89 |
id = getpid(); |
90 |
d->settings = new_fluid_settings(); |
91 |
fluid_settings_setstr(d->settings, "audio.driver", d->audio); |
92 |
temp = g_strdup_printf("gluid_audio_%d", id); |
93 |
fluid_settings_setstr(d->settings, "audio.jack.id", temp); |
94 |
g_free(temp); |
95 |
fluid_settings_setstr(d->settings, "midi.driver", d->midi); |
96 |
temp = g_strdup_printf("gluid_midi_%d", id); |
97 |
fluid_settings_setstr(d->settings, "midi.alsa_seq.id", temp); |
98 |
fluid_settings_setstr(d->settings, "midi.jack.id", temp); |
99 |
g_free(temp); |
100 |
fluid_settings_setstr(d->settings, "synth.reverb.active", d->reverb); |
101 |
fluid_settings_setstr(d->settings, "synth.chorus.active", d->chorus); |
102 |
|
103 |
d->synth = new_fluid_synth(d->settings); |
104 |
|
105 |
if (fluid_is_soundfont(d->sfpath)) { |
106 |
fluid_synth_sfload(d->synth, d->sfpath, 1); |
107 |
} else { |
108 |
gtk_status_icon_set_tooltip(d->status_icon, _("no sound font found")); |
109 |
goto stop; |
110 |
} |
111 |
|
112 |
d->adriver = new_fluid_audio_driver(d->settings, d->synth); |
113 |
if (!d->adriver) /* backend already used */ |
114 |
goto stop; |
115 |
|
116 |
d->router = new_fluid_midi_router(d->settings, fluid_synth_handle_midi_event, (void*)d->synth); |
117 |
fluid_synth_set_midi_router(d->synth, d->router); |
118 |
if (!d->router) |
119 |
goto stop; |
120 |
|
121 |
d->mdriver = new_fluid_midi_driver(d->settings, fluid_midi_router_handle_midi_event, (void*)d->router); |
122 |
if (!d->mdriver) /* backend already used */ |
123 |
goto stop; |
124 |
temp = g_strdup_printf (_("fluidsynth %d running"), id); |
125 |
gtk_status_icon_set_tooltip(d->status_icon, temp); |
126 |
gtk_menu_item_set_label(instance, _("Stop")); |
127 |
} else { /* is started : stop it*/ |
128 |
stop: |
129 |
if (d->mdriver) |
130 |
delete_fluid_midi_driver(d->mdriver); |
131 |
d->mdriver = NULL; |
132 |
if (d->router) |
133 |
delete_fluid_midi_router(d->router); |
134 |
d->router = NULL; |
135 |
if (d->adriver) |
136 |
delete_fluid_audio_driver(d->adriver); |
137 |
d->adriver = NULL; |
138 |
if (d->synth) |
139 |
delete_fluid_synth(d->synth); |
140 |
d->synth = NULL; |
141 |
if (d->settings) |
142 |
delete_fluid_settings(d->settings); |
143 |
d->settings = NULL; |
144 |
|
145 |
gtk_status_icon_set_tooltip(d->status_icon, _("fluidsynth stopped")); |
146 |
gtk_menu_item_set_label(instance, _("Start")); |
147 |
} |
148 |
} |
149 |
|
150 |
/* handler for the "About" menu item (see version.h) */ |
151 |
void menu_item_on_about(GtkMenuItem* instance, gpointer unused) { |
152 |
GtkAboutDialog* about; |
153 |
const gchar* authors [] = { |
154 |
PROG_AUTHOR0, |
155 |
NULL |
156 |
}; |
157 |
|
158 |
about = about_create (PROG_NAME, PROG_VERSION, PROG_COPYRIGHT, |
159 |
PROG_COMMENT, PROG_LICENSE, PROG_WEBSITE, |
160 |
authors); |
161 |
about_show (about); |
162 |
unused = NULL; /* avoid compiler warnings */ |
163 |
instance = NULL; /* _ */ |
164 |
return; |
165 |
} |
166 |
|
167 |
/* callback on Preferences window closed */ |
168 |
void pref_window_on_close (gpointer app_data) { |
169 |
AppData* d = (AppData*) app_data; |
170 |
|
171 |
g_free(d->sfpath); |
172 |
d->sfpath = g_strdup (gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(d->sfpath_chooser))); |
173 |
g_free(d->audio); |
174 |
d->audio = g_strdup (gtk_combo_box_get_active_text(d->audio_combo)); |
175 |
g_free(d->midi); |
176 |
d->midi = g_strdup (gtk_combo_box_get_active_text(d->midi_combo)); |
177 |
g_free(d->reverb); |
178 |
d->reverb = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(d->reverb_btn))? g_strdup ("yes"): g_strdup("no"); |
179 |
g_free(d->chorus); |
180 |
d->chorus = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(d->chorus_btn))? g_strdup ("yes"): g_strdup("no"); |
181 |
|
182 |
/* write it to $HOME/.gluid */ |
183 |
write_config (d); |
184 |
gtk_widget_hide (GTK_WIDGET(d->pref_window)); |
185 |
gtk_widget_destroy (GTK_WIDGET(d->pref_window)); |
186 |
gtk_widget_set_sensitive (GTK_WIDGET(d->pref_item), TRUE); |
187 |
d->pref_window = NULL; |
188 |
} |
189 |
|
190 |
/* handler for the "Preference" menu item */ |
191 |
void menu_item_on_pref(GtkMenuItem* instance, gpointer app_data) { |
192 |
AppData* d = (AppData*) app_data; |
193 |
GtkVBox* vbox; |
194 |
GtkHBox* hbox1; |
195 |
GtkHBox* hbox2; |
196 |
GtkHBox* hbox3; |
197 |
GtkHBox* hbox4; |
198 |
GtkHBox* hbox5; |
199 |
GtkLabel* label1; |
200 |
GtkLabel* label2; |
201 |
GtkLabel* label3; |
202 |
GtkLabel* label0; |
203 |
GtkButton* button1; |
204 |
|
205 |
d->pref_window = GTK_WINDOW(gtk_window_new (GTK_WINDOW_TOPLEVEL)); |
206 |
gtk_window_set_title (GTK_WINDOW(d->pref_window), _("Preferences")); |
207 |
gtk_window_set_default_size (GTK_WINDOW(d->pref_window), 300, 200); |
208 |
gtk_window_set_resizable (GTK_WINDOW(d->pref_window), TRUE); |
209 |
|
210 |
vbox = GTK_VBOX(gtk_vbox_new (TRUE, 0)); |
211 |
gtk_container_add (GTK_CONTAINER(d->pref_window), GTK_WIDGET(vbox)); |
212 |
|
213 |
hbox1 = GTK_HBOX(gtk_hbox_new (TRUE, 0)); |
214 |
gtk_box_pack_start (GTK_BOX(vbox), GTK_WIDGET(hbox1), TRUE, FALSE, 10); |
215 |
|
216 |
hbox2 = GTK_HBOX(gtk_hbox_new (TRUE, 0)); |
217 |
gtk_box_pack_start (GTK_BOX(vbox), GTK_WIDGET(hbox2), TRUE, FALSE, 10); |
218 |
|
219 |
hbox3 = GTK_HBOX(gtk_hbox_new (TRUE, 0)); |
220 |
gtk_box_pack_start (GTK_BOX(vbox), GTK_WIDGET(hbox3), TRUE, FALSE, 10); |
221 |
|
222 |
hbox4 = GTK_HBOX(gtk_hbox_new (TRUE, 0)); |
223 |
gtk_box_pack_start (GTK_BOX(vbox), GTK_WIDGET(hbox4), TRUE, FALSE, 10); |
224 |
|
225 |
hbox5 = GTK_HBOX(gtk_hbox_new (TRUE, 0)); |
226 |
gtk_box_pack_start (GTK_BOX(vbox), GTK_WIDGET(hbox5), TRUE, FALSE, 10); |
227 |
|
228 |
label1= GTK_LABEL(gtk_label_new (_("Soundfont Path:"))); |
229 |
gtk_box_pack_start (GTK_BOX(hbox1), GTK_WIDGET(label1), TRUE, FALSE, 10); |
230 |
d->sfpath_chooser = GTK_FILE_CHOOSER_BUTTON(gtk_file_chooser_button_new(_("Choose SF2 file"), GTK_FILE_CHOOSER_ACTION_OPEN)); |
231 |
gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(d->sfpath_chooser), d->sfpath); |
232 |
gtk_box_pack_start(GTK_BOX(hbox1), GTK_WIDGET(d->sfpath_chooser), TRUE, TRUE, 10); |
233 |
label2 = GTK_LABEL(gtk_label_new (_("Audio Driver:"))); |
234 |
gtk_box_pack_start (GTK_BOX(hbox2), GTK_WIDGET(label2), TRUE, FALSE, 10); |
235 |
d->audio_combo = GTK_COMBO_BOX(gtk_combo_box_new_text ()); |
236 |
gtk_combo_box_append_text (d->audio_combo, d->audio); |
237 |
gtk_combo_box_append_text (d->audio_combo, "alsa"); |
238 |
gtk_combo_box_append_text (d->audio_combo, "jack"); |
239 |
gtk_combo_box_append_text (d->audio_combo, "oss"); |
240 |
gtk_combo_box_append_text (d->audio_combo, "file"); |
241 |
gtk_combo_box_set_active(d->audio_combo, 0); |
242 |
gtk_box_pack_start(GTK_BOX(hbox2), GTK_WIDGET(d->audio_combo), TRUE, FALSE, 10); |
243 |
|
244 |
label3 = GTK_LABEL(gtk_label_new (_("Midi Driver:"))); |
245 |
gtk_box_pack_start (GTK_BOX(hbox3), GTK_WIDGET(label3), TRUE, FALSE, 10); |
246 |
d->midi_combo = GTK_COMBO_BOX(gtk_combo_box_new_text ()); |
247 |
gtk_combo_box_append_text (d->midi_combo, d->midi); |
248 |
gtk_combo_box_append_text (d->midi_combo, "alsa_raw"); |
249 |
gtk_combo_box_append_text (d->midi_combo, "alsa_seq"); |
250 |
gtk_combo_box_append_text (d->midi_combo, "jack"); |
251 |
gtk_combo_box_append_text (d->midi_combo, "oss"); |
252 |
gtk_combo_box_set_active(d->midi_combo, 0); |
253 |
gtk_box_pack_start(GTK_BOX(hbox3), GTK_WIDGET(d->midi_combo), TRUE, FALSE, 10); |
254 |
|
255 |
d->reverb_btn = gtk_check_button_new_with_label (_("Reverb")); |
256 |
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(d->reverb_btn), (gboolean)!g_strcmp0(d->reverb,"yes")); |
257 |
gtk_box_pack_start (GTK_BOX(hbox4), GTK_WIDGET(d->reverb_btn), TRUE, FALSE, 10); |
258 |
|
259 |
d->chorus_btn = gtk_check_button_new_with_label (_("Chorus")); |
260 |
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(d->chorus_btn), (gboolean)!g_strcmp0(d->chorus,"yes")); |
261 |
gtk_box_pack_start (GTK_BOX(hbox4), GTK_WIDGET(d->chorus_btn), TRUE, FALSE, 10); |
262 |
|
263 |
label0 = GTK_LABEL(gtk_label_new ("")); |
264 |
gtk_box_pack_start (GTK_BOX(hbox5), GTK_WIDGET(label0), TRUE, FALSE, 10); |
265 |
|
266 |
button1 = GTK_BUTTON(gtk_button_new_from_stock (GTK_STOCK_CLOSE)); |
267 |
gtk_box_pack_start (GTK_BOX(hbox5), GTK_WIDGET(button1), FALSE, FALSE, 10); |
268 |
|
269 |
g_signal_connect_swapped (G_OBJECT(button1), "clicked", G_CALLBACK(pref_window_on_close), (gpointer)d); |
270 |
g_signal_connect_swapped (G_OBJECT(d->pref_window), "delete-event", G_CALLBACK(pref_window_on_close), (gpointer)d); |
271 |
|
272 |
gtk_widget_show_all (GTK_WIDGET(d->pref_window)); |
273 |
gtk_widget_set_sensitive (GTK_WIDGET(instance), FALSE); |
274 |
} |
275 |
|
276 |
/* handler for the "Quit" menu item */ |
277 |
void menu_item_on_quit(GtkMenuItem* instance, gpointer app_data) { |
278 |
AppData* d = (AppData*) app_data; |
279 |
quit (d); |
280 |
instance = NULL; /* useless but does not warn at compile time */ |
281 |
} |
282 |
|