Mercurial > audlegacy
annotate audacious/input.c @ 1938:1d9c1026d9f8 trunk
[svn] - DoubleSize support.
This has bugs, the most notable one being that DoubleSize only works
right if you restart the player.
The second bug is rather obvious too. No osmosis skinengine. No
TinyPlayer. Classic-esque skinengine only. This is because the
doublesize algorithm hates you and wants you to go die in a fire.
author | nenolod |
---|---|
date | Sun, 05 Nov 2006 04:43:16 -0800 |
parents | c186ee9524ed |
children | c2a63f41d8c6 |
rev | line source |
---|---|
0 | 1 /* BMP - Cross-platform multimedia player |
2 * Copyright (C) 2003-2004 BMP development team. | |
3 * | |
4 * Based on XMMS: | |
5 * Copyright (C) 1998-2003 XMMS development team. | |
6 * | |
7 * This program is free software; you can redistribute it and/or modify | |
8 * it under the terms of the GNU General Public License as published by | |
9 * the Free Software Foundation; either version 2 of the License, or | |
10 * (at your option) any later version. | |
11 * | |
12 * This program is distributed in the hope that it will be useful, | |
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
15 * GNU General Public License for more details. | |
16 * | |
17 * You should have received a copy of the GNU General Public License | |
18 * along with this program; if not, write to the Free Software | |
1459 | 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
0 | 20 */ |
21 | |
22 #ifdef HAVE_CONFIG_H | |
23 # include "config.h" | |
24 #endif | |
25 | |
26 #include <glib.h> | |
27 #include <glib/gi18n.h> | |
28 #include <gtk/gtk.h> | |
29 #include <string.h> | |
30 | |
31 #include "fft.h" | |
32 #include "input.h" | |
33 #include "main.h" | |
1653 | 34 #include "mainwin.h" |
0 | 35 #include "output.h" |
36 #include "util.h" | |
37 #include "visualization.h" | |
538
e4e897d20791
[svn] remove libaudcore, we never did anything with it
nenolod
parents:
355
diff
changeset
|
38 #include "playback.h" |
1653 | 39 #include "widgets/widgetcore.h" |
0 | 40 #include "pluginenum.h" |
1755 | 41 #include "titlestring.h" |
0 | 42 |
43 #include "libaudacious/util.h" | |
44 #include "libaudacious/xentry.h" | |
45 | |
46 G_LOCK_DEFINE_STATIC(vis_mutex); | |
47 | |
48 struct _VisNode { | |
49 gint time; | |
50 gint nch; | |
51 gint length; /* number of samples per channel */ | |
52 gint16 data[2][512]; | |
53 }; | |
54 | |
55 typedef struct _VisNode VisNode; | |
56 | |
57 | |
58 InputPluginData ip_data = { | |
59 NULL, | |
60 NULL, | |
61 FALSE, | |
625
0a73d1faeb4e
[svn] GCC 4.1 warning fixes by Diego 'Flameeyes' Petteno from Gentoo.
chainsaw
parents:
538
diff
changeset
|
62 FALSE, |
890
ed26947bbf57
[svn] Gapless support. This comes with a few caveats, that I will mention here:
nenolod
parents:
625
diff
changeset
|
63 FALSE, |
1273
3b990c26fc46
[svn] - Support for the buffer indicator in playpaus.png that was apparently
nhjm449
parents:
1235
diff
changeset
|
64 FALSE, |
625
0a73d1faeb4e
[svn] GCC 4.1 warning fixes by Diego 'Flameeyes' Petteno from Gentoo.
chainsaw
parents:
538
diff
changeset
|
65 NULL |
0 | 66 }; |
67 | |
68 static GList *vis_list = NULL; | |
69 | |
70 gchar *input_info_text = NULL; | |
71 | |
72 InputPlugin * | |
73 get_current_input_plugin(void) | |
74 { | |
75 return ip_data.current_input_plugin; | |
76 } | |
77 | |
78 void | |
79 set_current_input_plugin(InputPlugin * ip) | |
80 { | |
81 ip_data.current_input_plugin = ip; | |
82 } | |
83 | |
84 GList * | |
85 get_input_list(void) | |
86 { | |
87 return ip_data.input_list; | |
88 } | |
89 | |
90 | |
91 gboolean | |
92 input_is_enabled(const gchar * filename) | |
93 { | |
94 gchar *basename = g_path_get_basename(filename); | |
95 gint enabled; | |
96 | |
97 enabled = GPOINTER_TO_INT(g_hash_table_lookup(plugin_matrix, basename)); | |
98 g_free(basename); | |
99 | |
100 return enabled; | |
101 } | |
102 | |
103 static void | |
104 disabled_iplugins_foreach_func(const gchar * name, | |
105 gboolean enabled, | |
106 GString * list) | |
107 { | |
108 g_return_if_fail(list != NULL); | |
109 | |
110 if (enabled) | |
111 return; | |
112 | |
113 if (list->len > 0) | |
114 g_string_append(list, ":"); | |
115 | |
116 g_string_append(list, name); | |
117 } | |
118 | |
119 gchar * | |
120 input_stringify_disabled_list(void) | |
121 { | |
122 GString *disabled_list; | |
123 | |
124 disabled_list = g_string_new(""); | |
125 g_hash_table_foreach(plugin_matrix, | |
126 (GHFunc) disabled_iplugins_foreach_func, | |
127 disabled_list); | |
128 | |
129 return g_string_free(disabled_list, FALSE); | |
130 } | |
131 | |
132 void | |
133 free_vis_data(void) | |
134 { | |
135 G_LOCK(vis_mutex); | |
136 g_list_foreach(vis_list, (GFunc) g_free, NULL); | |
137 g_list_free(vis_list); | |
138 vis_list = NULL; | |
139 G_UNLOCK(vis_mutex); | |
140 } | |
141 | |
142 static void | |
143 convert_to_s16_ne(AFormat fmt, gpointer ptr, gint16 * left, | |
144 gint16 * right, gint nch, gint max) | |
145 { | |
146 gint16 *ptr16; | |
147 guint16 *ptru16; | |
148 guint8 *ptru8; | |
149 gint i; | |
150 | |
151 switch (fmt) { | |
152 case FMT_U8: | |
153 ptru8 = ptr; | |
154 if (nch == 1) | |
155 for (i = 0; i < max; i++) | |
156 left[i] = ((*ptru8++) ^ 128) << 8; | |
157 else | |
158 for (i = 0; i < max; i++) { | |
159 left[i] = ((*ptru8++) ^ 128) << 8; | |
160 right[i] = ((*ptru8++) ^ 128) << 8; | |
161 } | |
162 break; | |
163 case FMT_S8: | |
164 ptru8 = ptr; | |
165 if (nch == 1) | |
166 for (i = 0; i < max; i++) | |
167 left[i] = (*ptru8++) << 8; | |
168 else | |
169 for (i = 0; i < max; i++) { | |
170 left[i] = (*ptru8++) << 8; | |
171 right[i] = (*ptru8++) << 8; | |
172 } | |
173 break; | |
174 case FMT_U16_LE: | |
175 ptru16 = ptr; | |
176 if (nch == 1) | |
177 for (i = 0; i < max; i++, ptru16++) | |
178 left[i] = GUINT16_FROM_LE(*ptru16) ^ 32768; | |
179 else | |
180 for (i = 0; i < max; i++) { | |
181 left[i] = GUINT16_FROM_LE(*ptru16) ^ 32768; | |
182 ptru16++; | |
183 right[i] = GUINT16_FROM_LE(*ptru16) ^ 32768; | |
184 ptru16++; | |
185 } | |
186 break; | |
187 case FMT_U16_BE: | |
188 ptru16 = ptr; | |
189 if (nch == 1) | |
190 for (i = 0; i < max; i++, ptru16++) | |
191 left[i] = GUINT16_FROM_BE(*ptru16) ^ 32768; | |
192 else | |
193 for (i = 0; i < max; i++) { | |
194 left[i] = GUINT16_FROM_BE(*ptru16) ^ 32768; | |
195 ptru16++; | |
196 right[i] = GUINT16_FROM_BE(*ptru16) ^ 32768; | |
197 ptru16++; | |
198 } | |
199 break; | |
200 case FMT_U16_NE: | |
201 ptru16 = ptr; | |
202 if (nch == 1) | |
203 for (i = 0; i < max; i++) | |
204 left[i] = (*ptru16++) ^ 32768; | |
205 else | |
206 for (i = 0; i < max; i++) { | |
207 left[i] = (*ptru16++) ^ 32768; | |
208 right[i] = (*ptru16++) ^ 32768; | |
209 } | |
210 break; | |
211 case FMT_S16_LE: | |
212 ptr16 = ptr; | |
213 if (nch == 1) | |
214 for (i = 0; i < max; i++, ptr16++) | |
215 left[i] = GINT16_FROM_LE(*ptr16); | |
216 else | |
217 for (i = 0; i < max; i++) { | |
218 left[i] = GINT16_FROM_LE(*ptr16); | |
219 ptr16++; | |
220 right[i] = GINT16_FROM_LE(*ptr16); | |
221 ptr16++; | |
222 } | |
223 break; | |
224 case FMT_S16_BE: | |
225 ptr16 = ptr; | |
226 if (nch == 1) | |
227 for (i = 0; i < max; i++, ptr16++) | |
228 left[i] = GINT16_FROM_BE(*ptr16); | |
229 else | |
230 for (i = 0; i < max; i++) { | |
231 left[i] = GINT16_FROM_BE(*ptr16); | |
232 ptr16++; | |
233 right[i] = GINT16_FROM_BE(*ptr16); | |
234 ptr16++; | |
235 } | |
236 break; | |
237 case FMT_S16_NE: | |
238 ptr16 = ptr; | |
239 if (nch == 1) | |
240 for (i = 0; i < max; i++) | |
241 left[i] = (*ptr16++); | |
242 else | |
243 for (i = 0; i < max; i++) { | |
244 left[i] = (*ptr16++); | |
245 right[i] = (*ptr16++); | |
246 } | |
247 break; | |
248 } | |
249 } | |
250 | |
251 InputVisType | |
252 input_get_vis_type() | |
253 { | |
254 return INPUT_VIS_OFF; | |
255 } | |
256 | |
257 void | |
258 input_add_vis(gint time, guchar * s, InputVisType type) | |
259 { | |
260 g_warning("plugin uses obsoleted input_add_vis()"); | |
261 } | |
262 | |
263 void | |
264 input_add_vis_pcm(gint time, AFormat fmt, gint nch, gint length, gpointer ptr) | |
265 { | |
266 VisNode *vis_node; | |
267 gint max; | |
268 | |
269 max = length / nch; | |
270 if (fmt == FMT_U16_LE || fmt == FMT_U16_BE || fmt == FMT_U16_NE || | |
271 fmt == FMT_S16_LE || fmt == FMT_S16_BE || fmt == FMT_S16_NE) | |
272 max /= 2; | |
273 max = CLAMP(max, 0, 512); | |
274 | |
275 vis_node = g_new0(VisNode, 1); | |
276 vis_node->time = time; | |
277 vis_node->nch = nch; | |
278 vis_node->length = max; | |
279 convert_to_s16_ne(fmt, ptr, vis_node->data[0], vis_node->data[1], nch, | |
280 max); | |
281 | |
282 G_LOCK(vis_mutex); | |
283 vis_list = g_list_append(vis_list, vis_node); | |
284 G_UNLOCK(vis_mutex); | |
285 } | |
286 | |
287 void | |
288 input_dont_show_warning(GtkObject * object, gpointer user_data) | |
289 { | |
290 *((gboolean *) user_data) = | |
291 !gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(object)); | |
292 } | |
293 | |
294 | |
295 void | |
296 input_show_unplayable_files(const gchar * filename) | |
297 { | |
298 static GtkWidget *dialog = NULL; | |
299 static GtkListStore *store = NULL; | |
300 | |
301 const gchar *markup = | |
302 N_("<b><big>Unable to play files.</big></b>\n\n" | |
303 "The following files could not be played. Please check that:\n" | |
304 "1. they are accessible.\n" | |
305 "2. you have enabled the media plugins required."); | |
306 | |
307 GtkTreeIter iter; | |
308 | |
309 gchar *filename_utf8; | |
310 | |
311 if (!dialog) { | |
312 GtkWidget *vbox, *check; | |
313 GtkWidget *expander; | |
314 GtkWidget *scrolled, *treeview; | |
315 GtkCellRenderer *renderer; | |
316 | |
317 dialog = | |
1653 | 318 gtk_message_dialog_new_with_markup(GTK_WINDOW(mainwin), |
0 | 319 GTK_DIALOG_DESTROY_WITH_PARENT, |
320 GTK_MESSAGE_ERROR, | |
321 GTK_BUTTONS_OK, | |
322 _(markup)); | |
323 | |
324 vbox = gtk_vbox_new(FALSE, 6); | |
325 | |
326 check = gtk_check_button_new_with_label | |
327 (_("Don't show this warning anymore")); | |
328 | |
329 expander = gtk_expander_new_with_mnemonic(_("Show more _details")); | |
330 | |
331 scrolled = gtk_scrolled_window_new(NULL, NULL); | |
332 gtk_container_add(GTK_CONTAINER(expander), scrolled); | |
333 | |
334 store = gtk_list_store_new(1, G_TYPE_STRING); | |
335 | |
336 treeview = gtk_tree_view_new_with_model(GTK_TREE_MODEL(store)); | |
337 gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(treeview), FALSE); | |
338 gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(scrolled), | |
339 treeview); | |
340 | |
341 renderer = gtk_cell_renderer_text_new(); | |
342 gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(treeview), | |
343 -1, _("Filename"), | |
344 renderer, | |
345 "text", 0, | |
346 NULL); | |
347 | |
348 vbox = GTK_DIALOG(dialog)->vbox; | |
349 gtk_box_pack_start(GTK_BOX(vbox), check, FALSE, FALSE, 0); | |
350 gtk_box_pack_start(GTK_BOX(vbox), expander, TRUE, TRUE, 0); | |
351 | |
352 g_signal_connect(dialog, "response", | |
353 G_CALLBACK(gtk_widget_destroy), | |
354 dialog); | |
355 g_signal_connect(dialog, "destroy", | |
356 G_CALLBACK(gtk_widget_destroyed), | |
357 &dialog); | |
358 g_signal_connect(check, "clicked", | |
359 G_CALLBACK(input_dont_show_warning), | |
360 &cfg.warn_about_unplayables); | |
361 | |
362 gtk_widget_show_all(dialog); | |
363 } | |
364 | |
365 gtk_window_present(GTK_WINDOW(dialog)); | |
366 | |
367 filename_utf8 = filename_to_utf8(filename); | |
368 gtk_list_store_append(store, &iter); | |
369 gtk_list_store_set(store, &iter, 0, filename_utf8, -1); | |
370 g_free(filename_utf8); | |
371 } | |
372 | |
373 | |
374 void | |
375 input_file_not_playable(const gchar * filename) | |
376 { | |
377 if (cfg.warn_about_unplayables) | |
378 input_show_unplayable_files(filename); | |
379 } | |
380 | |
355
1c701dfe5098
[svn] Cache the decoder used for each PlaylistEntry. This reduces the amount
nenolod
parents:
284
diff
changeset
|
381 /* |
1c701dfe5098
[svn] Cache the decoder used for each PlaylistEntry. This reduces the amount
nenolod
parents:
284
diff
changeset
|
382 * input_check_file() |
1c701dfe5098
[svn] Cache the decoder used for each PlaylistEntry. This reduces the amount
nenolod
parents:
284
diff
changeset
|
383 * |
1c701dfe5098
[svn] Cache the decoder used for each PlaylistEntry. This reduces the amount
nenolod
parents:
284
diff
changeset
|
384 * Inputs: |
1c701dfe5098
[svn] Cache the decoder used for each PlaylistEntry. This reduces the amount
nenolod
parents:
284
diff
changeset
|
385 * filename to check recursively against input plugins |
1c701dfe5098
[svn] Cache the decoder used for each PlaylistEntry. This reduces the amount
nenolod
parents:
284
diff
changeset
|
386 * whether or not to show an error |
1c701dfe5098
[svn] Cache the decoder used for each PlaylistEntry. This reduces the amount
nenolod
parents:
284
diff
changeset
|
387 * |
1c701dfe5098
[svn] Cache the decoder used for each PlaylistEntry. This reduces the amount
nenolod
parents:
284
diff
changeset
|
388 * Outputs: |
1c701dfe5098
[svn] Cache the decoder used for each PlaylistEntry. This reduces the amount
nenolod
parents:
284
diff
changeset
|
389 * pointer to input plugin which can handle this file |
1c701dfe5098
[svn] Cache the decoder used for each PlaylistEntry. This reduces the amount
nenolod
parents:
284
diff
changeset
|
390 * otherwise, NULL |
1c701dfe5098
[svn] Cache the decoder used for each PlaylistEntry. This reduces the amount
nenolod
parents:
284
diff
changeset
|
391 * |
1c701dfe5098
[svn] Cache the decoder used for each PlaylistEntry. This reduces the amount
nenolod
parents:
284
diff
changeset
|
392 * (the previous code returned a boolean of whether or not we can |
1c701dfe5098
[svn] Cache the decoder used for each PlaylistEntry. This reduces the amount
nenolod
parents:
284
diff
changeset
|
393 * play the file... even WORSE for performance) |
1c701dfe5098
[svn] Cache the decoder used for each PlaylistEntry. This reduces the amount
nenolod
parents:
284
diff
changeset
|
394 * |
1c701dfe5098
[svn] Cache the decoder used for each PlaylistEntry. This reduces the amount
nenolod
parents:
284
diff
changeset
|
395 * Side Effects: |
1c701dfe5098
[svn] Cache the decoder used for each PlaylistEntry. This reduces the amount
nenolod
parents:
284
diff
changeset
|
396 * various input plugins open the file and probe it |
1c701dfe5098
[svn] Cache the decoder used for each PlaylistEntry. This reduces the amount
nenolod
parents:
284
diff
changeset
|
397 * -- this can have very ugly effects performance wise on streams |
1c701dfe5098
[svn] Cache the decoder used for each PlaylistEntry. This reduces the amount
nenolod
parents:
284
diff
changeset
|
398 * |
1c701dfe5098
[svn] Cache the decoder used for each PlaylistEntry. This reduces the amount
nenolod
parents:
284
diff
changeset
|
399 * --nenolod, Dec 31 2005 |
1c701dfe5098
[svn] Cache the decoder used for each PlaylistEntry. This reduces the amount
nenolod
parents:
284
diff
changeset
|
400 */ |
1c701dfe5098
[svn] Cache the decoder used for each PlaylistEntry. This reduces the amount
nenolod
parents:
284
diff
changeset
|
401 InputPlugin * |
0 | 402 input_check_file(const gchar * filename, gboolean show_warning) |
403 { | |
404 GList *node; | |
405 InputPlugin *ip; | |
406 gchar *filename_proxy; | |
1486 | 407 gint ret = 1; |
0 | 408 |
409 filename_proxy = g_strdup(filename); | |
410 | |
411 for (node = get_input_list(); node != NULL; node = g_list_next(node)) { | |
412 ip = INPUT_PLUGIN(node->data); | |
413 if (ip && input_is_enabled(ip->filename) && | |
1486 | 414 (ret = ip->is_our_file(filename_proxy)) > 0) { |
0 | 415 g_free(filename_proxy); |
355
1c701dfe5098
[svn] Cache the decoder used for each PlaylistEntry. This reduces the amount
nenolod
parents:
284
diff
changeset
|
416 return ip; |
0 | 417 } |
1765
c186ee9524ed
[svn] - enforce the ret = -1 == silent failure rule
nenolod
parents:
1755
diff
changeset
|
418 else if (ret <= -1) |
c186ee9524ed
[svn] - enforce the ret = -1 == silent failure rule
nenolod
parents:
1755
diff
changeset
|
419 break; |
0 | 420 } |
421 | |
422 g_free(filename_proxy); | |
423 | |
1486 | 424 if (show_warning && !(ret <= -1)) { |
0 | 425 input_file_not_playable(filename); |
426 } | |
427 | |
355
1c701dfe5098
[svn] Cache the decoder used for each PlaylistEntry. This reduces the amount
nenolod
parents:
284
diff
changeset
|
428 return NULL; |
0 | 429 } |
430 | |
431 | |
432 void | |
433 input_set_eq(gint on, gfloat preamp, gfloat * bands) | |
434 { | |
435 if (!ip_data.playing) | |
436 return; | |
437 | |
438 if (!get_current_input_plugin()) | |
439 return; | |
440 | |
441 if (get_current_input_plugin()->set_eq) | |
442 get_current_input_plugin()->set_eq(on, preamp, bands); | |
443 } | |
444 | |
445 void | |
446 input_get_song_info(const gchar * filename, gchar ** title, gint * length) | |
447 { | |
448 InputPlugin *ip = NULL; | |
449 BmpTitleInput *input; | |
450 GList *node; | |
451 gchar *tmp = NULL, *ext; | |
452 gchar *filename_proxy; | |
453 | |
454 g_return_if_fail(filename != NULL); | |
455 g_return_if_fail(title != NULL); | |
456 g_return_if_fail(length != NULL); | |
457 | |
458 filename_proxy = g_strdup(filename); | |
459 | |
460 for (node = get_input_list(); node != NULL; node = g_list_next(node)) { | |
461 ip = INPUT_PLUGIN(node->data); | |
462 if (input_is_enabled(ip->filename) && ip->is_our_file(filename_proxy)) | |
463 break; | |
464 } | |
465 | |
466 if (ip && node && ip->get_song_info) { | |
467 ip->get_song_info(filename_proxy, &tmp, length); | |
468 *title = str_to_utf8(tmp); | |
469 g_free(tmp); | |
470 } | |
471 else { | |
472 input = bmp_title_input_new(); | |
473 | |
474 tmp = g_strdup(filename); | |
475 if ((ext = strrchr(tmp, '.'))) | |
476 *ext = '\0'; | |
477 | |
478 input->file_name = g_path_get_basename(tmp); | |
479 input->file_ext = ext ? ext + 1 : NULL; | |
480 input->file_path = tmp; | |
481 | |
482 if ((tmp = xmms_get_titlestring(xmms_get_gentitle_format(), input))) { | |
483 (*title) = str_to_utf8(tmp); | |
484 g_free(tmp); | |
485 } | |
486 else { | |
487 (*title) = filename_to_utf8(input->file_name); | |
488 } | |
489 | |
490 (*length) = -1; | |
491 | |
492 bmp_title_input_free(input); | |
1588
15d92c51bde6
[svn] - modified time (mtime) has been introduced into tuple
yaz
parents:
1547
diff
changeset
|
493 input = NULL; |
0 | 494 } |
495 | |
496 g_free(filename_proxy); | |
497 } | |
498 | |
1231 | 499 TitleInput * |
500 input_get_song_tuple(const gchar * filename) | |
501 { | |
502 InputPlugin *ip = NULL; | |
503 TitleInput *input; | |
504 GList *node; | |
505 gchar *tmp = NULL, *ext; | |
506 gchar *filename_proxy; | |
507 | |
508 if (filename == NULL) | |
509 return NULL; | |
510 | |
511 filename_proxy = g_strdup(filename); | |
512 | |
513 for (node = get_input_list(); node != NULL; node = g_list_next(node)) { | |
514 ip = INPUT_PLUGIN(node->data); | |
515 if (input_is_enabled(ip->filename) && ip->is_our_file(filename_proxy)) | |
516 break; | |
517 } | |
518 | |
519 if (ip && node && ip->get_song_tuple) | |
520 input = ip->get_song_tuple(filename_proxy); | |
521 else { | |
522 input = bmp_title_input_new(); | |
523 | |
524 tmp = g_strdup(filename); | |
525 if ((ext = strrchr(tmp, '.'))) | |
526 *ext = '\0'; | |
527 | |
1235 | 528 input->track_name = NULL; |
529 input->length = -1; | |
530 input_get_song_info(filename, &input->track_name, &input->length); | |
1231 | 531 input->file_name = g_path_get_basename(tmp); |
532 input->file_ext = ext ? ext + 1 : NULL; | |
533 input->file_path = tmp; | |
534 } | |
535 | |
536 return input; | |
537 } | |
538 | |
0 | 539 static void |
540 input_general_file_info_box(const gchar * filename, InputPlugin * ip) | |
541 { | |
542 GtkWidget *window, *vbox; | |
543 GtkWidget *label, *filename_hbox, *filename_entry; | |
544 GtkWidget *bbox, *cancel; | |
545 | |
546 gchar *title, *fileinfo, *basename, *iplugin; | |
547 gchar *filename_utf8; | |
548 | |
549 window = gtk_window_new(GTK_WINDOW_TOPLEVEL); | |
550 gtk_window_set_resizable(GTK_WINDOW(window), FALSE); | |
551 gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER); | |
552 | |
553 basename = g_path_get_basename(filename); | |
554 fileinfo = filename_to_utf8(basename); | |
257
256b3acc87d4
[svn] Properly report Audacious instead of XMMS or BMP in all places. Patch by laci; closes bug #379.
chainsaw
parents:
0
diff
changeset
|
555 title = g_strdup_printf(_("audacious: %s"), fileinfo); |
0 | 556 |
557 gtk_window_set_title(GTK_WINDOW(window), title); | |
558 | |
559 g_free(title); | |
560 g_free(fileinfo); | |
561 g_free(basename); | |
562 | |
563 gtk_container_set_border_width(GTK_CONTAINER(window), 10); | |
564 | |
565 vbox = gtk_vbox_new(FALSE, 10); | |
566 gtk_container_add(GTK_CONTAINER(window), vbox); | |
567 | |
568 filename_hbox = gtk_hbox_new(FALSE, 5); | |
569 gtk_box_pack_start(GTK_BOX(vbox), filename_hbox, FALSE, TRUE, 0); | |
570 | |
571 label = gtk_label_new(_("Filename:")); | |
572 gtk_box_pack_start(GTK_BOX(filename_hbox), label, FALSE, TRUE, 0); | |
573 | |
574 filename_entry = xmms_entry_new(); | |
575 filename_utf8 = filename_to_utf8(filename); | |
576 | |
577 gtk_entry_set_text(GTK_ENTRY(filename_entry), filename_utf8); | |
578 gtk_editable_set_editable(GTK_EDITABLE(filename_entry), FALSE); | |
579 gtk_box_pack_start(GTK_BOX(filename_hbox), filename_entry, TRUE, TRUE, 0); | |
580 | |
581 g_free(filename_utf8); | |
582 | |
583 if (ip) | |
584 if (ip->description) | |
585 iplugin = ip->description; | |
586 else | |
587 iplugin = ip->filename; | |
588 else | |
589 iplugin = _("No input plugin recognized this file"); | |
590 | |
591 title = g_strdup_printf(_("Input plugin: %s"), iplugin); | |
592 | |
593 label = gtk_label_new(title); | |
594 gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); | |
595 gtk_label_set_justify(GTK_LABEL(label), GTK_JUSTIFY_LEFT); | |
596 g_free(title); | |
597 gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, TRUE, 0); | |
598 | |
599 bbox = gtk_hbutton_box_new(); | |
600 gtk_button_box_set_layout(GTK_BUTTON_BOX(bbox), GTK_BUTTONBOX_END); | |
601 gtk_box_pack_start(GTK_BOX(vbox), bbox, FALSE, FALSE, 0); | |
602 | |
603 cancel = gtk_button_new_from_stock(GTK_STOCK_CLOSE); | |
604 g_signal_connect_swapped(G_OBJECT(cancel), "clicked", | |
605 GTK_SIGNAL_FUNC(gtk_widget_destroy), | |
606 GTK_OBJECT(window)); | |
607 GTK_WIDGET_SET_FLAGS(cancel, GTK_CAN_DEFAULT); | |
608 gtk_box_pack_start(GTK_BOX(bbox), cancel, TRUE, TRUE, 0); | |
609 | |
610 gtk_widget_show_all(window); | |
611 } | |
612 | |
613 void | |
614 input_file_info_box(const gchar * filename) | |
615 { | |
616 GList *node; | |
617 InputPlugin *ip; | |
618 gchar *filename_proxy; | |
619 | |
620 filename_proxy = g_strdup(filename); | |
621 | |
622 for (node = get_input_list(); node != NULL; node = g_list_next(node)) { | |
623 ip = INPUT_PLUGIN(node->data); | |
624 if (input_is_enabled(ip->filename) | |
625 && ip->is_our_file(filename_proxy)) { | |
626 if (ip->file_info_box) | |
627 ip->file_info_box(filename_proxy); | |
628 else | |
629 input_general_file_info_box(filename, ip); | |
630 | |
631 g_free(filename_proxy); | |
632 return; | |
633 } | |
634 } | |
635 | |
636 input_general_file_info_box(filename, NULL); | |
637 g_free(filename_proxy); | |
638 } | |
639 | |
640 GList * | |
641 input_scan_dir(const gchar * path) | |
642 { | |
643 GList *node, *result = NULL; | |
644 InputPlugin *ip; | |
645 gchar *path_proxy; | |
646 | |
647 g_return_val_if_fail(path != NULL, NULL); | |
648 | |
649 if (*path == '/') | |
650 while (path[1] == '/') | |
651 path++; | |
652 | |
653 path_proxy = g_strdup(path); | |
654 | |
655 for (node = get_input_list(); node; node = g_list_next(node)) { | |
656 ip = INPUT_PLUGIN(node->data); | |
657 | |
658 if (!ip) | |
659 continue; | |
660 | |
661 if (!ip->scan_dir) | |
662 continue; | |
663 | |
664 if (!input_is_enabled(ip->filename)) | |
665 continue; | |
666 | |
667 if ((result = ip->scan_dir(path_proxy))) | |
668 break; | |
669 } | |
670 | |
671 g_free(path_proxy); | |
672 | |
673 return result; | |
674 } | |
675 | |
676 void | |
677 input_get_volume(gint * l, gint * r) | |
678 { | |
679 *l = -1; | |
680 *r = -1; | |
681 if (bmp_playback_get_playing()) { | |
682 if (get_current_input_plugin() && | |
683 get_current_input_plugin()->get_volume) { | |
684 get_current_input_plugin()->get_volume(l, r); | |
685 return; | |
686 } | |
687 } | |
688 output_get_volume(l, r); | |
689 } | |
690 | |
691 void | |
692 input_set_volume(gint l, gint r) | |
693 { | |
694 if (bmp_playback_get_playing()) { | |
695 if (get_current_input_plugin() && | |
696 get_current_input_plugin()->set_volume) { | |
697 get_current_input_plugin()->set_volume(l, r); | |
698 return; | |
699 } | |
700 } | |
701 output_set_volume(l, r); | |
702 } | |
703 | |
704 void | |
705 input_update_vis(gint time) | |
706 { | |
707 GList *node; | |
708 VisNode *vis = NULL, *visnext = NULL; | |
709 gboolean found = FALSE; | |
710 | |
711 G_LOCK(vis_mutex); | |
712 node = vis_list; | |
713 while (g_list_next(node) && !found) { | |
714 visnext = g_list_next(node)->data; | |
715 vis = node->data; | |
716 | |
717 if (vis->time >= time) | |
718 break; | |
719 | |
720 vis_list = g_list_delete_link(vis_list, node); | |
721 | |
722 if (visnext->time >= time) { | |
723 found = TRUE; | |
724 break; | |
725 } | |
726 g_free(vis); | |
727 node = vis_list; | |
728 } | |
729 G_UNLOCK(vis_mutex); | |
730 | |
731 if (found) { | |
732 vis_send_data(vis->data, vis->nch, vis->length); | |
733 g_free(vis); | |
734 } | |
735 else | |
736 vis_send_data(NULL, 0, 0); | |
737 } | |
738 | |
739 | |
740 gchar * | |
741 input_get_info_text(void) | |
742 { | |
1653 | 743 return g_strdup(input_info_text); |
0 | 744 } |
745 | |
746 void | |
747 input_set_info_text(const gchar * text) | |
748 { | |
1653 | 749 g_free(input_info_text); |
750 input_info_text = g_strdup(text); | |
751 mainwin_set_info_text(); | |
0 | 752 } |
753 | |
754 void | |
1273
3b990c26fc46
[svn] - Support for the buffer indicator in playpaus.png that was apparently
nhjm449
parents:
1235
diff
changeset
|
755 input_set_status_buffering(gboolean status) |
3b990c26fc46
[svn] - Support for the buffer indicator in playpaus.png that was apparently
nhjm449
parents:
1235
diff
changeset
|
756 { |
3b990c26fc46
[svn] - Support for the buffer indicator in playpaus.png that was apparently
nhjm449
parents:
1235
diff
changeset
|
757 if (!bmp_playback_get_playing()) |
3b990c26fc46
[svn] - Support for the buffer indicator in playpaus.png that was apparently
nhjm449
parents:
1235
diff
changeset
|
758 return; |
3b990c26fc46
[svn] - Support for the buffer indicator in playpaus.png that was apparently
nhjm449
parents:
1235
diff
changeset
|
759 |
3b990c26fc46
[svn] - Support for the buffer indicator in playpaus.png that was apparently
nhjm449
parents:
1235
diff
changeset
|
760 if (!get_current_input_plugin()) |
3b990c26fc46
[svn] - Support for the buffer indicator in playpaus.png that was apparently
nhjm449
parents:
1235
diff
changeset
|
761 return; |
3b990c26fc46
[svn] - Support for the buffer indicator in playpaus.png that was apparently
nhjm449
parents:
1235
diff
changeset
|
762 |
3b990c26fc46
[svn] - Support for the buffer indicator in playpaus.png that was apparently
nhjm449
parents:
1235
diff
changeset
|
763 ip_data.buffering = status; |
3b990c26fc46
[svn] - Support for the buffer indicator in playpaus.png that was apparently
nhjm449
parents:
1235
diff
changeset
|
764 |
1672
600efc52c645
[svn] - be careful about referencing a NULL widget (e.g. headless/serveronly mode crashes on streams, bug #562)
nenolod
parents:
1653
diff
changeset
|
765 g_return_if_fail(mainwin_playstatus != NULL); |
600efc52c645
[svn] - be careful about referencing a NULL widget (e.g. headless/serveronly mode crashes on streams, bug #562)
nenolod
parents:
1653
diff
changeset
|
766 |
600efc52c645
[svn] - be careful about referencing a NULL widget (e.g. headless/serveronly mode crashes on streams, bug #562)
nenolod
parents:
1653
diff
changeset
|
767 if (ip_data.buffering == TRUE && mainwin_playstatus != NULL && mainwin_playstatus->ps_status == STATUS_STOP) |
1273
3b990c26fc46
[svn] - Support for the buffer indicator in playpaus.png that was apparently
nhjm449
parents:
1235
diff
changeset
|
768 mainwin_playstatus->ps_status = STATUS_PLAY; |
1672
600efc52c645
[svn] - be careful about referencing a NULL widget (e.g. headless/serveronly mode crashes on streams, bug #562)
nenolod
parents:
1653
diff
changeset
|
769 |
1273
3b990c26fc46
[svn] - Support for the buffer indicator in playpaus.png that was apparently
nhjm449
parents:
1235
diff
changeset
|
770 playstatus_set_status_buffering(mainwin_playstatus, ip_data.buffering); |
3b990c26fc46
[svn] - Support for the buffer indicator in playpaus.png that was apparently
nhjm449
parents:
1235
diff
changeset
|
771 } |
3b990c26fc46
[svn] - Support for the buffer indicator in playpaus.png that was apparently
nhjm449
parents:
1235
diff
changeset
|
772 |
3b990c26fc46
[svn] - Support for the buffer indicator in playpaus.png that was apparently
nhjm449
parents:
1235
diff
changeset
|
773 void |
0 | 774 input_about(gint index) |
775 { | |
776 InputPlugin *ip; | |
777 | |
778 ip = g_list_nth(ip_data.input_list, index)->data; | |
779 if (ip && ip->about) | |
780 ip->about(); | |
781 } | |
782 | |
783 void | |
784 input_configure(gint index) | |
785 { | |
786 InputPlugin *ip; | |
787 | |
788 ip = g_list_nth(ip_data.input_list, index)->data; | |
789 if (ip && ip->configure) | |
790 ip->configure(); | |
791 } |