summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAndrej Shadura <andrewsh@debian.org>2019-02-20 19:35:42 +0100
committerAndrej Shadura <andrewsh@debian.org>2019-02-20 19:35:42 +0100
commit1a988068635ca5f8a74c4654098d07f92bc0dcf4 (patch)
tree04ab5d5c0ffbdc6d60621be489508bf7140c7b34 /src
parent20b38fea7b2b8e6dd31a62dbc5ec9e4c2888a013 (diff)
New upstream version 3.10.1
Diffstat (limited to 'src')
-rw-r--r--src/audacious/dbus-server.cc31
-rw-r--r--src/audtool/main.c37
-rw-r--r--src/libaudcore/equalizer-preset.cc31
-rw-r--r--src/libaudcore/hook.h6
-rw-r--r--src/libaudcore/output.cc9
-rw-r--r--src/libaudcore/playlist-files.cc11
-rw-r--r--src/libaudcore/probe.cc9
-rw-r--r--src/libaudgui/eq-preset.cc29
-rw-r--r--src/libaudgui/infowin.cc35
-rw-r--r--src/libaudqt/audqt.cc2
-rw-r--r--src/libaudqt/infopopup-qt.cc14
-rw-r--r--src/libaudqt/libaudqt-internal.h7
-rw-r--r--src/libaudqt/util-qt.cc32
-rw-r--r--src/libaudqt/volumebutton.cc4
14 files changed, 196 insertions, 61 deletions
diff --git a/src/audacious/dbus-server.cc b/src/audacious/dbus-server.cc
index 7602ace..20a6c58 100644
--- a/src/audacious/dbus-server.cc
+++ b/src/audacious/dbus-server.cc
@@ -635,27 +635,30 @@ static gboolean do_song_title (Obj * obj, Invoc * invoc, unsigned pos)
static gboolean do_song_tuple (Obj * obj, Invoc * invoc, unsigned pos, const char * key)
{
Tuple::Field field = Tuple::field_by_name (key);
- Tuple tuple;
- GVariant * var;
+ GVariant * var = nullptr;
if (field >= 0)
- tuple = CURRENT.entry_tuple (pos);
-
- switch (tuple.get_value_type (field))
{
- case Tuple::String:
- var = g_variant_new_string (tuple.get_str (field));
- break;
+ Tuple tuple = CURRENT.entry_tuple (pos);
- case Tuple::Int:
- var = g_variant_new_int32 (tuple.get_int (field));
- break;
+ switch (tuple.get_value_type (field))
+ {
+ case Tuple::String:
+ var = g_variant_new_string (tuple.get_str (field));
+ break;
- default:
- var = g_variant_new_string ("");
- break;
+ case Tuple::Int:
+ var = g_variant_new_int32 (tuple.get_int (field));
+ break;
+
+ default:
+ break;
+ }
}
+ if (! var)
+ var = g_variant_new_string ("");
+
FINISH2 (song_tuple, g_variant_new_variant (var));
return true;
}
diff --git a/src/audtool/main.c b/src/audtool/main.c
index 345dcb1..a09c6b8 100644
--- a/src/audtool/main.c
+++ b/src/audtool/main.c
@@ -23,6 +23,10 @@
#include <string.h>
#include <locale.h>
+#ifdef _WIN32
+#include <windows.h>
+#endif
+
#include "audtool.h"
const struct commandhandler handlers[] =
@@ -182,6 +186,35 @@ static void audtool_connect (int instance)
atexit (audtool_disconnect);
}
+#ifdef _WIN32
+static void print_utf8 (const char * str)
+{
+ HANDLE h = GetStdHandle (STD_OUTPUT_HANDLE);
+ DWORD mode;
+
+ if (h != INVALID_HANDLE_VALUE && GetConsoleMode (h, & mode))
+ {
+ // stdout is the console, which needs special handling to display
+ // non-ASCII characters correctly (in 2018, the MS runtime *still*
+ // doesn't handle UTF-8 reliably).
+ glong n_converted;
+ gunichar2 * utf16 = g_utf8_to_utf16 (str, -1, NULL, & n_converted, NULL);
+
+ if (utf16)
+ {
+ DWORD n_written;
+ WriteConsoleW (h, utf16, n_converted, & n_written, NULL);
+ g_free (utf16);
+ }
+ }
+ else
+ {
+ // fputs() works fine when stdout is redirected.
+ fputs (str, stdout);
+ }
+}
+#endif // _WIN32
+
int main (int argc, char * * argv)
{
int instance = 1;
@@ -193,6 +226,10 @@ int main (int argc, char * * argv)
g_type_init();
#endif
+#ifdef _WIN32
+ g_set_print_handler (print_utf8);
+#endif
+
// parse instance number (must come first)
if (argc >= 2 && argv[1][0] == '-' && argv[1][1] >= '1' && argv[1][1] <= '9' && ! argv[1][2])
{
diff --git a/src/libaudcore/equalizer-preset.cc b/src/libaudcore/equalizer-preset.cc
index c57d5f0..933148f 100644
--- a/src/libaudcore/equalizer-preset.cc
+++ b/src/libaudcore/equalizer-preset.cc
@@ -92,8 +92,27 @@ EXPORT bool aud_eq_write_presets (const Index<EqualizerPreset> & list, const cha
/* Note: Winamp 2.x had a +/- 20 dB range.
* Winamp 5.x had a +/- 12 dB range, which we use here. */
-#define FROM_WINAMP_VAL(x) ((31.5 - (x)) * (12.0 / 31.5))
-#define TO_WINAMP_VAL(x) (round (31.5 - (x) * (31.5 / 12.0)))
+
+/* Encoded values range from 0 (+12 dB) to 63 (-12 dB). The sign is
+ * reversed for some unknown reason. Mathematically, there is no way
+ * to represent 0 dB exactly (31 is +0.19 dB, 32 is -0.19 dB) but we
+ * mimic WinAmp in letting 31 mean 0 dB as a special case. */
+
+static float decode_winamp_val (int val)
+{
+ if (val == 31)
+ return 0.0f;
+
+ return (31.5f - val) * (12.0f / 31.5f);
+}
+
+static int encode_winamp_val (float val)
+{
+ if (val == 0.0f)
+ return 31;
+
+ return lroundf (31.5f - val * (31.5f / 12.0f));
+}
EXPORT Index<EqualizerPreset> aud_import_winamp_presets (VFSFile & file)
{
@@ -118,10 +137,10 @@ EXPORT Index<EqualizerPreset> aud_import_winamp_presets (VFSFile & file)
break;
EqualizerPreset & preset = list.append (String (preset_name));
- preset.preamp = FROM_WINAMP_VAL (bands[10]);
+ preset.preamp = decode_winamp_val (bands[10]);
for (int i = 0; i < AUD_EQ_NBANDS; i ++)
- preset.bands[i] = FROM_WINAMP_VAL (bands[i]);
+ preset.bands[i] = decode_winamp_val (bands[i]);
}
return list;
@@ -141,9 +160,9 @@ EXPORT bool aud_export_winamp_preset (const EqualizerPreset & preset, VFSFile &
return false;
for (int i = 0; i < AUD_EQ_NBANDS; i ++)
- bands[i] = TO_WINAMP_VAL (preset.bands[i]);
+ bands[i] = encode_winamp_val (preset.bands[i]);
- bands[10] = TO_WINAMP_VAL (preset.preamp);
+ bands[10] = encode_winamp_val (preset.preamp);
if (file.fwrite (bands, 1, 11) != 11)
return false;
diff --git a/src/libaudcore/hook.h b/src/libaudcore/hook.h
index 147591a..5772844 100644
--- a/src/libaudcore/hook.h
+++ b/src/libaudcore/hook.h
@@ -99,9 +99,9 @@ void hook_call (const char * name, void * data);
typedef void (* EventDestroyFunc) (void * data);
-/* Schedules a call of the hook <name> from the program's main loop, to be
- * executed in <time> milliseconds. If <destroy> is not nullptr, it will be called
- * on <data> after the hook is called. */
+/* Schedules a call of the hook <name> from the program's main loop.
+ * If <destroy> is not nullptr, it will be called on <data> after the
+ * hook is called. */
void event_queue (const char * name, void * data, EventDestroyFunc destroy = nullptr);
/* Cancels pending hook calls matching <name> and <data>. If <data> is nullptr,
diff --git a/src/libaudcore/output.cc b/src/libaudcore/output.cc
index 191884d..bb861e5 100644
--- a/src/libaudcore/output.cc
+++ b/src/libaudcore/output.cc
@@ -172,11 +172,14 @@ static void setup_output (bool new_input)
bool automatic;
int format = get_format (automatic);
- AUDINFO ("Setup output, format %d, %d channels, %d Hz.\n", format, effect_channels, effect_rate);
-
- if (s_output && format == out_format && effect_channels == out_channels &&
+ if (s_output && effect_channels == out_channels &&
effect_rate == out_rate && ! (new_input && cop->force_reopen))
+ {
+ AUDINFO ("Reuse output, %d channels, %d Hz.\n", effect_channels, effect_rate);
return;
+ }
+
+ AUDINFO ("Setup output, format %d, %d channels, %d Hz.\n", format, effect_channels, effect_rate);
cleanup_output ();
cop->set_info (in_filename, in_tuple);
diff --git a/src/libaudcore/playlist-files.cc b/src/libaudcore/playlist-files.cc
index 29cbff0..a2914b1 100644
--- a/src/libaudcore/playlist-files.cc
+++ b/src/libaudcore/playlist-files.cc
@@ -142,14 +142,21 @@ EXPORT bool Playlist::save_to_file (const char * filename, GetMode mode) const
VFSFile file (filename, "w");
if (! file)
+ {
+ aud_ui_show_error (str_printf (_("Error opening %s:\n%s"),
+ filename, file.error ()));
return false;
+ }
- return pp->save (filename, file, title, items) && file.fflush () == 0;
+ if (pp->save (filename, file, title, items) && file.fflush () == 0)
+ return true;
+
+ aud_ui_show_error (str_printf (_("Error saving %s."), filename));
+ return false;
}
}
aud_ui_show_error (str_printf (_("Cannot save %s: unsupported file name extension."), filename));
-
return false;
}
diff --git a/src/libaudcore/probe.cc b/src/libaudcore/probe.cc
index 5c57ef8..38cf73d 100644
--- a/src/libaudcore/probe.cc
+++ b/src/libaudcore/probe.cc
@@ -242,6 +242,15 @@ EXPORT bool aud_custom_infowin (const char * filename, PluginHandle * decoder)
if (! strncmp (filename, "stdin://", 8))
return false;
+ // In hindsight, a flag should have been added indicating whether a
+ // plugin provides a custom info window or not. Currently, only two
+ // plugins do so. Since custom info windows are deprecated anyway,
+ // check for those two plugins explicitly and in all other cases,
+ // don't open the input file to prevent freezing the UI.
+ const char * base = aud_plugin_get_basename (decoder);
+ if (strcmp (base, "amidi-plug") && strcmp (base, "vtx"))
+ return false;
+
auto ip = (InputPlugin *) aud_plugin_get_header (decoder);
if (! ip)
return false;
diff --git a/src/libaudgui/eq-preset.cc b/src/libaudgui/eq-preset.cc
index a2f1c9d..159fef9 100644
--- a/src/libaudgui/eq-preset.cc
+++ b/src/libaudgui/eq-preset.cc
@@ -188,6 +188,9 @@ static void revert_changes ()
static void cleanup_eq_preset_window ()
{
+ // also hide the preset browser window
+ audgui_hide_unique_window (AUDGUI_PRESET_BROWSER_WINDOW);
+
if (changes_made)
{
save_list ();
@@ -312,22 +315,14 @@ static void merge_presets (const Index<EqualizerPreset> & presets)
EXPORT void audgui_import_eq_presets (const Index<EqualizerPreset> & presets)
{
- if (list)
- {
- /* import via presets window if it exists */
- audgui_list_delete_rows (list, 0, preset_list.len ());
- merge_presets (presets);
- audgui_list_insert_rows (list, 0, preset_list.len ());
+ // make sure the presets window is displayed
+ if (! list)
+ return;
- changes_made = true;
- gtk_widget_set_sensitive (revert, true);
- }
- else
- {
- /* otherwise import directly to ~/.config/audacious/eq.preset */
- populate_list ();
- merge_presets (presets);
- save_list ();
- preset_list.clear ();
- }
+ audgui_list_delete_rows (list, 0, preset_list.len ());
+ merge_presets (presets);
+ audgui_list_insert_rows (list, 0, preset_list.len ());
+
+ changes_made = true;
+ gtk_widget_set_sensitive (revert, true);
}
diff --git a/src/libaudgui/infowin.cc b/src/libaudgui/infowin.cc
index b36c1a6..8f62856 100644
--- a/src/libaudgui/infowin.cc
+++ b/src/libaudgui/infowin.cc
@@ -141,22 +141,32 @@ static GtkWidget * small_label_new (const char * text)
}
static void set_entry_str_from_field (GtkWidget * widget, const Tuple & tuple,
- Tuple::Field field, bool editable, bool clear)
+ Tuple::Field field, bool editable, bool clear, bool & changed)
{
String text = tuple.get_str (field);
+
if (! text && ! clear)
+ {
+ if (gtk_entry_get_text_length ((GtkEntry *) widget) > 0)
+ changed = true;
return;
+ }
gtk_entry_set_text ((GtkEntry *) widget, text ? text : "");
gtk_editable_set_editable ((GtkEditable *) widget, editable);
}
static void set_entry_int_from_field (GtkWidget * widget, const Tuple & tuple,
- Tuple::Field field, bool editable, bool clear)
+ Tuple::Field field, bool editable, bool clear, bool & changed)
{
int value = tuple.get_int (field);
+
if (value <= 0 && ! clear)
+ {
+ if (gtk_entry_get_text_length ((GtkEntry *) widget) > 0)
+ changed = true;
return;
+ }
gtk_entry_set_text ((GtkEntry *) widget, (value > 0) ? (const char *) int_to_str (value) : "");
gtk_editable_set_editable ((GtkEditable *) widget, editable);
@@ -424,19 +434,20 @@ static void infowin_show (Playlist list, int entry, const String & filename,
can_write = writable;
bool clear = aud_get_bool ("audgui", "clear_song_fields");
+ bool changed = false;
- set_entry_str_from_field (widgets.title, tuple, Tuple::Title, writable, clear);
- set_entry_str_from_field (widgets.artist, tuple, Tuple::Artist, writable, clear);
- set_entry_str_from_field (widgets.album, tuple, Tuple::Album, writable, clear);
- set_entry_str_from_field (widgets.album_artist, tuple, Tuple::AlbumArtist, writable, clear);
- set_entry_str_from_field (widgets.comment, tuple, Tuple::Comment, writable, clear);
+ set_entry_str_from_field (widgets.title, tuple, Tuple::Title, writable, clear, changed);
+ set_entry_str_from_field (widgets.artist, tuple, Tuple::Artist, writable, clear, changed);
+ set_entry_str_from_field (widgets.album, tuple, Tuple::Album, writable, clear, changed);
+ set_entry_str_from_field (widgets.album_artist, tuple, Tuple::AlbumArtist, writable, clear, changed);
+ set_entry_str_from_field (widgets.comment, tuple, Tuple::Comment, writable, clear, changed);
set_entry_str_from_field (gtk_bin_get_child ((GtkBin *) widgets.genre),
- tuple, Tuple::Genre, writable, clear);
+ tuple, Tuple::Genre, writable, clear, changed);
gtk_label_set_text ((GtkLabel *) widgets.location, uri_to_display (filename));
- set_entry_int_from_field (widgets.year, tuple, Tuple::Year, writable, clear);
- set_entry_int_from_field (widgets.track, tuple, Tuple::Track, writable, clear);
+ set_entry_int_from_field (widgets.year, tuple, Tuple::Year, writable, clear, changed);
+ set_entry_int_from_field (widgets.track, tuple, Tuple::Track, writable, clear, changed);
String codec_values[CODEC_ITEMS];
@@ -455,9 +466,7 @@ static void infowin_show (Playlist list, int entry, const String & filename,
infowin_display_image (filename);
- /* nothing has been changed yet */
- gtk_widget_set_sensitive (widgets.apply, false);
-
+ gtk_widget_set_sensitive (widgets.apply, changed);
gtk_widget_grab_focus (widgets.title);
if (! audgui_reshow_unique_window (AUDGUI_INFO_WINDOW))
diff --git a/src/libaudqt/audqt.cc b/src/libaudqt/audqt.cc
index d44df33..0677b96 100644
--- a/src/libaudqt/audqt.cc
+++ b/src/libaudqt/audqt.cc
@@ -102,7 +102,7 @@ EXPORT void cleanup ()
aboutwindow_hide ();
equalizer_hide ();
- infopopup_hide ();
+ infopopup_hide_now ();
infowin_hide ();
log_inspector_hide ();
prefswin_hide ();
diff --git a/src/libaudqt/infopopup-qt.cc b/src/libaudqt/infopopup-qt.cc
index fdbba41..de6d7b7 100644
--- a/src/libaudqt/infopopup-qt.cc
+++ b/src/libaudqt/infopopup-qt.cc
@@ -176,7 +176,9 @@ static InfoPopup * s_infopopup;
static void infopopup_show (const String & filename, const Tuple & tuple)
{
- delete s_infopopup;
+ if (s_infopopup)
+ s_infopopup->deleteLater ();
+
s_infopopup = new InfoPopup (filename, tuple);
QObject::connect (s_infopopup, & QObject::destroyed, [] () {
@@ -206,6 +208,16 @@ EXPORT void infopopup_show_current ()
EXPORT void infopopup_hide ()
{
+ /* This function can be called from an enter/leave event, and Qt does not
+ * like widgets being deleted from such events. This is debatably a bug in
+ * Qt, but deleteLater() is an effective workaround. */
+ if (s_infopopup)
+ s_infopopup->deleteLater ();
+}
+
+void infopopup_hide_now ()
+{
+ /* On exit, we really do want to delete the widget immediately. */
delete s_infopopup;
}
diff --git a/src/libaudqt/libaudqt-internal.h b/src/libaudqt/libaudqt-internal.h
index 2aec88f..19dded2 100644
--- a/src/libaudqt/libaudqt-internal.h
+++ b/src/libaudqt/libaudqt-internal.h
@@ -28,6 +28,9 @@ class QString;
namespace audqt {
+/* infopopup.cc */
+void infopopup_hide_now ();
+
/* log-inspector.cc */
void log_init ();
void log_cleanup ();
@@ -35,7 +38,11 @@ void log_cleanup ();
/* util-qt.cc */
class PopupWidget : public QWidget
{
+public:
+ PopupWidget (QWidget * parent = nullptr);
+
protected:
+ bool eventFilter (QObject *, QEvent * e) override;
void showEvent (QShowEvent *) override;
};
diff --git a/src/libaudqt/util-qt.cc b/src/libaudqt/util-qt.cc
index 213e983..866f3a4 100644
--- a/src/libaudqt/util-qt.cc
+++ b/src/libaudqt/util-qt.cc
@@ -33,6 +33,38 @@
namespace audqt {
+PopupWidget::PopupWidget (QWidget * parent) :
+ QWidget (parent)
+{
+ qApp->installEventFilter (this);
+}
+
+// This event filter mimics QToolTip by hiding the popup widget when
+// certain events are received by any widget.
+bool PopupWidget::eventFilter (QObject *, QEvent * e)
+{
+ switch (e->type ())
+ {
+ case QEvent::Leave:
+ case QEvent::WindowActivate:
+ case QEvent::WindowDeactivate:
+ case QEvent::FocusIn:
+ case QEvent::FocusOut:
+ case QEvent::Close:
+ case QEvent::MouseButtonPress:
+ case QEvent::MouseButtonRelease:
+ case QEvent::MouseButtonDblClick:
+ case QEvent::Wheel:
+ deleteLater ();
+ break;
+
+ default:
+ break;
+ }
+
+ return false;
+}
+
void PopupWidget::showEvent (QShowEvent *)
{
auto pos = QCursor::pos ();
diff --git a/src/libaudqt/volumebutton.cc b/src/libaudqt/volumebutton.cc
index 673002d..9455c55 100644
--- a/src/libaudqt/volumebutton.cc
+++ b/src/libaudqt/volumebutton.cc
@@ -121,7 +121,9 @@ void VolumeButton::showSlider ()
int dy = container_size.height () / 2 - button_size.height () / 2;
QPoint pos = mapToGlobal (QPoint (0, 0));
- pos += QPoint (-dx, -dy);
+ pos -= QPoint (dx, dy);
+ pos.setX(qMax(pos.x(), 0));
+ pos.setY(qMax(pos.y(), 0));
m_container->move (pos);
window_bring_to_front (m_container);