summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMateusz Łukasik <mati75@linuxmint.pl>2016-09-27 23:00:10 +0200
committerMateusz Łukasik <mati75@linuxmint.pl>2016-09-27 23:00:10 +0200
commitdd85ec05d263a006bab6d1da553482aac969cde3 (patch)
tree5d818c6bfe154320f95fb48f840dc17130e70774 /src
parentee3770c3849e4aa9702432e7b83646b5a33ed82a (diff)
New upstream version 3.8
Diffstat (limited to 'src')
-rw-r--r--src/audacious/audacious.manifest8
-rw-r--r--src/audacious/audacious.rc4
-rw-r--r--src/libaudcore/Makefile1
-rw-r--r--src/libaudcore/audio.cc11
-rw-r--r--src/libaudcore/output.cc8
-rw-r--r--src/libaudcore/parse.cc51
-rw-r--r--src/libaudcore/parse.h48
-rw-r--r--src/libaudcore/playlist.cc64
-rw-r--r--src/libaudcore/plugin-registry.cc135
-rw-r--r--src/libaudcore/tests/test.cc5
-rw-r--r--src/libaudgui/Makefile2
-rw-r--r--src/libaudgui/init.cc6
-rw-r--r--src/libaudgui/libaudgui-gtk.h2
-rw-r--r--src/libaudgui/util.cc66
14 files changed, 261 insertions, 150 deletions
diff --git a/src/audacious/audacious.manifest b/src/audacious/audacious.manifest
new file mode 100644
index 0000000..1fc9cfd
--- /dev/null
+++ b/src/audacious/audacious.manifest
@@ -0,0 +1,8 @@
+<?xml version='1.0' encoding='UTF-8' standalone='yes'?>
+<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
+ <asmv3:application xmlns:asmv3="urn:schemas-microsoft-com:asm.v3">
+ <asmv3:windowsSettings xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">
+ <dpiAware>true</dpiAware>
+ </asmv3:windowsSettings>
+ </asmv3:application>
+</assembly>
diff --git a/src/audacious/audacious.rc b/src/audacious/audacious.rc
index c7b9839..89c09e3 100644
--- a/src/audacious/audacious.rc
+++ b/src/audacious/audacious.rc
@@ -2,6 +2,6 @@
LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
-#define IDI_ICON_AUDACIOUS 102
+CREATEPROCESS_MANIFEST_RESOURCE_ID RT_MANIFEST "audacious.manifest"
-IDI_ICON_AUDACIOUS ICON "../../images/audacious.ico"
+100 ICON "../../images/audacious.ico"
diff --git a/src/libaudcore/Makefile b/src/libaudcore/Makefile
index 68768ed..dde7284 100644
--- a/src/libaudcore/Makefile
+++ b/src/libaudcore/Makefile
@@ -26,6 +26,7 @@ SRCS = adder.cc \
mainloop.cc \
multihash.cc \
output.cc \
+ parse.cc \
playback.cc \
playlist.cc \
playlist-cache.cc \
diff --git a/src/libaudcore/audio.cc b/src/libaudcore/audio.cc
index 0e56d2b..6b20f5d 100644
--- a/src/libaudcore/audio.cc
+++ b/src/libaudcore/audio.cc
@@ -125,8 +125,11 @@ EXPORT void audio_deinterlace (const void * in, int format, int channels,
static void NAME (const TYPE * in, float * out, int samples) \
{ \
const TYPE * end = in + samples; \
- while (in < end) \
- * out ++ = (TYPE) (SWAP (* in ++) - OFFSET) * (1.0f / RANGE); \
+ while (in < end) { \
+ TYPE value = SWAP (* in ++) + (RANGE - OFFSET); \
+ if (RANGE == 0x800000) value &= 0xffffff; /* ignore high byte */ \
+ * out ++ = (TYPE) (value - RANGE) * (1.0f / RANGE); \
+ } \
}
#define TO_INT_LOOP(NAME, TYPE, SWAP, OFFSET, RANGE, RANGE_P) \
@@ -136,7 +139,9 @@ static void NAME (const float * in, TYPE * out, int samples) \
while (in < end) \
{ \
float f = (* in ++) * RANGE; \
- * out ++ = SWAP (OFFSET + (TYPE) lrintf (aud::clamp (f, -(float) RANGE, (float) RANGE_P))); \
+ TYPE value = OFFSET + TYPE (lrintf (aud::clamp (f, -(float) RANGE, (float) RANGE_P))); \
+ if (RANGE == 0x800000) value &= 0xffffff; /* zero high byte */ \
+ * out ++ = SWAP (value); \
} \
}
diff --git a/src/libaudcore/output.cc b/src/libaudcore/output.cc
index 4ac6ab4..abb3c7f 100644
--- a/src/libaudcore/output.cc
+++ b/src/libaudcore/output.cc
@@ -181,13 +181,9 @@ static void setup_output (bool new_input)
cleanup_output ();
cop->set_info (in_filename, in_tuple);
- String error, tmp_error;
- while (! cop->open_audio (format, effect_rate, effect_channels, tmp_error))
+ String error;
+ while (! cop->open_audio (format, effect_rate, effect_channels, error))
{
- /* display only the error from the first attempt */
- if (! automatic || format == FMT_FLOAT)
- error = std::move (tmp_error);
-
if (automatic && format == FMT_FLOAT)
format = FMT_S32_NE;
else if (automatic && format == FMT_S32_NE)
diff --git a/src/libaudcore/parse.cc b/src/libaudcore/parse.cc
new file mode 100644
index 0000000..9450e72
--- /dev/null
+++ b/src/libaudcore/parse.cc
@@ -0,0 +1,51 @@
+/*
+ * parse.cc
+ * Copyright 2016 John Lindgren
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions, and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions, and the following disclaimer in the documentation
+ * provided with the distribution.
+ *
+ * This software is provided "as is" and without any warranty, express or
+ * implied. In no event shall the authors be liable for any damages arising from
+ * the use of this software.
+ */
+
+#include "parse.h"
+#include <string.h>
+
+void TextParser::next ()
+{
+ m_val = nullptr;
+
+ if (! fgets (m_key, sizeof m_key, m_file))
+ return;
+
+ char * space = strchr (m_key, ' ');
+ if (! space)
+ return;
+
+ * space = 0;
+ m_val = space + 1;
+
+ char * newline = strchr (m_val, '\n');
+ if (newline)
+ * newline = 0;
+}
+
+bool TextParser::get_int (const char * key, int & val) const
+{
+ return (m_val && ! strcmp (m_key, key) && sscanf (m_val, "%d", & val) == 1);
+}
+
+String TextParser::get_str (const char * key) const
+{
+ return (m_val && ! strcmp (m_key, key)) ? String (m_val) : String ();
+}
+
diff --git a/src/libaudcore/parse.h b/src/libaudcore/parse.h
new file mode 100644
index 0000000..0dc63e4
--- /dev/null
+++ b/src/libaudcore/parse.h
@@ -0,0 +1,48 @@
+/*
+ * parse.h
+ * Copyright 2016 John Lindgren
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions, and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions, and the following disclaimer in the documentation
+ * provided with the distribution.
+ *
+ * This software is provided "as is" and without any warranty, express or
+ * implied. In no event shall the authors be liable for any damages arising from
+ * the use of this software.
+ */
+
+#ifndef LIBAUDCORE_PARSE_H
+#define LIBAUDCORE_PARSE_H
+
+#include <stdio.h>
+#include "objects.h"
+
+// simplistic key-value file parser
+// used for playlist-state and plugin-registry files
+class TextParser
+{
+public:
+ TextParser (FILE * file) :
+ m_file (file)
+ { next (); }
+
+ void next ();
+ bool eof () const
+ { return ! m_val; }
+
+ bool get_int (const char * key, int & val) const;
+ String get_str (const char * key) const;
+
+private:
+ FILE * m_file;
+ char * m_val;
+ char m_key[512];
+};
+
+#endif // LIBAUDCORE_PARSE_H
diff --git a/src/libaudcore/playlist.cc b/src/libaudcore/playlist.cc
index 9bfc718..f2bd034 100644
--- a/src/libaudcore/playlist.cc
+++ b/src/libaudcore/playlist.cc
@@ -41,6 +41,7 @@
#include "mainloop.h"
#include "multihash.h"
#include "objects.h"
+#include "parse.h"
#include "plugins.h"
#include "scanner.h"
#include "tuple.h"
@@ -120,7 +121,6 @@ struct Entry {
int number;
int length;
int shuffle_num;
- bool scanned, failed;
bool selected, queued;
};
@@ -2287,38 +2287,6 @@ void playlist_save_state ()
LEAVE;
}
-static char parse_key[512];
-static char * parse_value;
-
-static void parse_next (FILE * handle)
-{
- parse_value = nullptr;
-
- if (! fgets (parse_key, sizeof parse_key, handle))
- return;
-
- char * space = strchr (parse_key, ' ');
- if (! space)
- return;
-
- * space = 0;
- parse_value = space + 1;
-
- char * newline = strchr (parse_value, '\n');
- if (newline)
- * newline = 0;
-}
-
-static bool parse_integer (const char * key, int * value)
-{
- return (parse_value && ! strcmp (parse_key, key) && sscanf (parse_value, "%d", value) == 1);
-}
-
-static String parse_string (const char * key)
-{
- return (parse_value && ! strcmp (parse_key, key)) ? String (parse_value) : String ();
-}
-
void playlist_load_state ()
{
ENTER;
@@ -2331,41 +2299,41 @@ void playlist_load_state ()
if (! handle)
RETURN ();
- parse_next (handle);
+ TextParser parser (handle);
- if (parse_integer ("active", & playlist_num))
+ if (parser.get_int ("active", playlist_num))
{
if (! (active_playlist = lookup_playlist (playlist_num)))
active_playlist = playlists[0].get ();
- parse_next (handle);
+ parser.next ();
}
- if (parse_integer ("playing", & resume_playlist))
- parse_next (handle);
+ if (parser.get_int ("playing", resume_playlist))
+ parser.next ();
- while (parse_integer ("playlist", & playlist_num) && playlist_num >= 0 &&
+ while (parser.get_int ("playlist", playlist_num) && playlist_num >= 0 &&
playlist_num < playlists.len ())
{
PlaylistData * playlist = playlists[playlist_num].get ();
int entries = playlist->entries.len ();
- parse_next (handle);
+ parser.next ();
- playlist->filename = parse_string ("filename");
+ playlist->filename = parser.get_str ("filename");
if (playlist->filename)
- parse_next (handle);
+ parser.next ();
int position = -1;
- if (parse_integer ("position", & position))
- parse_next (handle);
+ if (parser.get_int ("position", position))
+ parser.next ();
if (position >= 0 && position < entries)
set_position (playlist, playlist->entries [position].get (), true);
/* resume state is stored per-playlist for historical reasons */
int resume_state = ResumePlay;
- if (parse_integer ("resume-state", & resume_state))
- parse_next (handle);
+ if (parser.get_int ("resume-state", resume_state))
+ parser.next ();
if (playlist_num == resume_playlist)
{
@@ -2375,8 +2343,8 @@ void playlist_load_state ()
resume_paused = true;
}
- if (parse_integer ("resume-time", & playlist->resume_time))
- parse_next (handle);
+ if (parser.get_int ("resume-time", playlist->resume_time))
+ parser.next ();
}
fclose (handle);
diff --git a/src/libaudcore/plugin-registry.cc b/src/libaudcore/plugin-registry.cc
index 00114a9..cdeed7e 100644
--- a/src/libaudcore/plugin-registry.cc
+++ b/src/libaudcore/plugin-registry.cc
@@ -28,6 +28,7 @@
#include "audstrings.h"
#include "i18n.h"
#include "interface.h"
+#include "parse.h"
#include "plugin.h"
#include "runtime.h"
@@ -212,89 +213,57 @@ void plugin_registry_save ()
fclose (handle);
}
-static char parse_key[512];
-static char * parse_value;
-
-static void parse_next (FILE * handle)
-{
- parse_value = nullptr;
-
- if (! fgets (parse_key, sizeof parse_key, handle))
- return;
-
- char * space = strchr (parse_key, ' ');
- if (! space)
- return;
-
- * space = 0;
- parse_value = space + 1;
-
- char * newline = strchr (parse_value, '\n');
- if (newline)
- * newline = 0;
-}
-
-static bool parse_integer (const char * key, int * value)
-{
- return (parse_value && ! strcmp (parse_key, key) && sscanf (parse_value, "%d", value) == 1);
-}
-
-static String parse_string (const char * key)
-{
- return (parse_value && ! strcmp (parse_key, key)) ? String (parse_value) : String ();
-}
-
-static void transport_plugin_parse (PluginHandle * plugin, FILE * handle)
+static void transport_plugin_parse (PluginHandle * plugin, TextParser & parser)
{
while (1)
{
- String value = parse_string ("scheme");
+ String value = parser.get_str ("scheme");
if (! value)
break;
plugin->schemes.append (std::move (value));
- parse_next (handle);
+ parser.next ();
}
}
-static void playlist_plugin_parse (PluginHandle * plugin, FILE * handle)
+static void playlist_plugin_parse (PluginHandle * plugin, TextParser & parser)
{
while (1)
{
- String value = parse_string ("ext");
+ String value = parser.get_str ("ext");
if (! value)
break;
plugin->exts.append (std::move (value));
- parse_next (handle);
+ parser.next ();
}
- if (parse_integer ("saves", & plugin->can_save))
- parse_next (handle);
+ if (parser.get_int ("saves", plugin->can_save))
+ parser.next ();
}
-static void input_plugin_parse (PluginHandle * plugin, FILE * handle)
+static void input_plugin_parse (PluginHandle * plugin, TextParser & parser)
{
for (auto key : aud::range<InputKey> ())
{
while (1)
{
- String value = parse_string (input_key_names[key]);
+ String value = parser.get_str (input_key_names[key]);
if (! value)
break;
plugin->keys[key].append (std::move (value));
- parse_next (handle);
+ parser.next ();
}
}
- if (parse_integer ("subtunes", & plugin->has_subtunes))
- parse_next (handle);
- if (parse_integer ("writes", & plugin->writes_tag))
- parse_next (handle);
+ if (parser.get_int ("subtunes", plugin->has_subtunes))
+ parser.next ();
+ if (parser.get_int ("writes", plugin->writes_tag))
+ parser.next ();
}
-static bool plugin_parse (FILE * handle)
+static bool plugin_parse (TextParser & parser)
{
PluginType type;
String path;
@@ -302,7 +271,7 @@ static bool plugin_parse (FILE * handle)
for (auto type2 : aud::range<PluginType> ())
{
type = type2;
- if ((path = parse_string (plugin_type_names[type2])))
+ if ((path = parser.get_str (plugin_type_names[type2])))
break;
}
@@ -313,61 +282,61 @@ static bool plugin_parse (FILE * handle)
if (! basename)
return false;
- parse_next (handle);
+ parser.next ();
int timestamp;
- if (! parse_integer ("stamp", & timestamp))
+ if (! parser.get_int ("stamp", timestamp))
return false;
- parse_next (handle);
+ parser.next ();
int version = 0, flags = 0;
- if (parse_integer ("version", & version))
- parse_next (handle);
- if (parse_integer ("flags", & flags))
- parse_next (handle);
+ if (parser.get_int ("version", version))
+ parser.next ();
+ if (parser.get_int ("flags", flags))
+ parser.next ();
auto plugin = new PluginHandle (basename, String (), false, timestamp,
version, flags, type, nullptr);
plugins[type].append (plugin);
- plugin->name = parse_string ("name");
+ plugin->name = parser.get_str ("name");
if (plugin->name)
- parse_next (handle);
+ parser.next ();
- plugin->domain = parse_string ("domain");
+ plugin->domain = parser.get_str ("domain");
if (plugin->domain)
- parse_next (handle);
+ parser.next ();
- if (parse_integer ("priority", & plugin->priority))
- parse_next (handle);
- if (parse_integer ("about", & plugin->has_about))
- parse_next (handle);
- if (parse_integer ("config", & plugin->has_configure))
- parse_next (handle);
+ if (parser.get_int ("priority", plugin->priority))
+ parser.next ();
+ if (parser.get_int ("about", plugin->has_about))
+ parser.next ();
+ if (parser.get_int ("config", plugin->has_configure))
+ parser.next ();
int enabled;
- if (parse_integer ("enabled", & enabled))
+ if (parser.get_int ("enabled", enabled))
{
plugin->enabled = (PluginEnabled) enabled;
- parse_next (handle);
+ parser.next ();
}
if (type == PluginType::Transport)
- transport_plugin_parse (plugin, handle);
+ transport_plugin_parse (plugin, parser);
else if (type == PluginType::Playlist)
- playlist_plugin_parse (plugin, handle);
+ playlist_plugin_parse (plugin, parser);
else if (type == PluginType::Input)
- input_plugin_parse (plugin, handle);
+ input_plugin_parse (plugin, parser);
return true;
}
/* try to migrate enabled status from another version */
-static void parse_plugins_fallback (FILE * handle)
+static void parse_plugins_fallback (TextParser & parser)
{
- for (; parse_value; parse_next (handle))
+ for (; ! parser.eof (); parser.next ())
{
PluginType type;
String path;
@@ -376,7 +345,7 @@ static void parse_plugins_fallback (FILE * handle)
for (auto type2 : aud::range<PluginType> ())
{
type = type2;
- if ((path = parse_string (plugin_type_names[type2])))
+ if ((path = parser.get_str (plugin_type_names[type2])))
break;
}
@@ -387,15 +356,15 @@ static void parse_plugins_fallback (FILE * handle)
if (! basename)
continue;
- parse_next (handle);
+ parser.next ();
- for (; parse_value; parse_next (handle))
+ for (; ! parser.eof (); parser.next ())
{
- if (parse_integer ("enabled", & enabled))
+ if (parser.get_int ("enabled", enabled))
break;
}
- if (! parse_value)
+ if (parser.eof ())
return;
// setting timestamp to zero forces a rescan
@@ -411,21 +380,21 @@ void plugin_registry_load ()
if (! handle)
return;
- parse_next (handle);
+ TextParser parser (handle);
int format;
- if (! parse_integer ("format", & format))
+ if (! parser.get_int ("format", format))
goto ERR;
- parse_next (handle);
+ parser.next ();
if (format == FORMAT)
{
- while (plugin_parse (handle))
+ while (plugin_parse (parser))
continue;
}
else if (format >= MIN_FORMAT && format < FORMAT + 10)
- parse_plugins_fallback (handle);
+ parse_plugins_fallback (parser);
ERR:
fclose (handle);
diff --git a/src/libaudcore/tests/test.cc b/src/libaudcore/tests/test.cc
index 3d33332..dac2724 100644
--- a/src/libaudcore/tests/test.cc
+++ b/src/libaudcore/tests/test.cc
@@ -33,8 +33,9 @@
static void test_audio_conversion ()
{
/* single precision float should be lossless for 24-bit audio */
+ /* also test that high byte is correctly ignored/zeroed */
static const int32_t in[10] =
- {-0x800000, -0x7fffff, -0x7ffffe, -2, -1, 0, 1, 2, 0x7ffffe, 0x7fffff};
+ {0x800000, 0x800001, 0x800002, -2, -1, 0, 1, 2, 0x7ffffe, 0x7fffff};
float f[10];
int32_t out[10];
@@ -46,7 +47,7 @@ static void test_audio_conversion ()
assert (f[5] == 0.0f);
for (int i = 0; i < 10; i ++)
- assert (in[i] == out[i]);
+ assert (out[i] == (in[i] & 0xffffff));
}
static void test_numeric_conversion ()
diff --git a/src/libaudgui/Makefile b/src/libaudgui/Makefile
index dde93e1..2ef4ed3 100644
--- a/src/libaudgui/Makefile
+++ b/src/libaudgui/Makefile
@@ -1,6 +1,6 @@
SHARED_LIB = ${LIB_PREFIX}audgui${LIB_SUFFIX}
LIB_MAJOR = 4
-LIB_MINOR = 0
+LIB_MINOR = 1
SRCS = about.cc \
confirm.cc \
diff --git a/src/libaudgui/init.cc b/src/libaudgui/init.cc
index ede7414..b6192fd 100644
--- a/src/libaudgui/init.cc
+++ b/src/libaudgui/init.cc
@@ -67,6 +67,9 @@ static gboolean configure_cb (GtkWidget * window, GdkEventConfigure * event, con
gtk_window_get_position ((GtkWindow *) window, & pos[0], & pos[1]);
gtk_window_get_size ((GtkWindow *) window, & pos[2], & pos[3]);
+ pos[2] = audgui_to_portable_dpi (pos[2]);
+ pos[3] = audgui_to_portable_dpi (pos[3]);
+
aud_set_str ("audgui", name, int_array_to_str (pos, 4));
}
@@ -90,6 +93,9 @@ void audgui_show_unique_window (int id, GtkWidget * widget)
if (str_to_int_array (str, pos, 4))
{
+ pos[2] = audgui_to_native_dpi (pos[2]);
+ pos[3] = audgui_to_native_dpi (pos[3]);
+
gtk_window_move ((GtkWindow *) widget, pos[0], pos[1]);
gtk_window_set_default_size ((GtkWindow *) widget, pos[2], pos[3]);
}
diff --git a/src/libaudgui/libaudgui-gtk.h b/src/libaudgui/libaudgui-gtk.h
index 8bd8c08..a789a6b 100644
--- a/src/libaudgui/libaudgui-gtk.h
+++ b/src/libaudgui/libaudgui-gtk.h
@@ -52,6 +52,8 @@ void audgui_scaled_image_set (GtkWidget * widget, GdkPixbuf * pixbuf);
/* util.c -- okay to use without audgui_init() */
int audgui_get_dpi ();
+int audgui_to_native_dpi (int size);
+int audgui_to_portable_dpi (int size);
int audgui_get_digit_width (GtkWidget * widget);
void audgui_get_mouse_coords (GtkWidget * widget, int * x, int * y);
void audgui_get_mouse_coords (GdkScreen * screen, int * x, int * y);
diff --git a/src/libaudgui/util.cc b/src/libaudgui/util.cc
index 98307e5..79f8727 100644
--- a/src/libaudgui/util.cc
+++ b/src/libaudgui/util.cc
@@ -20,6 +20,10 @@
#include <math.h>
#include <string.h>
+#ifdef _WIN32
+#include <windows.h>
+#endif
+
#include <gdk/gdkkeysyms.h>
#include <gtk/gtk.h>
@@ -32,25 +36,43 @@
#include "libaudgui.h"
#include "libaudgui-gtk.h"
+#define PORTABLE_DPI 96
+
EXPORT int audgui_get_dpi ()
{
static int dpi = 0;
if (! dpi)
{
+#ifdef _WIN32
+ HDC screen = GetDC (nullptr);
+ dpi = (GetDeviceCaps (screen, LOGPIXELSX) + GetDeviceCaps (screen, LOGPIXELSY)) / 2;
+ ReleaseDC (nullptr, screen);
+#else
GdkScreen * screen = gdk_screen_get_default ();
/* force GTK settings to be loaded for the GDK screen */
(void) gtk_settings_get_for_screen (screen);
dpi = round (gdk_screen_get_resolution (screen));
- if (dpi < 1)
- dpi = 96;
+#endif
+
+ dpi = aud::max (PORTABLE_DPI, dpi);
}
return dpi;
}
+EXPORT int audgui_to_native_dpi (int size)
+{
+ return aud::rescale (size, PORTABLE_DPI, audgui_get_dpi ());
+}
+
+EXPORT int audgui_to_portable_dpi (int size)
+{
+ return aud::rescale (size, audgui_get_dpi (), PORTABLE_DPI);
+}
+
EXPORT int audgui_get_digit_width (GtkWidget * widget)
{
int width;
@@ -233,6 +255,39 @@ EXPORT void audgui_dialog_add_widget (GtkWidget * dialog, GtkWidget * widget)
gtk_box_pack_start ((GtkBox *) box, widget, false, false, 0);
}
+static StringBuf ellipsize (const char * text)
+{
+ constexpr int maxword = 100;
+
+ StringBuf buf = str_copy (text);
+ int start = 0;
+
+ while (1)
+ {
+ while (buf[start] && g_ascii_isspace (buf[start]))
+ start ++;
+
+ if (! buf[start])
+ break;
+
+ int stop = start + 1;
+ while (buf[stop] && ! g_ascii_isspace (buf[stop]))
+ stop ++;
+
+ if (stop - start > maxword)
+ {
+ buf.remove (start + maxword / 2, stop - start - maxword);
+ buf.insert (start + maxword / 2, "…");
+
+ stop = start + maxword + strlen ("…");
+ }
+
+ start = stop;
+ }
+
+ return buf;
+}
+
EXPORT void audgui_simple_message (GtkWidget * * widget, GtkMessageType type,
const char * title, const char * text)
{
@@ -253,9 +308,10 @@ EXPORT void audgui_simple_message (GtkWidget * * widget, GtkMessageType type,
if (messages > 10)
text = _("\n(Further messages have been hidden.)");
- if (! strstr (old, text))
+ StringBuf shortened = ellipsize (text);
+ if (! strstr (old, shortened))
{
- StringBuf both = str_concat ({old, "\n", text});
+ StringBuf both = str_concat ({old, "\n", shortened});
g_object_set ((GObject *) * widget, "text", (const char *) both, nullptr);
g_object_set_data ((GObject *) * widget, "messages", GINT_TO_POINTER (messages + 1));
}
@@ -266,7 +322,7 @@ EXPORT void audgui_simple_message (GtkWidget * * widget, GtkMessageType type,
else
{
GtkWidget * button = audgui_button_new (_("_Close"), "window-close", nullptr, nullptr);
- * widget = audgui_dialog_new (type, title, text, button, nullptr);
+ * widget = audgui_dialog_new (type, title, ellipsize (text), button, nullptr);
g_object_set_data ((GObject *) * widget, "messages", GINT_TO_POINTER (1));
g_signal_connect (* widget, "destroy", (GCallback) gtk_widget_destroyed, widget);