mirror of
https://github.com/Rafostar/clapper.git
synced 2025-08-29 15:22:11 +02:00
Compare commits
6 Commits
b9e98e2fdb
...
crowdin_sy
Author | SHA1 | Date | |
---|---|---|---|
|
aa0be37cb9 | ||
|
9aee805b6d | ||
|
6ee406c11d | ||
|
fcc41b2e9c | ||
|
fb8ee8497a | ||
|
3ba2611901 |
31
COPYING-LGPL
31
COPYING-LGPL
@@ -2,7 +2,7 @@
|
||||
Version 2.1, February 1999
|
||||
|
||||
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
|
||||
<https://fsf.org/>
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
@@ -55,7 +55,7 @@ modified by someone else and passed on, the recipients should know
|
||||
that what they have is not the original version, so that the original
|
||||
author's reputation will not be affected by problems that might be
|
||||
introduced by others.
|
||||
|
||||
|
||||
Finally, software patents pose a constant threat to the existence of
|
||||
any free program. We wish to make sure that a company cannot
|
||||
effectively restrict the users of a free program by obtaining a
|
||||
@@ -111,7 +111,7 @@ modification follow. Pay close attention to the difference between a
|
||||
"work based on the library" and a "work that uses the library". The
|
||||
former contains code derived from the library, whereas the latter must
|
||||
be combined with the library in order to run.
|
||||
|
||||
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
@@ -158,7 +158,7 @@ Library.
|
||||
You may charge a fee for the physical act of transferring a copy,
|
||||
and you may at your option offer warranty protection in exchange for a
|
||||
fee.
|
||||
|
||||
|
||||
2. You may modify your copy or copies of the Library or any portion
|
||||
of it, thus forming a work based on the Library, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
@@ -216,7 +216,7 @@ instead of to this License. (If a newer version than version 2 of the
|
||||
ordinary GNU General Public License has appeared, then you can specify
|
||||
that version instead if you wish.) Do not make any other change in
|
||||
these notices.
|
||||
|
||||
|
||||
Once this change is made in a given copy, it is irreversible for
|
||||
that copy, so the ordinary GNU General Public License applies to all
|
||||
subsequent copies and derivative works made from that copy.
|
||||
@@ -267,7 +267,7 @@ Library will still fall under Section 6.)
|
||||
distribute the object code for the work under the terms of Section 6.
|
||||
Any executables containing that work also fall under Section 6,
|
||||
whether or not they are linked directly with the Library itself.
|
||||
|
||||
|
||||
6. As an exception to the Sections above, you may also combine or
|
||||
link a "work that uses the Library" with the Library to produce a
|
||||
work containing portions of the Library, and distribute that work
|
||||
@@ -329,7 +329,7 @@ restrictions of other proprietary libraries that do not normally
|
||||
accompany the operating system. Such a contradiction means you cannot
|
||||
use both them and the Library together in an executable that you
|
||||
distribute.
|
||||
|
||||
|
||||
7. You may place library facilities that are a work based on the
|
||||
Library side-by-side in a single library together with other library
|
||||
facilities not covered by this License, and distribute such a combined
|
||||
@@ -370,7 +370,7 @@ subject to these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties with
|
||||
this License.
|
||||
|
||||
|
||||
11. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
@@ -422,7 +422,7 @@ conditions either of that version or of any later version published by
|
||||
the Free Software Foundation. If the Library does not specify a
|
||||
license version number, you may choose any version ever published by
|
||||
the Free Software Foundation.
|
||||
|
||||
|
||||
14. If you wish to incorporate parts of the Library into other free
|
||||
programs whose distribution conditions are incompatible with these,
|
||||
write to the author to ask for permission. For software which is
|
||||
@@ -456,7 +456,7 @@ SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
||||
DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
|
||||
How to Apply These Terms to Your New Libraries
|
||||
|
||||
If you develop a new library, and you want it to be of the greatest
|
||||
@@ -484,7 +484,9 @@ convey the exclusion of warranty; and each file should have at least the
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, see <https://www.gnu.org/licenses/>.
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
|
||||
USA
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
@@ -493,9 +495,10 @@ school, if any, to sign a "copyright disclaimer" for the library, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the
|
||||
library `Frob' (a library for tweaking knobs) written by James Random Hacker.
|
||||
library `Frob' (a library for tweaking knobs) written by James Random
|
||||
Hacker.
|
||||
|
||||
<signature of Moe Ghoul>, 1 April 1990
|
||||
Moe Ghoul, President of Vice
|
||||
<signature of Ty Coon>, 1 April 1990
|
||||
Ty Coon, President of Vice
|
||||
|
||||
That's all there is to it!
|
||||
|
@@ -1,49 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import gi
|
||||
gi.require_version('Adw', '1')
|
||||
gi.require_version('Clapper', '0.0')
|
||||
gi.require_version('ClapperGtk', '0.0')
|
||||
gi.require_version('Gtk', '4.0')
|
||||
from gi.repository import Adw, Clapper, ClapperGtk, Gtk
|
||||
|
||||
Clapper.init(None)
|
||||
|
||||
def on_activate(app):
|
||||
# Create our widgets.
|
||||
win = Gtk.ApplicationWindow(application=app, title='Clapper Audio', default_width=640, default_height=96)
|
||||
audio = ClapperGtk.Audio()
|
||||
box = Gtk.Box(valign=Gtk.Align.CENTER, margin_start=8, margin_end=8, spacing=4)
|
||||
prev_btn = ClapperGtk.PreviousItemButton()
|
||||
play_btn = ClapperGtk.TogglePlayButton()
|
||||
next_btn = ClapperGtk.NextItemButton()
|
||||
seek_bar = ClapperGtk.SeekBar()
|
||||
|
||||
# Add media for playback. First media item in queue will be automatically selected.
|
||||
item = Clapper.MediaItem(uri='https://www.soundhelix.com/examples/mp3/SoundHelix-Song-1.mp3')
|
||||
audio.props.player.props.queue.add_item(item)
|
||||
|
||||
item = Clapper.MediaItem(uri='https://www.learningcontainer.com/wp-content/uploads/2020/02/Kalimba.mp3')
|
||||
audio.props.player.props.queue.add_item(item)
|
||||
|
||||
# Assemble window.
|
||||
box.append(prev_btn)
|
||||
box.append(play_btn)
|
||||
box.append(next_btn)
|
||||
box.append(seek_bar)
|
||||
audio.set_child(box)
|
||||
win.set_child(audio)
|
||||
win.present()
|
||||
|
||||
# Not too loud. Mind the ears.
|
||||
audio.props.player.props.volume = 0.7
|
||||
|
||||
# Start playback.
|
||||
audio.props.player.play()
|
||||
|
||||
# Create a new application.
|
||||
app = Adw.Application(application_id='com.example.ClapperAudio')
|
||||
app.connect('activate', on_activate)
|
||||
|
||||
# Run the application.
|
||||
app.run(None)
|
@@ -1,5 +1,5 @@
|
||||
project('clapper', 'c',
|
||||
version: '0.9.1',
|
||||
version: '0.9.0',
|
||||
meson_version: '>= 0.64.0',
|
||||
license: 'LGPL-2.1-or-later AND GPL-3.0-or-later', # LGPL-2.1+ for libs and gst-plugin, GPL-3.0+ for app
|
||||
default_options: [
|
||||
@@ -11,7 +11,7 @@ project('clapper', 'c',
|
||||
glib_req = '>= 2.76.0'
|
||||
gst_req = '>= 1.24.0'
|
||||
gtk4_req = '>= 4.10.0'
|
||||
adw_req = '>= 1.5.0'
|
||||
adw_req = '>= 1.4.0'
|
||||
|
||||
clapper_version = meson.project_version().split('-')[0]
|
||||
version_array = clapper_version.split('.')
|
||||
|
@@ -16,7 +16,7 @@
|
||||
"autodelete": false
|
||||
},
|
||||
"com.github.rafostar.Clapper.Enhancers": {
|
||||
"versions": "stable;test;master",
|
||||
"versions": "master;test;stable",
|
||||
"directory": "extensions/clapper/enhancers",
|
||||
"add-ld-path": "lib",
|
||||
"no-autodownload": false,
|
||||
|
@@ -12,7 +12,7 @@
|
||||
"autodelete": false
|
||||
},
|
||||
"com.github.rafostar.Clapper.Enhancers": {
|
||||
"versions": "stable;test;master",
|
||||
"versions": "master;test;stable",
|
||||
"directory": "extensions/clapper/enhancers",
|
||||
"add-ld-path": "lib",
|
||||
"no-autodownload": false,
|
||||
|
Submodule pkgs/flatpak/flathub updated: 3a672be190...f58477c356
@@ -642,6 +642,18 @@ clapper_app_application_command_line (GApplication *app, GApplicationCommandLine
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
_is_claps_file (GFile *file)
|
||||
{
|
||||
gchar *basename = g_file_get_basename (file);
|
||||
gboolean is_claps;
|
||||
|
||||
is_claps = (basename && g_str_has_suffix (basename, ".claps"));
|
||||
g_free (basename);
|
||||
|
||||
return is_claps;
|
||||
}
|
||||
|
||||
static void
|
||||
add_item_from_file (GFile *file, ClapperQueue *queue)
|
||||
{
|
||||
@@ -654,6 +666,51 @@ add_item_from_file (GFile *file, ClapperQueue *queue)
|
||||
gst_object_unref (item);
|
||||
}
|
||||
|
||||
static void
|
||||
add_items_from_claps_file (GFile *file, ClapperQueue *queue)
|
||||
{
|
||||
GDataInputStream *dstream = NULL;
|
||||
GFileInputStream *stream;
|
||||
GError *error = NULL;
|
||||
gchar *line;
|
||||
|
||||
if (!(stream = g_file_read (file, NULL, &error)))
|
||||
goto finish;
|
||||
|
||||
dstream = g_data_input_stream_new (G_INPUT_STREAM (stream));
|
||||
|
||||
while ((line = g_data_input_stream_read_line (
|
||||
dstream, NULL, NULL, &error))) {
|
||||
g_strstrip (line);
|
||||
|
||||
if (strlen (line) > 0) {
|
||||
GFile *tmp_file = gst_uri_is_valid (line)
|
||||
? g_file_new_for_uri (line)
|
||||
: g_file_new_for_path (line);
|
||||
|
||||
if (_is_claps_file (tmp_file))
|
||||
add_items_from_claps_file (tmp_file, queue);
|
||||
else
|
||||
add_item_from_file (tmp_file, queue);
|
||||
|
||||
g_object_unref (tmp_file);
|
||||
}
|
||||
|
||||
g_free (line);
|
||||
}
|
||||
|
||||
finish:
|
||||
if (error) {
|
||||
GST_ERROR ("Could not read \".claps\" file, reason: %s", error->message);
|
||||
g_error_free (error);
|
||||
}
|
||||
if (stream) {
|
||||
g_input_stream_close (G_INPUT_STREAM (stream), NULL, NULL);
|
||||
g_object_unref (stream);
|
||||
}
|
||||
g_clear_object (&dstream);
|
||||
}
|
||||
|
||||
static void
|
||||
add_item_with_subtitles (GFile *media_file,
|
||||
GFile *subs_file, ClapperQueue *queue)
|
||||
@@ -722,8 +779,12 @@ clapper_app_application_open (GApplication *app,
|
||||
if (!handled) {
|
||||
gint i;
|
||||
|
||||
for (i = 0; i < n_files; ++i)
|
||||
add_item_from_file (files[i], queue);
|
||||
for (i = 0; i < n_files; ++i) {
|
||||
if (_is_claps_file (files[i]))
|
||||
add_items_from_claps_file (files[i], queue);
|
||||
else
|
||||
add_item_from_file (files[i], queue);
|
||||
}
|
||||
}
|
||||
|
||||
add_only = (g_strcmp0 (hint, "add-only") == 0);
|
||||
|
@@ -72,43 +72,6 @@ _open_subtitles_cb (GtkFileDialog *dialog, GAsyncResult *result, ClapperMediaIte
|
||||
gst_object_unref (item); // Borrowed reference
|
||||
}
|
||||
|
||||
static void
|
||||
_on_select_file_dir_finish (GFile *file, AdwActionRow *action_row, GError *error)
|
||||
{
|
||||
if (G_LIKELY (error == NULL)) {
|
||||
gchar *path = g_file_get_path (file);
|
||||
|
||||
adw_action_row_set_subtitle (action_row, path);
|
||||
g_free (path);
|
||||
} else {
|
||||
if (error->domain != GTK_DIALOG_ERROR || error->code != GTK_DIALOG_ERROR_DISMISSED) {
|
||||
g_printerr ("Error: %s\n",
|
||||
(error->message) ? error->message : "Could not open file dialog");
|
||||
}
|
||||
g_error_free (error);
|
||||
}
|
||||
g_clear_object (&file);
|
||||
g_object_unref (action_row); // Borrowed reference
|
||||
}
|
||||
|
||||
static void
|
||||
_select_file_cb (GtkFileDialog *dialog, GAsyncResult *result, AdwActionRow *action_row)
|
||||
{
|
||||
GError *error = NULL;
|
||||
GFile *file = gtk_file_dialog_open_finish (dialog, result, &error);
|
||||
|
||||
_on_select_file_dir_finish (file, action_row, error);
|
||||
}
|
||||
|
||||
static void
|
||||
_select_dir_cb (GtkFileDialog *dialog, GAsyncResult *result, AdwActionRow *action_row)
|
||||
{
|
||||
GError *error = NULL;
|
||||
GFile *file = gtk_file_dialog_select_folder_finish (dialog, result, &error);
|
||||
|
||||
_on_select_file_dir_finish (file, action_row, error);
|
||||
}
|
||||
|
||||
static void
|
||||
_dialog_add_mime_types (GtkFileDialog *dialog, const gchar *filter_name,
|
||||
const gchar *const *mime_types)
|
||||
@@ -181,35 +144,3 @@ clapper_app_file_dialog_open_subtitles (GtkApplication *gtk_app, ClapperMediaIte
|
||||
|
||||
g_object_unref (dialog);
|
||||
}
|
||||
|
||||
void
|
||||
clapper_app_file_dialog_select_prefs_file (GtkApplication *gtk_app, AdwActionRow *action_row)
|
||||
{
|
||||
GtkWindow *window = gtk_application_get_active_window (gtk_app);
|
||||
GtkFileDialog *dialog = gtk_file_dialog_new ();
|
||||
|
||||
gtk_file_dialog_set_modal (dialog, TRUE);
|
||||
gtk_file_dialog_set_title (dialog, "Select File");
|
||||
|
||||
gtk_file_dialog_open (dialog, window, NULL,
|
||||
(GAsyncReadyCallback) _select_file_cb,
|
||||
g_object_ref (action_row));
|
||||
|
||||
g_object_unref (dialog);
|
||||
}
|
||||
|
||||
void
|
||||
clapper_app_file_dialog_select_prefs_dir (GtkApplication *gtk_app, AdwActionRow *action_row)
|
||||
{
|
||||
GtkWindow *window = gtk_application_get_active_window (gtk_app);
|
||||
GtkFileDialog *dialog = gtk_file_dialog_new ();
|
||||
|
||||
gtk_file_dialog_set_modal (dialog, TRUE);
|
||||
gtk_file_dialog_set_title (dialog, "Select Folder");
|
||||
|
||||
gtk_file_dialog_select_folder (dialog, window, NULL,
|
||||
(GAsyncReadyCallback) _select_dir_cb,
|
||||
g_object_ref (action_row));
|
||||
|
||||
g_object_unref (dialog);
|
||||
}
|
||||
|
@@ -19,7 +19,6 @@
|
||||
|
||||
#include <glib.h>
|
||||
#include <gtk/gtk.h>
|
||||
#include <adwaita.h>
|
||||
#include <clapper/clapper.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
@@ -30,10 +29,4 @@ void clapper_app_file_dialog_open_files (GtkApplication *gtk_app);
|
||||
G_GNUC_INTERNAL
|
||||
void clapper_app_file_dialog_open_subtitles (GtkApplication *gtk_app, ClapperMediaItem *item);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
void clapper_app_file_dialog_select_prefs_file (GtkApplication *gtk_app, AdwActionRow *action_row);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
void clapper_app_file_dialog_select_prefs_dir (GtkApplication *gtk_app, AdwActionRow *action_row);
|
||||
|
||||
G_END_DECLS
|
||||
|
@@ -23,7 +23,6 @@
|
||||
|
||||
#include "clapper-app-preferences-window.h"
|
||||
#include "clapper-app-application.h"
|
||||
#include "clapper-app-file-dialog.h"
|
||||
#include "clapper-app-utils.h"
|
||||
|
||||
#define GST_CAT_DEFAULT clapper_app_preferences_window_debug
|
||||
@@ -42,14 +41,6 @@ struct _ClapperAppPreferencesWindow
|
||||
AdwSpinRow *subtitle_offset_spin_row;
|
||||
GtkFontDialogButton *font_dialog_button;
|
||||
|
||||
GtkStack *enhancers_stack;
|
||||
GtkWidget *browse_enhancers_page;
|
||||
GtkWidget *no_enhancers_page;
|
||||
|
||||
AdwNavigationPage *enhancers_subpage;
|
||||
AdwComboRow *enhancers_combo_row;
|
||||
AdwPreferencesGroup *enhancer_config_group;
|
||||
|
||||
AdwNavigationPage *plugins_subpage;
|
||||
AdwComboRow *plugins_combo_row;
|
||||
AdwComboRow *features_combo_row;
|
||||
@@ -57,8 +48,6 @@ struct _ClapperAppPreferencesWindow
|
||||
|
||||
GSettings *settings;
|
||||
|
||||
GList *enhancer_pspec_rows;
|
||||
|
||||
GList *features;
|
||||
GtkStringList *plugins_list;
|
||||
|
||||
@@ -78,19 +67,6 @@ typedef struct
|
||||
gboolean updated;
|
||||
} ClapperAppPreferencesIterRanksData;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
GSettings *settings;
|
||||
const gchar *key;
|
||||
} ClapperAppPreferencesResetData;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
GSettings *settings;
|
||||
GParamSpec *pspec;
|
||||
guint flag;
|
||||
} ClapperAppPreferencesFlagMapData;
|
||||
|
||||
enum
|
||||
{
|
||||
PROP_0,
|
||||
@@ -100,347 +76,6 @@ enum
|
||||
|
||||
static GParamSpec *param_specs[PROP_LAST] = { NULL, };
|
||||
|
||||
static void
|
||||
_flag_map_data_free (ClapperAppPreferencesFlagMapData *data)
|
||||
{
|
||||
GST_TRACE ("Destroying flag map data: %p", data);
|
||||
g_object_unref (data->settings);
|
||||
g_free (data);
|
||||
}
|
||||
|
||||
static void
|
||||
_reset_button_closure (ClapperAppPreferencesResetData *data, GClosure *closure)
|
||||
{
|
||||
GST_TRACE ("Destroying reset button data: %p", data);
|
||||
g_object_unref (data->settings);
|
||||
g_free (data);
|
||||
}
|
||||
|
||||
static void
|
||||
_reset_button_clicked_cb (GtkButton *button, ClapperAppPreferencesResetData *data)
|
||||
{
|
||||
g_settings_reset (data->settings, data->key);
|
||||
}
|
||||
|
||||
static void
|
||||
file_selection_row_activated_cb (AdwActionRow *action_row, GParamSpec *pspec)
|
||||
{
|
||||
GtkApplication *gtk_app;
|
||||
GtkWidget *window;
|
||||
|
||||
if (!(window = gtk_widget_get_ancestor (GTK_WIDGET (action_row), GTK_TYPE_WINDOW))) {
|
||||
GST_ERROR ("Could not get a hold of parent window");
|
||||
return;
|
||||
}
|
||||
|
||||
gtk_app = gtk_window_get_application (GTK_WINDOW (window));
|
||||
|
||||
if (pspec->flags & CLAPPER_ENHANCER_PARAM_FILEPATH)
|
||||
clapper_app_file_dialog_select_prefs_file (gtk_app, action_row);
|
||||
else
|
||||
clapper_app_file_dialog_select_prefs_dir (gtk_app, action_row);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
_get_enum_mapping (GValue *value, GVariant *variant, GParamSpec *pspec)
|
||||
{
|
||||
GEnumClass *enum_class = G_ENUM_CLASS (g_type_class_peek (pspec->value_type));
|
||||
const gchar *selected_str = g_variant_get_string (variant, NULL);
|
||||
guint i, selected = 0;
|
||||
|
||||
for (i = 0; i < enum_class->n_values; ++i) {
|
||||
if (g_strcmp0 (selected_str, enum_class->values[i].value_nick) == 0) {
|
||||
selected = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
g_value_set_uint (value, selected);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static GVariant *
|
||||
_set_enum_mapping (GValue *value, GVariantType *exp_type, GParamSpec *pspec)
|
||||
{
|
||||
GEnumClass *enum_class = G_ENUM_CLASS (g_type_class_peek (pspec->value_type));
|
||||
guint selected = g_value_get_uint (value);
|
||||
|
||||
if (G_UNLIKELY (selected == GTK_INVALID_LIST_POSITION))
|
||||
selected = 0;
|
||||
|
||||
return g_variant_new_string (enum_class->values[selected].value_nick);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
_get_flag_mapping (GValue *value, GVariant *variant, ClapperAppPreferencesFlagMapData *data)
|
||||
{
|
||||
guint flags = g_settings_get_flags (data->settings, data->pspec->name);
|
||||
|
||||
g_value_set_boolean (value, (flags & data->flag));
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static GVariant *
|
||||
_set_flag_mapping (GValue *value, GVariantType *exp_type, ClapperAppPreferencesFlagMapData *data)
|
||||
{
|
||||
GFlagsClass *flags_class = G_FLAGS_CLASS (g_type_class_peek (data->pspec->value_type));
|
||||
GStrvBuilder *builder;
|
||||
GVariant *variant;
|
||||
gchar **strv;
|
||||
gboolean active = g_value_get_boolean (value);
|
||||
guint i, flags = g_settings_get_flags (data->settings, data->pspec->name);
|
||||
|
||||
if (active)
|
||||
flags |= data->flag;
|
||||
else
|
||||
flags &= ~(data->flag);
|
||||
|
||||
builder = g_strv_builder_new ();
|
||||
|
||||
for (i = 0; i < flags_class->n_values; ++i) {
|
||||
if (flags & flags_class->values[i].value)
|
||||
g_strv_builder_add (builder, flags_class->values[i].value_nick);
|
||||
}
|
||||
|
||||
strv = g_strv_builder_end (builder);
|
||||
g_strv_builder_unref (builder);
|
||||
|
||||
variant = g_variant_new_strv ((const gchar *const *) strv, -1);
|
||||
g_strfreev (strv);
|
||||
|
||||
return variant;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
_add_enhancer_config_row (ClapperAppPreferencesWindow *self, GParamSpec *pspec,
|
||||
GSettings *enhancer_settings)
|
||||
{
|
||||
GtkWidget *row = NULL, *reset_button;
|
||||
ClapperAppPreferencesResetData *reset_data;
|
||||
const gchar *bind_prop = NULL;
|
||||
gboolean is_enum = FALSE, is_flags = FALSE;
|
||||
|
||||
switch (pspec->value_type) {
|
||||
case G_TYPE_BOOLEAN:{
|
||||
row = adw_switch_row_new ();
|
||||
break;
|
||||
}
|
||||
case G_TYPE_INT:{
|
||||
GParamSpecInt *p = (GParamSpecInt *) pspec;
|
||||
row = adw_spin_row_new_with_range (p->minimum, p->maximum, 1);
|
||||
break;
|
||||
}
|
||||
case G_TYPE_UINT:{
|
||||
GParamSpecUInt *p = (GParamSpecUInt *) pspec;
|
||||
row = adw_spin_row_new_with_range (p->minimum, p->maximum, 1);
|
||||
break;
|
||||
}
|
||||
case G_TYPE_DOUBLE:{
|
||||
GParamSpecDouble *p = (GParamSpecDouble *) pspec;
|
||||
row = adw_spin_row_new_with_range (p->minimum, p->maximum, 0.25);
|
||||
break;
|
||||
}
|
||||
case G_TYPE_STRING:{
|
||||
if (pspec->flags & (CLAPPER_ENHANCER_PARAM_FILEPATH | CLAPPER_ENHANCER_PARAM_DIRPATH)) {
|
||||
GtkWidget *image;
|
||||
|
||||
image = gtk_image_new_from_icon_name ("document-open-symbolic");
|
||||
gtk_widget_set_margin_end (image, 10); // matches other rows
|
||||
|
||||
row = adw_action_row_new ();
|
||||
adw_action_row_add_suffix (ADW_ACTION_ROW (row), image);
|
||||
adw_action_row_set_activatable_widget (ADW_ACTION_ROW (row), image);
|
||||
|
||||
g_signal_connect (row, "activated",
|
||||
G_CALLBACK (file_selection_row_activated_cb), pspec);
|
||||
} else {
|
||||
row = adw_entry_row_new ();
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:{
|
||||
if ((is_enum = G_IS_PARAM_SPEC_ENUM (pspec))) {
|
||||
GtkExpression *expression;
|
||||
AdwEnumListModel *enum_model;
|
||||
|
||||
row = adw_combo_row_new ();
|
||||
expression = gtk_property_expression_new (ADW_TYPE_ENUM_LIST_ITEM, NULL, "nick");
|
||||
adw_combo_row_set_expression (ADW_COMBO_ROW (row), expression);
|
||||
|
||||
enum_model = adw_enum_list_model_new (pspec->value_type);
|
||||
adw_combo_row_set_model (ADW_COMBO_ROW (row), G_LIST_MODEL (enum_model));
|
||||
|
||||
gtk_expression_unref (expression);
|
||||
g_object_unref (enum_model);
|
||||
break;
|
||||
} else if ((is_flags = G_IS_PARAM_SPEC_FLAGS (pspec))) {
|
||||
GFlagsClass *flags_class = G_FLAGS_CLASS (g_type_class_peek (pspec->value_type));
|
||||
guint i;
|
||||
|
||||
row = adw_expander_row_new ();
|
||||
|
||||
for (i = 0; i < flags_class->n_values; ++i) {
|
||||
GtkWidget *flag_row = adw_switch_row_new ();
|
||||
ClapperAppPreferencesFlagMapData *fm_data;
|
||||
|
||||
adw_preferences_row_set_title (ADW_PREFERENCES_ROW (flag_row),
|
||||
flags_class->values[i].value_nick);
|
||||
|
||||
fm_data = g_new (ClapperAppPreferencesFlagMapData, 1);
|
||||
fm_data->settings = g_object_ref (enhancer_settings);
|
||||
fm_data->pspec = pspec;
|
||||
fm_data->flag = flags_class->values[i].value;
|
||||
|
||||
GST_TRACE ("Created flag map data: %p", fm_data);
|
||||
|
||||
g_settings_bind_with_mapping (enhancer_settings, pspec->name, flag_row,
|
||||
"active", G_SETTINGS_BIND_DEFAULT,
|
||||
(GSettingsBindGetMapping) _get_flag_mapping,
|
||||
(GSettingsBindSetMapping) _set_flag_mapping,
|
||||
fm_data, (GDestroyNotify) _flag_map_data_free);
|
||||
|
||||
adw_expander_row_add_row (ADW_EXPANDER_ROW (row), flag_row);
|
||||
}
|
||||
break;
|
||||
}
|
||||
g_warning ("Unsupported enhancer \"%s\" property type: %s",
|
||||
pspec->name, g_type_name (pspec->value_type));
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
reset_button = gtk_button_new_from_icon_name ("view-refresh-symbolic");
|
||||
gtk_widget_set_tooltip_text (reset_button, _("Restore default"));
|
||||
|
||||
gtk_widget_set_halign (reset_button, GTK_ALIGN_CENTER);
|
||||
gtk_widget_set_valign (reset_button, GTK_ALIGN_CENTER);
|
||||
gtk_widget_add_css_class (reset_button, "circular");
|
||||
|
||||
gtk_widget_set_tooltip_text (row, g_param_spec_get_blurb (pspec));
|
||||
|
||||
adw_preferences_row_set_title (ADW_PREFERENCES_ROW (row), g_param_spec_get_nick (pspec));
|
||||
|
||||
if (ADW_IS_SWITCH_ROW (row)) {
|
||||
bind_prop = "active";
|
||||
} else if (ADW_IS_SPIN_ROW (row)) {
|
||||
bind_prop = "value";
|
||||
adw_spin_row_set_numeric (ADW_SPIN_ROW (row), TRUE);
|
||||
} else if (ADW_IS_ENTRY_ROW (row)) {
|
||||
bind_prop = "text";
|
||||
} else if (ADW_IS_COMBO_ROW (row)) {
|
||||
bind_prop = "selected";
|
||||
} else if (ADW_IS_ACTION_ROW (row)) {
|
||||
bind_prop = "subtitle";
|
||||
} else if (!is_flags) { // In case of flags we bind individual widgets
|
||||
g_assert_not_reached ();
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (ADW_IS_ENTRY_ROW (row))
|
||||
adw_entry_row_add_prefix (ADW_ENTRY_ROW (row), reset_button);
|
||||
else if (ADW_IS_ACTION_ROW (row))
|
||||
adw_action_row_add_prefix (ADW_ACTION_ROW (row), reset_button);
|
||||
else if (ADW_IS_EXPANDER_ROW (row))
|
||||
adw_expander_row_add_prefix (ADW_EXPANDER_ROW (row), reset_button);
|
||||
|
||||
if (is_enum) {
|
||||
g_settings_bind_with_mapping (enhancer_settings, pspec->name, row,
|
||||
bind_prop, G_SETTINGS_BIND_DEFAULT,
|
||||
(GSettingsBindGetMapping) _get_enum_mapping,
|
||||
(GSettingsBindSetMapping) _set_enum_mapping,
|
||||
pspec, NULL);
|
||||
} else if (!is_flags) {
|
||||
g_settings_bind (enhancer_settings, pspec->name, row,
|
||||
bind_prop, G_SETTINGS_BIND_DEFAULT);
|
||||
}
|
||||
|
||||
reset_data = g_new (ClapperAppPreferencesResetData, 1);
|
||||
reset_data->settings = g_object_ref (enhancer_settings);
|
||||
reset_data->key = pspec->name;
|
||||
|
||||
GST_TRACE ("Created reset button data: %p", reset_data);
|
||||
|
||||
g_signal_connect_data (reset_button, "clicked",
|
||||
G_CALLBACK (_reset_button_clicked_cb), reset_data,
|
||||
(GClosureNotify) _reset_button_closure, G_CONNECT_DEFAULT);
|
||||
|
||||
adw_preferences_group_add (self->enhancer_config_group, row);
|
||||
self->enhancer_pspec_rows = g_list_append (self->enhancer_pspec_rows, row);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
selected_enhancer_changed_cb (AdwComboRow *combo_row,
|
||||
GParamSpec *pspec G_GNUC_UNUSED, ClapperAppPreferencesWindow *self)
|
||||
{
|
||||
guint selected = adw_combo_row_get_selected (combo_row);
|
||||
|
||||
/* Remove old rows */
|
||||
if (self->enhancer_pspec_rows) {
|
||||
GList *el;
|
||||
|
||||
for (el = self->enhancer_pspec_rows; el; el = g_list_next (el))
|
||||
adw_preferences_group_remove (self->enhancer_config_group, GTK_WIDGET (el->data));
|
||||
|
||||
g_clear_list (&self->enhancer_pspec_rows, NULL);
|
||||
}
|
||||
|
||||
/* Add new rows */
|
||||
if (selected != GTK_INVALID_LIST_POSITION) {
|
||||
ClapperEnhancerProxyList *proxies = clapper_get_global_enhancer_proxies ();
|
||||
ClapperEnhancerProxy *proxy = clapper_enhancer_proxy_list_peek_proxy (proxies, selected);
|
||||
GParamSpec **pspecs;
|
||||
guint n_pspecs;
|
||||
gboolean has_props = FALSE;
|
||||
|
||||
if ((pspecs = clapper_enhancer_proxy_get_target_properties (proxy, &n_pspecs))) {
|
||||
GSettings *enhancer_settings = NULL;
|
||||
guint i;
|
||||
|
||||
for (i = 0; i < n_pspecs; ++i) {
|
||||
if (pspecs[i]->flags & CLAPPER_ENHANCER_PARAM_GLOBAL) {
|
||||
if (!enhancer_settings)
|
||||
enhancer_settings = clapper_enhancer_proxy_get_settings (proxy);
|
||||
if (enhancer_settings)
|
||||
has_props |= _add_enhancer_config_row (self, pspecs[i], enhancer_settings);
|
||||
}
|
||||
}
|
||||
|
||||
g_clear_object (&enhancer_settings);
|
||||
}
|
||||
|
||||
if (!has_props) {
|
||||
GtkWidget *row = adw_action_row_new ();
|
||||
|
||||
adw_preferences_row_set_title (ADW_PREFERENCES_ROW (row), _("No configurable properties"));
|
||||
adw_preferences_group_add (self->enhancer_config_group, row);
|
||||
self->enhancer_pspec_rows = g_list_append (self->enhancer_pspec_rows, row);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
enhancers_config_activated_cb (AdwActionRow *action_row, ClapperAppPreferencesWindow *self)
|
||||
{
|
||||
/* If no model set yet */
|
||||
if (!adw_combo_row_get_model (self->enhancers_combo_row)) {
|
||||
ClapperEnhancerProxyList *proxies = clapper_get_global_enhancer_proxies ();
|
||||
|
||||
adw_combo_row_set_model (self->enhancers_combo_row, G_LIST_MODEL (proxies));
|
||||
adw_combo_row_set_selected (self->enhancers_combo_row, GTK_INVALID_LIST_POSITION);
|
||||
|
||||
GST_DEBUG ("Populated names combo row in enhancers subpage");
|
||||
|
||||
if (clapper_enhancer_proxy_list_get_n_proxies (proxies) > 0)
|
||||
gtk_stack_set_visible_child (self->enhancers_stack, self->browse_enhancers_page);
|
||||
else
|
||||
gtk_stack_set_visible_child (self->enhancers_stack, self->no_enhancers_page);
|
||||
}
|
||||
|
||||
adw_preferences_window_push_subpage (ADW_PREFERENCES_WINDOW (self), self->enhancers_subpage);
|
||||
}
|
||||
|
||||
/* Sort by plugin name and if the same, sort by element name */
|
||||
static gint
|
||||
_compare_plugins_cb (gconstpointer ptr_a, gconstpointer ptr_b)
|
||||
@@ -666,12 +301,6 @@ _make_plugin_features_string_list (ClapperAppPreferencesWindow *self, const gcha
|
||||
return features_list;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
list_has_selection_closure (ClapperAppPreferencesWindow *self, guint selected)
|
||||
{
|
||||
return (selected != GTK_INVALID_LIST_POSITION);
|
||||
}
|
||||
|
||||
static GtkStringList *
|
||||
ranking_features_model_closure (ClapperAppPreferencesWindow *self, GtkStringObject *string_obj)
|
||||
{
|
||||
@@ -914,7 +543,6 @@ clapper_app_preferences_window_finalize (GObject *object)
|
||||
|
||||
g_object_unref (self->settings);
|
||||
|
||||
g_clear_list (&self->enhancer_pspec_rows, NULL);
|
||||
g_clear_object (&self->plugins_list);
|
||||
|
||||
if (self->features)
|
||||
@@ -970,14 +598,6 @@ clapper_app_preferences_window_class_init (ClapperAppPreferencesWindowClass *kla
|
||||
gtk_widget_class_bind_template_child (widget_class, ClapperAppPreferencesWindow, subtitle_offset_spin_row);
|
||||
gtk_widget_class_bind_template_child (widget_class, ClapperAppPreferencesWindow, font_dialog_button);
|
||||
|
||||
gtk_widget_class_bind_template_child (widget_class, ClapperAppPreferencesWindow, enhancers_stack);
|
||||
gtk_widget_class_bind_template_child (widget_class, ClapperAppPreferencesWindow, browse_enhancers_page);
|
||||
gtk_widget_class_bind_template_child (widget_class, ClapperAppPreferencesWindow, no_enhancers_page);
|
||||
|
||||
gtk_widget_class_bind_template_child (widget_class, ClapperAppPreferencesWindow, enhancers_subpage);
|
||||
gtk_widget_class_bind_template_child (widget_class, ClapperAppPreferencesWindow, enhancers_combo_row);
|
||||
gtk_widget_class_bind_template_child (widget_class, ClapperAppPreferencesWindow, enhancer_config_group);
|
||||
|
||||
gtk_widget_class_bind_template_child (widget_class, ClapperAppPreferencesWindow, plugins_subpage);
|
||||
gtk_widget_class_bind_template_child (widget_class, ClapperAppPreferencesWindow, plugins_combo_row);
|
||||
gtk_widget_class_bind_template_child (widget_class, ClapperAppPreferencesWindow, features_combo_row);
|
||||
@@ -985,13 +605,9 @@ clapper_app_preferences_window_class_init (ClapperAppPreferencesWindowClass *kla
|
||||
|
||||
gtk_widget_class_bind_template_callback (widget_class, seek_method_name_closure);
|
||||
|
||||
gtk_widget_class_bind_template_callback (widget_class, enhancers_config_activated_cb);
|
||||
gtk_widget_class_bind_template_callback (widget_class, selected_enhancer_changed_cb);
|
||||
|
||||
gtk_widget_class_bind_template_callback (widget_class, plugin_ranking_activated_cb);
|
||||
gtk_widget_class_bind_template_callback (widget_class, plugin_ranking_unrealize_cb);
|
||||
|
||||
gtk_widget_class_bind_template_callback (widget_class, list_has_selection_closure);
|
||||
gtk_widget_class_bind_template_callback (widget_class, ranking_features_model_closure);
|
||||
gtk_widget_class_bind_template_callback (widget_class, add_override_button_sensitive_closure);
|
||||
gtk_widget_class_bind_template_callback (widget_class, add_override_button_clicked_cb);
|
||||
|
@@ -582,7 +582,7 @@ _create_pipeline_svg_file_in_thread (GTask *task, GObject *source G_GNUC_UNUSED,
|
||||
GVC_t *gvc;
|
||||
gchar *path, *template = NULL, *dot_data = NULL, *img_data = NULL;
|
||||
gint fd;
|
||||
gsize size = 0;
|
||||
guint size = 0;
|
||||
|
||||
if (!(tmp_subdir = _create_tmp_subdir ("pipelines", cancellable, &error)))
|
||||
goto finish;
|
||||
@@ -610,16 +610,7 @@ _create_pipeline_svg_file_in_thread (GTask *task, GObject *source G_GNUC_UNUSED,
|
||||
|
||||
gvc = gvContext ();
|
||||
gvLayout (gvc, graph, "dot");
|
||||
|
||||
#ifdef HAVE_GVC_13
|
||||
gvRenderData (gvc, graph, "svg", &img_data, &size);
|
||||
#else
|
||||
{
|
||||
guint tmp_size = 0; // Temporary uint to satisfy older API
|
||||
gvRenderData (gvc, graph, "svg", &img_data, &tmp_size);
|
||||
size = tmp_size;
|
||||
}
|
||||
#endif
|
||||
|
||||
agclose (graph);
|
||||
gvFreeContext (gvc);
|
||||
|
@@ -86,7 +86,9 @@ typedef struct
|
||||
gint64 last_tick;
|
||||
} ClapperAppWindowResizeData;
|
||||
|
||||
#if CLAPPER_HAVE_MPRIS
|
||||
static guint16 instance_count = 0;
|
||||
#endif
|
||||
|
||||
static inline GQuark
|
||||
clapper_app_window_extra_options_get_quark (void)
|
||||
@@ -231,7 +233,7 @@ video_map_cb (GtkWidget *widget, ClapperAppWindow *self)
|
||||
|
||||
GST_TRACE_OBJECT (self, "Video map");
|
||||
|
||||
player = clapper_gtk_av_get_player (CLAPPER_GTK_AV_CAST (self->video));
|
||||
player = clapper_gtk_video_get_player (CLAPPER_GTK_VIDEO_CAST (self->video));
|
||||
|
||||
g_signal_connect (player, "notify::volume",
|
||||
G_CALLBACK (_player_volume_changed_cb), self);
|
||||
@@ -252,7 +254,7 @@ video_unmap_cb (GtkWidget *widget, ClapperAppWindow *self)
|
||||
|
||||
GST_TRACE_OBJECT (self, "Video unmap");
|
||||
|
||||
player = clapper_gtk_av_get_player (CLAPPER_GTK_AV_CAST (self->video));
|
||||
player = clapper_gtk_video_get_player (CLAPPER_GTK_VIDEO_CAST (self->video));
|
||||
|
||||
g_signal_handlers_disconnect_by_func (player, _player_volume_changed_cb, self);
|
||||
g_signal_handlers_disconnect_by_func (player, _player_speed_changed_cb, self);
|
||||
@@ -524,7 +526,7 @@ drag_update_cb (GtkGestureDrag *drag,
|
||||
static inline void
|
||||
_alter_volume (ClapperAppWindow *self, gdouble dy)
|
||||
{
|
||||
ClapperPlayer *player = clapper_gtk_av_get_player (CLAPPER_GTK_AV_CAST (self->video));
|
||||
ClapperPlayer *player = clapper_gtk_video_get_player (CLAPPER_GTK_VIDEO_CAST (self->video));
|
||||
gdouble volume = clapper_player_get_volume (player);
|
||||
|
||||
/* We do not want for volume to change too suddenly */
|
||||
@@ -547,7 +549,7 @@ _alter_volume (ClapperAppWindow *self, gdouble dy)
|
||||
static inline void
|
||||
_alter_speed (ClapperAppWindow *self, gdouble dx)
|
||||
{
|
||||
ClapperPlayer *player = clapper_gtk_av_get_player (CLAPPER_GTK_AV_CAST (self->video));
|
||||
ClapperPlayer *player = clapper_gtk_video_get_player (CLAPPER_GTK_VIDEO_CAST (self->video));
|
||||
gdouble speed = clapper_player_get_speed (player);
|
||||
|
||||
speed -= dx * 0.02;
|
||||
@@ -571,7 +573,8 @@ _begin_seek_operation (ClapperAppWindow *self)
|
||||
if (self->seeking)
|
||||
return FALSE;
|
||||
|
||||
player = clapper_gtk_av_get_player (CLAPPER_GTK_AV_CAST (self->video));
|
||||
player = clapper_gtk_video_get_player (
|
||||
CLAPPER_GTK_VIDEO_CAST (self->video));
|
||||
queue = clapper_player_get_queue (player);
|
||||
current_item = clapper_queue_get_current_item (queue);
|
||||
|
||||
@@ -599,8 +602,8 @@ static void
|
||||
_end_seek_operation (ClapperAppWindow *self)
|
||||
{
|
||||
if (self->seeking && self->current_duration > 0) {
|
||||
ClapperPlayer *player = clapper_gtk_av_get_player (
|
||||
CLAPPER_GTK_AV_CAST (self->video));
|
||||
ClapperPlayer *player = clapper_gtk_video_get_player (
|
||||
CLAPPER_GTK_VIDEO_CAST (self->video));
|
||||
|
||||
clapper_player_seek_custom (player, self->pending_position,
|
||||
g_settings_get_int (self->settings, "seek-method"));
|
||||
@@ -763,8 +766,8 @@ _handle_seek_key_press (ClapperAppWindow *self, gboolean forward)
|
||||
static void
|
||||
_handle_chapter_key_press (ClapperAppWindow *self, gboolean forward)
|
||||
{
|
||||
ClapperPlayer *player = clapper_gtk_av_get_player (
|
||||
CLAPPER_GTK_AV_CAST (self->video));
|
||||
ClapperPlayer *player = clapper_gtk_video_get_player (
|
||||
CLAPPER_GTK_VIDEO_CAST (self->video));
|
||||
ClapperQueue *queue = clapper_player_get_queue (player);
|
||||
ClapperMediaItem *current_item = clapper_queue_get_current_item (queue);
|
||||
ClapperTimeline *timeline;
|
||||
@@ -854,8 +857,8 @@ _handle_chapter_key_press (ClapperAppWindow *self, gboolean forward)
|
||||
static void
|
||||
_handle_item_key_press (ClapperAppWindow *self, gboolean forward)
|
||||
{
|
||||
ClapperPlayer *player = clapper_gtk_av_get_player (
|
||||
CLAPPER_GTK_AV_CAST (self->video));
|
||||
ClapperPlayer *player = clapper_gtk_video_get_player (
|
||||
CLAPPER_GTK_VIDEO_CAST (self->video));
|
||||
ClapperQueue *queue = clapper_player_get_queue (player);
|
||||
guint prev_index, index;
|
||||
|
||||
@@ -863,7 +866,7 @@ _handle_item_key_press (ClapperAppWindow *self, gboolean forward)
|
||||
|
||||
prev_index = clapper_queue_get_current_index (queue);
|
||||
gtk_widget_activate_action (self->video,
|
||||
(forward) ? "av.next-item" : "av.previous-item", NULL);
|
||||
(forward) ? "video.next-item" : "video.previous-item", NULL);
|
||||
index = clapper_queue_get_current_index (queue);
|
||||
|
||||
/* Notify only when changed */
|
||||
@@ -880,14 +883,14 @@ _handle_speed_key_press (ClapperAppWindow *self, gboolean forward)
|
||||
forward ^= (gtk_widget_get_default_direction () == GTK_TEXT_DIR_RTL);
|
||||
|
||||
gtk_widget_activate_action (self->video,
|
||||
(forward) ? "av.speed-up" : "av.speed-down", NULL);
|
||||
(forward) ? "video.speed-up" : "video.speed-down", NULL);
|
||||
}
|
||||
|
||||
static inline void
|
||||
_handle_progression_key_press (ClapperAppWindow *self)
|
||||
{
|
||||
ClapperPlayer *player = clapper_gtk_av_get_player (
|
||||
CLAPPER_GTK_AV_CAST (self->video));
|
||||
ClapperPlayer *player = clapper_gtk_video_get_player (
|
||||
CLAPPER_GTK_VIDEO_CAST (self->video));
|
||||
ClapperQueue *queue = clapper_player_get_queue (player);
|
||||
ClapperQueueProgressionMode mode;
|
||||
const gchar *icon = NULL, *label = NULL;
|
||||
@@ -907,11 +910,11 @@ key_pressed_cb (GtkEventControllerKey *controller, guint keyval,
|
||||
switch (keyval) {
|
||||
case GDK_KEY_Up:
|
||||
if ((state & GDK_MODIFIER_MASK) == 0)
|
||||
gtk_widget_activate_action (self->video, "av.volume-up", NULL);
|
||||
gtk_widget_activate_action (self->video, "video.volume-up", NULL);
|
||||
break;
|
||||
case GDK_KEY_Down:
|
||||
if ((state & GDK_MODIFIER_MASK) == 0)
|
||||
gtk_widget_activate_action (self->video, "av.volume-down", NULL);
|
||||
gtk_widget_activate_action (self->video, "video.volume-down", NULL);
|
||||
break;
|
||||
case GDK_KEY_Left:
|
||||
if ((state & GDK_MODIFIER_MASK) == 0) {
|
||||
@@ -942,7 +945,7 @@ key_pressed_cb (GtkEventControllerKey *controller, guint keyval,
|
||||
case GDK_KEY_space:
|
||||
case GDK_KEY_k:
|
||||
if (!self->key_held && (state & GDK_MODIFIER_MASK) == 0)
|
||||
gtk_widget_activate_action (self->video, "av.toggle-play", NULL);
|
||||
gtk_widget_activate_action (self->video, "video.toggle-play", NULL);
|
||||
break;
|
||||
case GDK_KEY_less:
|
||||
if (!self->key_held) // Needs seek (action is slow)
|
||||
@@ -954,7 +957,7 @@ key_pressed_cb (GtkEventControllerKey *controller, guint keyval,
|
||||
break;
|
||||
case GDK_KEY_m:
|
||||
if (!self->key_held && (state & GDK_MODIFIER_MASK) == 0)
|
||||
gtk_widget_activate_action (self->video, "av.toggle-mute", NULL);
|
||||
gtk_widget_activate_action (self->video, "video.toggle-mute", NULL);
|
||||
break;
|
||||
case GDK_KEY_p:
|
||||
if (!self->key_held && (state & GDK_MODIFIER_MASK) == 0)
|
||||
@@ -1122,7 +1125,7 @@ clapper_app_window_get_video (ClapperAppWindow *self)
|
||||
ClapperPlayer *
|
||||
clapper_app_window_get_player (ClapperAppWindow *self)
|
||||
{
|
||||
return clapper_gtk_av_get_player (CLAPPER_GTK_AV_CAST (self->video));
|
||||
return clapper_gtk_video_get_player (CLAPPER_GTK_VIDEO_CAST (self->video));
|
||||
}
|
||||
|
||||
ClapperAppWindowExtraOptions *
|
||||
@@ -1197,7 +1200,6 @@ clapper_app_window_init (ClapperAppWindow *self)
|
||||
GtkSettings *settings;
|
||||
GtkWidget *dummy_titlebar;
|
||||
gint distance = 0;
|
||||
GtkWindowGroup *group;
|
||||
|
||||
gtk_widget_set_size_request (GTK_WIDGET (self),
|
||||
MIN_WINDOW_WIDTH, MIN_WINDOW_HEIGHT);
|
||||
@@ -1229,11 +1231,6 @@ clapper_app_window_init (ClapperAppWindow *self)
|
||||
|
||||
gtk_drop_target_set_gtypes (self->drop_target,
|
||||
(GType[3]) { GDK_TYPE_FILE_LIST, G_TYPE_FILE, G_TYPE_STRING }, 3);
|
||||
|
||||
/* Add to window group */
|
||||
group = gtk_window_group_new ();
|
||||
gtk_window_group_add_window (group, GTK_WINDOW (self));
|
||||
g_object_unref (group);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1242,8 +1239,6 @@ clapper_app_window_constructed (GObject *object)
|
||||
ClapperAppWindow *self = CLAPPER_APP_WINDOW_CAST (object);
|
||||
ClapperPlayer *player = clapper_app_window_get_player (self);
|
||||
ClapperQueue *queue = clapper_player_get_queue (player);
|
||||
ClapperEnhancerProxyList *proxies = clapper_player_get_enhancer_proxies (player);
|
||||
ClapperEnhancerProxy *proxy;
|
||||
ClapperGtkExtraMenuButton *button;
|
||||
AdwStyleManager *manager;
|
||||
|
||||
@@ -1257,30 +1252,22 @@ clapper_app_window_constructed (GObject *object)
|
||||
#if (CLAPPER_HAVE_MPRIS || CLAPPER_HAVE_SERVER || CLAPPER_HAVE_DISCOVERER)
|
||||
ClapperFeature *feature = NULL;
|
||||
#endif
|
||||
|
||||
#if CLAPPER_HAVE_MPRIS
|
||||
gchar mpris_name[45];
|
||||
g_snprintf (mpris_name, sizeof (mpris_name),
|
||||
"org.mpris.MediaPlayer2.Clapper.instance%" G_GUINT16_FORMAT, instance_count++);
|
||||
#endif
|
||||
|
||||
self->settings = g_settings_new (CLAPPER_APP_ID);
|
||||
self->last_volume = PERCENTAGE_ROUND (g_settings_get_double (self->settings, "volume"));
|
||||
|
||||
if ((proxy = clapper_enhancer_proxy_list_get_proxy_by_module (proxies, "clapper-mpris"))) {
|
||||
clapper_enhancer_proxy_set_locally (proxy,
|
||||
"own-name", mpris_name,
|
||||
"identity", CLAPPER_APP_NAME,
|
||||
"desktop-entry", CLAPPER_APP_ID,
|
||||
"queue-controllable", TRUE, NULL);
|
||||
gst_object_unref (proxy);
|
||||
} else {
|
||||
#if CLAPPER_HAVE_MPRIS
|
||||
feature = CLAPPER_FEATURE (clapper_mpris_new (
|
||||
mpris_name, CLAPPER_APP_NAME, CLAPPER_APP_ID));
|
||||
clapper_mpris_set_queue_controllable (CLAPPER_MPRIS (feature), TRUE);
|
||||
clapper_player_add_feature (player, feature);
|
||||
gst_object_unref (feature);
|
||||
feature = CLAPPER_FEATURE (clapper_mpris_new (
|
||||
mpris_name, CLAPPER_APP_NAME, CLAPPER_APP_ID));
|
||||
clapper_mpris_set_queue_controllable (CLAPPER_MPRIS (feature), TRUE);
|
||||
clapper_player_add_feature (player, feature);
|
||||
gst_object_unref (feature);
|
||||
#endif
|
||||
}
|
||||
|
||||
#if CLAPPER_HAVE_SERVER
|
||||
feature = CLAPPER_FEATURE (clapper_server_new ());
|
||||
|
@@ -21,10 +21,10 @@ window.info .subcontent streamlist preferencesgroup {
|
||||
window.preferences .subcontent {
|
||||
margin: 16px;
|
||||
}
|
||||
window.preferences .configsubpage .subcontent popover {
|
||||
window.preferences .pluginssubpage .subcontent popover {
|
||||
min-width: 264px;
|
||||
}
|
||||
window.preferences .configsubpage .subcontent button.pill {
|
||||
window.preferences .pluginssubpage .subcontent button.pill {
|
||||
margin-top: 8px;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
@@ -1,11 +1,10 @@
|
||||
appstream_cli = find_program('appstreamcli', required: false)
|
||||
if appstream_cli.found()
|
||||
appstream_util = find_program('appstream-util', required: false)
|
||||
if appstream_util.found()
|
||||
test('Validate appstream file',
|
||||
appstream_cli,
|
||||
appstream_util,
|
||||
args: [
|
||||
'validate',
|
||||
'--no-net',
|
||||
'--explain',
|
||||
'validate-relax',
|
||||
'--nonet',
|
||||
join_paths(meson.current_source_dir(), 'metainfo', 'com.github.rafostar.Clapper.metainfo.xml'),
|
||||
]
|
||||
)
|
||||
|
@@ -31,10 +31,8 @@
|
||||
gint
|
||||
main (gint argc, gchar **argv)
|
||||
{
|
||||
GApplication *application;
|
||||
ClapperEnhancerProxyList *proxies;
|
||||
const gchar *clapper_ldir;
|
||||
guint i, n_proxies;
|
||||
GApplication *application;
|
||||
gint status;
|
||||
|
||||
#ifdef G_OS_WIN32
|
||||
@@ -66,15 +64,6 @@ main (gint argc, gchar **argv)
|
||||
resolution = clapper_app_utils_win_hi_res_clock_start ();
|
||||
#endif
|
||||
|
||||
proxies = clapper_get_global_enhancer_proxies ();
|
||||
n_proxies = clapper_enhancer_proxy_list_get_n_proxies (proxies);
|
||||
|
||||
/* Allow usage of all enhancers */
|
||||
for (i = 0; i < n_proxies; ++i) {
|
||||
ClapperEnhancerProxy *proxy = clapper_enhancer_proxy_list_peek_proxy (proxies, i);
|
||||
clapper_enhancer_proxy_set_target_creation_allowed (proxy, TRUE);
|
||||
}
|
||||
|
||||
application = clapper_app_application_new ();
|
||||
|
||||
status = g_application_run (application, argc, argv);
|
||||
|
@@ -105,9 +105,6 @@ if not pp_option.disabled()
|
||||
if cgraph_dep.found() and gvc_dep.found()
|
||||
clapperapp_c_args += ['-DHAVE_GRAPHVIZ']
|
||||
clapperapp_deps += [cgraph_dep, gvc_dep]
|
||||
if gvc_dep.version().version_compare('>= 13.0.0')
|
||||
clapperapp_c_args += ['-DHAVE_GVC_13']
|
||||
endif
|
||||
clapperapp_available_functionalities += 'pipeline-preview'
|
||||
elif pp_option.enabled()
|
||||
error('pipeline-preview option was enabled, but required dependencies were not found')
|
||||
|
@@ -3,7 +3,7 @@ msgstr ""
|
||||
"Project-Id-Version: clapper\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2025-02-15 12:47+0100\n"
|
||||
"PO-Revision-Date: 2025-02-15 12:10\n"
|
||||
"PO-Revision-Date: 2025-06-14 17:10\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: Arabic\n"
|
||||
"Language: ar_SA\n"
|
||||
@@ -20,30 +20,30 @@ msgstr ""
|
||||
#. Translators: Do NOT translate app name!
|
||||
#: src/bin/clapper-app/data/applications/com.github.rafostar.Clapper.desktop.in:4
|
||||
msgid "Clapper"
|
||||
msgstr ""
|
||||
msgstr "كلابر"
|
||||
|
||||
#: src/bin/clapper-app/data/applications/com.github.rafostar.Clapper.desktop.in:5
|
||||
msgid "Multimedia Player"
|
||||
msgstr ""
|
||||
msgstr "مشغل وسائط متعددة"
|
||||
|
||||
#: src/bin/clapper-app/data/applications/com.github.rafostar.Clapper.desktop.in:6
|
||||
msgid "Play videos and music"
|
||||
msgstr ""
|
||||
msgstr "شغِّل الفيديوهات والموسيقى"
|
||||
|
||||
#. Translators: Search terms to find this application. Do NOT translate the semicolons!
|
||||
#: src/bin/clapper-app/data/applications/com.github.rafostar.Clapper.desktop.in:16
|
||||
msgid "Video;Movie;Film;Clip;Series;Player;Playlist;DVD;TV;Disc;"
|
||||
msgstr ""
|
||||
msgstr "الفيديوهات;الفيلم;الأفلام;المقطع;المقاطع;المسلسلات;المشغلات;قائمة تشغيل;DVD;دي في دي;التلفاز;القرص;Clapper;"
|
||||
|
||||
#: src/bin/clapper-app/data/applications/com.github.rafostar.Clapper.desktop.in:22
|
||||
#: src/bin/clapper-app/ui/clapper-app-headerbar.ui:183
|
||||
msgid "New Window"
|
||||
msgstr ""
|
||||
msgstr "نافذة جديدة"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-audio-stream-list-item.ui:14
|
||||
#: src/bin/clapper-app/ui/clapper-app-video-stream-list-item.ui:14
|
||||
msgid "Codec"
|
||||
msgstr ""
|
||||
msgstr "المرماز"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-audio-stream-list-item.ui:24
|
||||
msgid "Channels"
|
||||
@@ -65,23 +65,23 @@ msgstr ""
|
||||
#: src/bin/clapper-app/ui/clapper-app-audio-stream-list-item.ui:70
|
||||
#: src/bin/clapper-app/ui/clapper-app-subtitle-stream-list-item.ui:24
|
||||
msgid "Language"
|
||||
msgstr ""
|
||||
msgstr "اللغة"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-headerbar.ui:189
|
||||
#: src/bin/clapper-app/ui/clapper-app-initial-state.ui:80
|
||||
msgid "Preferences"
|
||||
msgstr "الإعدادات"
|
||||
msgstr "التفضيلات"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-headerbar.ui:193
|
||||
#: src/bin/clapper-app/ui/clapper-app-initial-state.ui:84
|
||||
msgid "Keyboard Shortcuts"
|
||||
msgstr ""
|
||||
msgstr "اختصارات لوحة المفاتيح"
|
||||
|
||||
#. TRANSLATORS: Please do not translate application name
|
||||
#: src/bin/clapper-app/ui/clapper-app-headerbar.ui:200
|
||||
#: src/bin/clapper-app/ui/clapper-app-initial-state.ui:91
|
||||
msgid "About Clapper"
|
||||
msgstr "حول Clapper"
|
||||
msgstr "عَنْ «كلابر»"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-help-overlay.ui:10
|
||||
#: src/bin/clapper-app/ui/clapper-app-preferences-window.ui:11
|
||||
@@ -90,19 +90,19 @@ msgstr "عام"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-help-overlay.ui:13
|
||||
msgid "New window"
|
||||
msgstr ""
|
||||
msgstr "نافذة جديدة"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-help-overlay.ui:19
|
||||
msgid "Open preferences"
|
||||
msgstr ""
|
||||
msgstr "افتح التفضيلات"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-help-overlay.ui:25
|
||||
msgid "Show shortcuts"
|
||||
msgstr "إظهار الاختصارات"
|
||||
msgstr "أظهِر الاختصارات"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-help-overlay.ui:31
|
||||
msgid "Toggle fullscreen"
|
||||
msgstr "تبديل ملء الشاشة"
|
||||
msgstr "بدِّل ملء الشاشة"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-help-overlay.ui:32
|
||||
msgid "Double tap | Double click"
|
||||
@@ -122,7 +122,7 @@ msgstr ""
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-help-overlay.ui:51
|
||||
msgid "Quit"
|
||||
msgstr "خروج"
|
||||
msgstr "اخرج"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-help-overlay.ui:59
|
||||
#: src/bin/clapper-app/ui/clapper-app-info-window.ui:32
|
||||
@@ -133,13 +133,13 @@ msgstr "الوسائط"
|
||||
#: src/bin/clapper-app/ui/clapper-app-initial-state.ui:55
|
||||
#: src/bin/clapper-app/ui/clapper-app-queue-list.ui:178
|
||||
msgid "Add Files…"
|
||||
msgstr ""
|
||||
msgstr "أضِف ملفات…"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-help-overlay.ui:68
|
||||
#: src/bin/clapper-app/ui/clapper-app-initial-state.ui:65
|
||||
#: src/bin/clapper-app/ui/clapper-app-queue-list.ui:182
|
||||
msgid "Add URI…"
|
||||
msgstr ""
|
||||
msgstr "أضِف URI…"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-help-overlay.ui:76
|
||||
msgid "Queue"
|
||||
@@ -148,12 +148,12 @@ msgstr ""
|
||||
#: src/bin/clapper-app/ui/clapper-app-help-overlay.ui:80
|
||||
#: src/bin/clapper-app/ui/clapper-app-help-overlay.ui:87
|
||||
msgid "Next item"
|
||||
msgstr "المحتوى التالي"
|
||||
msgstr "العنصر التالي"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-help-overlay.ui:94
|
||||
#: src/bin/clapper-app/ui/clapper-app-help-overlay.ui:101
|
||||
msgid "Previous item"
|
||||
msgstr "المحتوى السابق"
|
||||
msgstr "العنصر السابق"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-help-overlay.ui:107
|
||||
msgid "Change progression mode"
|
||||
@@ -162,11 +162,11 @@ msgstr ""
|
||||
#: src/bin/clapper-app/ui/clapper-app-help-overlay.ui:115
|
||||
#: src/bin/clapper-app/ui/clapper-app-preferences-window.ui:76
|
||||
msgid "Playback"
|
||||
msgstr "المشغل"
|
||||
msgstr "التشغيل"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-help-overlay.ui:118
|
||||
msgid "Toggle play"
|
||||
msgstr "بَدْءّ / إيقاف"
|
||||
msgstr "بدِّل التشغيل"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-help-overlay.ui:119
|
||||
msgid "Tap | Left click"
|
||||
@@ -175,7 +175,7 @@ msgstr ""
|
||||
#: src/bin/clapper-app/ui/clapper-app-help-overlay.ui:126
|
||||
#: src/bin/clapper-app/ui/clapper-app-help-overlay.ui:134
|
||||
msgid "Seek forward"
|
||||
msgstr "التقدم للأمام"
|
||||
msgstr "تقدَم للأمام"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-help-overlay.ui:127
|
||||
#: src/bin/clapper-app/ui/clapper-app-help-overlay.ui:151
|
||||
@@ -190,11 +190,11 @@ msgstr ""
|
||||
#: src/bin/clapper-app/ui/clapper-app-help-overlay.ui:142
|
||||
#: src/bin/clapper-app/ui/clapper-app-help-overlay.ui:150
|
||||
msgid "Seek backward"
|
||||
msgstr "الرجوع للوراء"
|
||||
msgstr "عُد للوراء"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-help-overlay.ui:157
|
||||
msgid "Volume up"
|
||||
msgstr "رفع مستوى الصوت"
|
||||
msgstr "ارفع شدة الصوت"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-help-overlay.ui:158
|
||||
msgid "Scroll up"
|
||||
@@ -202,7 +202,7 @@ msgstr ""
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-help-overlay.ui:164
|
||||
msgid "Volume down"
|
||||
msgstr "خفض مستوى الصوت"
|
||||
msgstr "اخفض شدة الصوت"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-help-overlay.ui:165
|
||||
msgid "Scroll down"
|
||||
@@ -210,7 +210,7 @@ msgstr ""
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-help-overlay.ui:171
|
||||
msgid "Toggle mute"
|
||||
msgstr "كتم الصوت"
|
||||
msgstr "بدِّل الكتم"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-help-overlay.ui:177
|
||||
msgid "Speed up"
|
||||
@@ -232,7 +232,7 @@ msgstr "الفصل السابق"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-info-window.ui:13
|
||||
msgid "Info"
|
||||
msgstr ""
|
||||
msgstr "معلومات"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-info-window.ui:35
|
||||
#: src/bin/clapper-app/ui/clapper-app-subtitle-stream-list-item.ui:14
|
||||
@@ -254,7 +254,7 @@ msgstr ""
|
||||
#: src/bin/clapper-app/ui/clapper-app-info-window.ui:84
|
||||
#: src/bin/clapper-app/clapper-app-list-item-utils.c:36
|
||||
msgid "Video"
|
||||
msgstr ""
|
||||
msgstr "الفيديو"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-info-window.ui:107
|
||||
#: src/bin/clapper-app/ui/clapper-app-preferences-window.ui:80
|
||||
@@ -266,7 +266,7 @@ msgstr "الصوت"
|
||||
#: src/bin/clapper-app/ui/clapper-app-preferences-window.ui:100
|
||||
#: src/bin/clapper-app/clapper-app-list-item-utils.c:42
|
||||
msgid "Subtitles"
|
||||
msgstr "التَّرْجَمَةً"
|
||||
msgstr "الترجَمة"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-info-window.ui:155
|
||||
msgid "Video Playback"
|
||||
@@ -309,11 +309,11 @@ msgstr ""
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-preferences-window.ui:15
|
||||
msgid "Seeking"
|
||||
msgstr "الوضع"
|
||||
msgstr "السعي"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-preferences-window.ui:18
|
||||
msgid "Method"
|
||||
msgstr ""
|
||||
msgstr "الطريقة"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-preferences-window.ui:19
|
||||
msgid "A preferred method used for seeking"
|
||||
@@ -349,15 +349,15 @@ msgstr "النسبة المئوية"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-preferences-window.ui:63
|
||||
msgid "Features"
|
||||
msgstr ""
|
||||
msgstr "الميزات"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-preferences-window.ui:66
|
||||
msgid "Server"
|
||||
msgstr "الخادم"
|
||||
msgstr "الخادوم"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-preferences-window.ui:67
|
||||
msgid "Control player remotely"
|
||||
msgstr "التحكم بالوسائط عن بعد"
|
||||
msgstr "يتحكم بالوسائط عن بعد"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-preferences-window.ui:83
|
||||
#: src/bin/clapper-app/ui/clapper-app-preferences-window.ui:103
|
||||
@@ -374,7 +374,7 @@ msgstr ""
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-preferences-window.ui:118
|
||||
msgid "Default font"
|
||||
msgstr "الخط الافتراضي"
|
||||
msgstr "الخط المبدئي"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-preferences-window.ui:119
|
||||
msgid "Text font used for subtitles when media does not explicitly specify one"
|
||||
@@ -382,15 +382,15 @@ msgstr ""
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-preferences-window.ui:137
|
||||
msgid "Tweaks"
|
||||
msgstr "تعديلات"
|
||||
msgstr "التطويعات"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-preferences-window.ui:144
|
||||
msgid "Plugin ranking"
|
||||
msgstr "أعدادات الإضافات"
|
||||
msgstr "منازل الملحقات"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-preferences-window.ui:145
|
||||
msgid "Alter default ranks of GStreamer plugins"
|
||||
msgstr "تغيير الأعدادات الافتراضية للأضافات GStreamer"
|
||||
msgstr "يغيِّر المنازل المبدئية لملحقات GStreamer"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-preferences-window.ui:164
|
||||
msgid "Plugin Ranking"
|
||||
@@ -443,11 +443,11 @@ msgstr ""
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-uri-dialog.ui:18
|
||||
msgid "Enter or drop URI here"
|
||||
msgstr "أدخل أو الصق URI هنا"
|
||||
msgstr "أدخِل أو أسقِط URI هنا"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-uri-dialog.ui:22
|
||||
msgid "Cancel"
|
||||
msgstr "إلغاء"
|
||||
msgstr "ألغِ"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-video-stream-list-item.ui:24
|
||||
msgid "Resolution"
|
||||
@@ -464,7 +464,8 @@ msgstr ""
|
||||
#. TRANSLATORS: Put your name(s) here for credits or leave untranslated
|
||||
#: src/bin/clapper-app/clapper-app-about-window.c:47
|
||||
msgid "translator-credits"
|
||||
msgstr "Yousef Fawaz"
|
||||
msgstr "Yousef Fawaz\n"
|
||||
"أحمد النجماوي <iramosu@protonmail.com>"
|
||||
|
||||
#: src/bin/clapper-app/clapper-app-application.c:696
|
||||
msgid "Create a new window"
|
||||
@@ -512,7 +513,7 @@ msgstr ""
|
||||
|
||||
#: src/bin/clapper-app/clapper-app-info-window.c:86
|
||||
msgid "Hardware"
|
||||
msgstr ""
|
||||
msgstr "العتاد"
|
||||
|
||||
#: src/bin/clapper-app/clapper-app-info-window.c:86
|
||||
msgid "Software"
|
||||
@@ -520,7 +521,7 @@ msgstr ""
|
||||
|
||||
#: src/bin/clapper-app/clapper-app-preferences-window.c:441
|
||||
msgid "Accurate"
|
||||
msgstr "دَقيق"
|
||||
msgstr "دقيق"
|
||||
|
||||
#: src/bin/clapper-app/clapper-app-preferences-window.c:443
|
||||
msgid "Normal"
|
||||
|
@@ -3,7 +3,7 @@ msgstr ""
|
||||
"Project-Id-Version: clapper\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2025-02-15 12:47+0100\n"
|
||||
"PO-Revision-Date: 2025-02-15 13:14\n"
|
||||
"PO-Revision-Date: 2025-05-18 14:52\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: Persian\n"
|
||||
"Language: fa_IR\n"
|
||||
@@ -305,7 +305,7 @@ msgstr "جریانهای زیرنویس"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-initial-state.ui:46
|
||||
msgid "Start by adding media to playback queue"
|
||||
msgstr "آغزا با افزودن رسانه به صف پخش"
|
||||
msgstr "آغاز با افزودن رسانه به صف پخش"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-preferences-window.ui:15
|
||||
msgid "Seeking"
|
||||
@@ -402,7 +402,7 @@ msgstr "افزایههای موجود"
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-preferences-window.ui:183
|
||||
msgid "Select a plugin and its feature to override rank for. When multiple elements have similiar capabilities, the one with highest value is preferred."
|
||||
msgstr "گزینش افزایه و ویژگیش برای پایمالی رتبه دهیش. هنگامی که چندین عنصر قابلیتّای مشابهی دارند، آنی که بیشترین رتبه را دارد ترجیح داده میشود."
|
||||
msgstr "گزینش افزایه و ویژگیش برای پایمالی رتبه دهیش. هنگامی که چندین عنصر قابلیتهای مشابهی دارند، آنی که بیشترین رتبه را دارد ترجیح داده میشود."
|
||||
|
||||
#: src/bin/clapper-app/ui/clapper-app-preferences-window.ui:186
|
||||
msgid "Plugin"
|
||||
|
@@ -3,7 +3,7 @@ msgstr ""
|
||||
"Project-Id-Version: clapper\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2025-02-15 12:47+0100\n"
|
||||
"PO-Revision-Date: 2025-02-15 12:11\n"
|
||||
"PO-Revision-Date: 2025-05-01 13:52\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: Chinese Simplified\n"
|
||||
"Language: zh_CN\n"
|
||||
@@ -33,7 +33,7 @@ msgstr "播放视频和音乐"
|
||||
#. Translators: Search terms to find this application. Do NOT translate the semicolons!
|
||||
#: src/bin/clapper-app/data/applications/com.github.rafostar.Clapper.desktop.in:16
|
||||
msgid "Video;Movie;Film;Clip;Series;Player;Playlist;DVD;TV;Disc;"
|
||||
msgstr ""
|
||||
msgstr "视频;电影;影片;短片;连续剧;播放器;播放列表;DVD;电视;唱片;"
|
||||
|
||||
#: src/bin/clapper-app/data/applications/com.github.rafostar.Clapper.desktop.in:22
|
||||
#: src/bin/clapper-app/ui/clapper-app-headerbar.ui:183
|
||||
|
@@ -136,24 +136,6 @@
|
||||
<object class="AdwPreferencesPage">
|
||||
<property name="title" translatable="yes">Tweaks</property>
|
||||
<property name="icon-name">applications-engineering-symbolic</property>
|
||||
<child>
|
||||
<object class="AdwPreferencesGroup">
|
||||
<property name="title" translatable="no">Clapper</property>
|
||||
<child>
|
||||
<object class="AdwActionRow">
|
||||
<property name="title" translatable="yes">Enhancers</property>
|
||||
<property name="subtitle" translatable="yes">Browse and configure properties of available enhancers</property>
|
||||
<property name="activatable">true</property>
|
||||
<signal name="activated" handler="enhancers_config_activated_cb"/>
|
||||
<child>
|
||||
<object class="GtkImage">
|
||||
<property name="icon_name">go-next-symbolic</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="AdwPreferencesGroup">
|
||||
<property name="title" translatable="no">GStreamer</property>
|
||||
@@ -178,124 +160,6 @@
|
||||
<class name="preferences"/>
|
||||
</style>
|
||||
</template>
|
||||
<object class="AdwNavigationPage" id="enhancers_subpage">
|
||||
<property name="title" translatable="yes">Clapper Enhancers</property>
|
||||
<property name="child">
|
||||
<object class="AdwToolbarView">
|
||||
<child type="top">
|
||||
<object class="AdwHeaderBar"/>
|
||||
</child>
|
||||
<property name="content">
|
||||
<object class="GtkScrolledWindow">
|
||||
<child>
|
||||
<object class="AdwClamp">
|
||||
<style>
|
||||
<class name="subcontent"/>
|
||||
</style>
|
||||
<child>
|
||||
<object class="GtkStack" id="enhancers_stack">
|
||||
<child>
|
||||
<object class="GtkBox" id="browse_enhancers_page">
|
||||
<property name="orientation">vertical</property>
|
||||
<child>
|
||||
<object class="AdwPreferencesGroup">
|
||||
<property name="title" translatable="yes">Available enhancers</property>
|
||||
<property name="description" translatable="yes">Select an enhancer plugin to view its information and properties to configure.</property>
|
||||
<child>
|
||||
<object class="AdwComboRow" id="enhancers_combo_row">
|
||||
<property name="title" translatable="yes">Enhancer</property>
|
||||
<property name="enable-search">true</property>
|
||||
<property name="expression">
|
||||
<lookup type="ClapperEnhancerProxy" name="friendly-name"/>
|
||||
</property>
|
||||
<signal name="notify::selected" handler="selected_enhancer_changed_cb"/>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="orientation">vertical</property>
|
||||
<binding name="visible">
|
||||
<closure type="gboolean" function="list_has_selection_closure">
|
||||
<lookup name="selected">enhancers_combo_row</lookup>
|
||||
</closure>
|
||||
</binding>
|
||||
<child>
|
||||
<object class="AdwPreferencesGroup">
|
||||
<property name="title" translatable="yes">Information</property>
|
||||
<child>
|
||||
<object class="AdwActionRow">
|
||||
<property name="title" translatable="yes">Module</property>
|
||||
<binding name="subtitle">
|
||||
<lookup name="module-name" type="ClapperEnhancerProxy">
|
||||
<lookup name="selected-item">enhancers_combo_row</lookup>
|
||||
</lookup>
|
||||
</binding>
|
||||
<style>
|
||||
<class name="property"/>
|
||||
</style>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="AdwActionRow">
|
||||
<property name="title" translatable="yes">Description</property>
|
||||
<binding name="subtitle">
|
||||
<lookup name="description" type="ClapperEnhancerProxy">
|
||||
<lookup name="selected-item">enhancers_combo_row</lookup>
|
||||
</lookup>
|
||||
</binding>
|
||||
<style>
|
||||
<class name="property"/>
|
||||
</style>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="AdwActionRow">
|
||||
<property name="title" translatable="yes">Version</property>
|
||||
<binding name="subtitle">
|
||||
<lookup name="version" type="ClapperEnhancerProxy">
|
||||
<lookup name="selected-item">enhancers_combo_row</lookup>
|
||||
</lookup>
|
||||
</binding>
|
||||
<style>
|
||||
<class name="property"/>
|
||||
</style>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="AdwPreferencesGroup" id="enhancer_config_group">
|
||||
<property name="title" translatable="yes">Properties</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="AdwStatusPage" id="no_enhancers_page">
|
||||
<property name="vexpand">true</property>
|
||||
<property name="hexpand">true</property>
|
||||
<property name="icon-name">edit-find-symbolic</property>
|
||||
<property name="title" translatable="yes">No Clapper Enhancers Found</property>
|
||||
<property name="description" translatable="yes">Install some to add more cool functionalities to the player!</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</property>
|
||||
</object>
|
||||
</property>
|
||||
<signal name="unrealize" handler="plugin_ranking_unrealize_cb"/>
|
||||
<style>
|
||||
<class name="configsubpage"/>
|
||||
</style>
|
||||
</object>
|
||||
<object class="AdwNavigationPage" id="plugins_subpage">
|
||||
<property name="title" translatable="yes">Plugin Ranking</property>
|
||||
<property name="child">
|
||||
@@ -376,7 +240,7 @@
|
||||
</property>
|
||||
<signal name="unrealize" handler="plugin_ranking_unrealize_cb"/>
|
||||
<style>
|
||||
<class name="configsubpage"/>
|
||||
<class name="pluginssubpage"/>
|
||||
</style>
|
||||
</object>
|
||||
</interface>
|
||||
|
@@ -1,268 +0,0 @@
|
||||
/* Clapper GTK Integration Library
|
||||
* Copyright (C) 2025 Rafał Dzięgiel <rafostar.github@gmail.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, see
|
||||
* <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* ClapperGtkAudio:
|
||||
*
|
||||
* A GTK widget for audio playback with Clapper API.
|
||||
*
|
||||
* #ClapperGtkAudio is a widget meant for integrating audio playback
|
||||
* within GTK application. It exposes [class@Clapper.Player] through its
|
||||
* base class [property@ClapperGtk.Av:player] property.
|
||||
*
|
||||
* Other widgets (buttons, seek bar, etc.) provided by `ClapperGtk` library, once placed
|
||||
* anywhere inside audio container (including nesting within another widget like [class@Gtk.Box])
|
||||
* will automatically control #ClapperGtkAudio they are within. This allows to freely create
|
||||
* custom UI best suited for specific application.
|
||||
*
|
||||
* # Basic usage
|
||||
*
|
||||
* A typical use case is to embed audio widget as part of your app where audio playback
|
||||
* is needed (can be even the very first child of the window). Get the [class@Clapper.Player]
|
||||
* belonging to the AV widget and start adding new [class@Clapper.MediaItem] items to the
|
||||
* [class@Clapper.Queue] for playback. For more information please refer to the Clapper
|
||||
* playback library documentation.
|
||||
*
|
||||
* # Actions
|
||||
*
|
||||
* You can use built-in actions of parent [class@ClapperGtk.Av].
|
||||
* See its documentation for the list of available ones.
|
||||
*
|
||||
* # ClapperGtkAudio as GtkBuildable
|
||||
*
|
||||
* #ClapperGtkAudio implementation of the [iface@Gtk.Buildable] interface supports
|
||||
* placing a single widget (which might then hold multiple widgets) as `<child>` element.
|
||||
*
|
||||
* ```xml
|
||||
* <object class="ClapperGtkAudio" id="audio">
|
||||
* <child>
|
||||
* <object class="GtkBox">
|
||||
* <property name="orientation">horizontal</property>
|
||||
* <child>
|
||||
* <object class="ClapperGtkPreviousItemButton">
|
||||
* </child>
|
||||
* <child>
|
||||
* <object class="ClapperGtkTogglePlayButton">
|
||||
* </child>
|
||||
* <child>
|
||||
* <object class="ClapperGtkNextItemButton">
|
||||
* </child>
|
||||
* </object>
|
||||
* </child>
|
||||
* </object>
|
||||
* ```
|
||||
*
|
||||
* Since: 0.10
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "clapper-gtk-audio.h"
|
||||
|
||||
#define GST_CAT_DEFAULT clapper_gtk_audio_debug
|
||||
GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);
|
||||
|
||||
struct _ClapperGtkAudio
|
||||
{
|
||||
ClapperGtkAv parent;
|
||||
|
||||
GtkWidget *child;
|
||||
};
|
||||
|
||||
static void
|
||||
clapper_gtk_audio_add_child (GtkBuildable *buildable,
|
||||
GtkBuilder *builder, GObject *child, const char *type)
|
||||
{
|
||||
if (GTK_IS_WIDGET (child)) {
|
||||
clapper_gtk_audio_set_child (CLAPPER_GTK_AUDIO (buildable), GTK_WIDGET (child));
|
||||
} else {
|
||||
GtkBuildableIface *parent_iface = g_type_interface_peek_parent (GTK_BUILDABLE_GET_IFACE (buildable));
|
||||
parent_iface->add_child (buildable, builder, child, type);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
_buildable_iface_init (GtkBuildableIface *iface)
|
||||
{
|
||||
iface->add_child = clapper_gtk_audio_add_child;
|
||||
}
|
||||
|
||||
#define parent_class clapper_gtk_audio_parent_class
|
||||
G_DEFINE_TYPE_WITH_CODE (ClapperGtkAudio, clapper_gtk_audio, CLAPPER_GTK_TYPE_AV,
|
||||
G_IMPLEMENT_INTERFACE (GTK_TYPE_BUILDABLE, _buildable_iface_init))
|
||||
|
||||
enum
|
||||
{
|
||||
PROP_0,
|
||||
PROP_CHILD,
|
||||
PROP_LAST
|
||||
};
|
||||
|
||||
static GParamSpec *param_specs[PROP_LAST] = { NULL, };
|
||||
|
||||
static inline void
|
||||
_unparent_child (ClapperGtkAudio *self)
|
||||
{
|
||||
GtkWidget *child;
|
||||
|
||||
if ((child = gtk_widget_get_first_child (GTK_WIDGET (self))))
|
||||
gtk_widget_unparent (child);
|
||||
}
|
||||
|
||||
/**
|
||||
* clapper_gtk_audio_new:
|
||||
*
|
||||
* Creates a new #ClapperGtkAudio instance.
|
||||
*
|
||||
* Newly created audio widget will also have set "scaletempo" GStreamer element
|
||||
* as default audio filter on its [class@Clapper.Player] and disable video and
|
||||
* subtitle streams. This can be changed after construction by setting
|
||||
* corresponding player properties.
|
||||
*
|
||||
* Returns: a new audio #GtkWidget.
|
||||
*/
|
||||
GtkWidget *
|
||||
clapper_gtk_audio_new (void)
|
||||
{
|
||||
return g_object_new (CLAPPER_GTK_TYPE_AUDIO, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* clapper_gtk_audio_set_child:
|
||||
* @audio: a #ClapperGtkAudio
|
||||
* @child: (nullable): a #GtkWidget
|
||||
*
|
||||
* Set a child #GtkWidget of @audio.
|
||||
*/
|
||||
void
|
||||
clapper_gtk_audio_set_child (ClapperGtkAudio *self, GtkWidget *child)
|
||||
{
|
||||
g_return_if_fail (CLAPPER_GTK_IS_AUDIO (self));
|
||||
g_return_if_fail (GTK_IS_WIDGET (child));
|
||||
|
||||
_unparent_child (self);
|
||||
if (child)
|
||||
gtk_widget_set_parent (child, GTK_WIDGET (self));
|
||||
}
|
||||
|
||||
/**
|
||||
* clapper_gtk_audio_get_child:
|
||||
* @audio: a #ClapperGtkAudio
|
||||
*
|
||||
* Get a child #GtkWidget of @audio.
|
||||
*
|
||||
* Returns: (transfer none) (nullable): #GtkWidget set as child.
|
||||
*/
|
||||
GtkWidget *
|
||||
clapper_gtk_audio_get_child (ClapperGtkAudio *self)
|
||||
{
|
||||
g_return_val_if_fail (CLAPPER_GTK_IS_AUDIO (self), NULL);
|
||||
|
||||
return gtk_widget_get_first_child (GTK_WIDGET (self));
|
||||
}
|
||||
|
||||
static void
|
||||
clapper_gtk_audio_init (ClapperGtkAudio *self)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
clapper_gtk_audio_constructed (GObject *object)
|
||||
{
|
||||
ClapperGtkAudio *self = CLAPPER_GTK_AUDIO_CAST (object);
|
||||
ClapperPlayer *player;
|
||||
|
||||
G_OBJECT_CLASS (parent_class)->constructed (object);
|
||||
|
||||
player = clapper_gtk_av_get_player (CLAPPER_GTK_AV_CAST (self));
|
||||
|
||||
clapper_player_set_video_enabled (player, FALSE);
|
||||
clapper_player_set_subtitles_enabled (player, FALSE);
|
||||
}
|
||||
|
||||
static void
|
||||
clapper_gtk_audio_dispose (GObject *object)
|
||||
{
|
||||
ClapperGtkAudio *self = CLAPPER_GTK_AUDIO_CAST (object);
|
||||
|
||||
_unparent_child (self);
|
||||
|
||||
G_OBJECT_CLASS (parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
clapper_gtk_audio_get_property (GObject *object, guint prop_id,
|
||||
GValue *value, GParamSpec *pspec)
|
||||
{
|
||||
ClapperGtkAudio *self = CLAPPER_GTK_AUDIO_CAST (object);
|
||||
|
||||
switch (prop_id) {
|
||||
case PROP_CHILD:
|
||||
g_value_set_object (value, clapper_gtk_audio_get_child (self));
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
clapper_gtk_audio_set_property (GObject *object, guint prop_id,
|
||||
const GValue *value, GParamSpec *pspec)
|
||||
{
|
||||
ClapperGtkAudio *self = CLAPPER_GTK_AUDIO_CAST (object);
|
||||
|
||||
switch (prop_id) {
|
||||
case PROP_CHILD:
|
||||
clapper_gtk_audio_set_child (self, g_value_get_object (value));
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
clapper_gtk_audio_class_init (ClapperGtkAudioClass *klass)
|
||||
{
|
||||
GObjectClass *gobject_class = (GObjectClass *) klass;
|
||||
GtkWidgetClass *widget_class = (GtkWidgetClass *) klass;
|
||||
|
||||
GST_DEBUG_CATEGORY_INIT (GST_CAT_DEFAULT, "clappergtkaudio", GST_DEBUG_FG_MAGENTA,
|
||||
"Clapper GTK Audio");
|
||||
|
||||
gobject_class->constructed = clapper_gtk_audio_constructed;
|
||||
gobject_class->get_property = clapper_gtk_audio_get_property;
|
||||
gobject_class->set_property = clapper_gtk_audio_set_property;
|
||||
gobject_class->dispose = clapper_gtk_audio_dispose;
|
||||
|
||||
/**
|
||||
* ClapperGtkAudio:child:
|
||||
*
|
||||
* The child widget of `ClapperGtkAudio`.
|
||||
*/
|
||||
param_specs[PROP_CHILD] = g_param_spec_object ("child",
|
||||
NULL, NULL, GTK_TYPE_WIDGET,
|
||||
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
|
||||
|
||||
g_object_class_install_properties (gobject_class, PROP_LAST, param_specs);
|
||||
|
||||
gtk_widget_class_set_layout_manager_type (widget_class, GTK_TYPE_BIN_LAYOUT);
|
||||
gtk_widget_class_set_accessible_role (widget_class, GTK_ACCESSIBLE_ROLE_GENERIC);
|
||||
gtk_widget_class_set_css_name (widget_class, "clapper-gtk-audio");
|
||||
}
|
@@ -1,49 +0,0 @@
|
||||
/* Clapper GTK Integration Library
|
||||
* Copyright (C) 2025 Rafał Dzięgiel <rafostar.github@gmail.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, see
|
||||
* <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#if !defined(__CLAPPER_GTK_INSIDE__) && !defined(CLAPPER_GTK_COMPILATION)
|
||||
#error "Only <clapper-gtk/clapper-gtk.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#include <glib.h>
|
||||
#include <glib-object.h>
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#include <clapper-gtk/clapper-gtk-av.h>
|
||||
#include <clapper-gtk/clapper-gtk-visibility.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define CLAPPER_GTK_TYPE_AUDIO (clapper_gtk_audio_get_type())
|
||||
#define CLAPPER_GTK_AUDIO_CAST(obj) ((ClapperGtkAudio *)(obj))
|
||||
|
||||
CLAPPER_GTK_API
|
||||
G_DECLARE_FINAL_TYPE (ClapperGtkAudio, clapper_gtk_audio, CLAPPER_GTK, AUDIO, ClapperGtkAv)
|
||||
|
||||
CLAPPER_GTK_API
|
||||
GtkWidget * clapper_gtk_audio_new (void);
|
||||
|
||||
CLAPPER_GTK_API
|
||||
void clapper_gtk_audio_set_child (ClapperGtkAudio *audio, GtkWidget *child);
|
||||
|
||||
CLAPPER_GTK_API
|
||||
GtkWidget * clapper_gtk_audio_get_child (ClapperGtkAudio *audio);
|
||||
|
||||
G_END_DECLS
|
@@ -1,645 +0,0 @@
|
||||
/* Clapper GTK Integration Library
|
||||
* Copyright (C) 2025 Rafał Dzięgiel <rafostar.github@gmail.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, see
|
||||
* <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* ClapperGtkAv:
|
||||
*
|
||||
* A base class for GTK audio and video widgets.
|
||||
*
|
||||
* See its descendants: [class@ClapperGtk.Audio] and [class@ClapperGtk.Video].
|
||||
*
|
||||
* # Actions
|
||||
*
|
||||
* #ClapperGtkAv defines a set of built-in actions:
|
||||
*
|
||||
* ```yaml
|
||||
* - "av.toggle-play": toggle play/pause
|
||||
* - "av.play": start/resume playback
|
||||
* - "av.pause": pause playback
|
||||
* - "av.stop": stop playback
|
||||
* - "av.seek": seek to position (variant "d")
|
||||
* - "av.seek-custom": seek to position using seek method (variant "(di)")
|
||||
* - "av.toggle-mute": toggle mute state
|
||||
* - "av.set-mute": set mute state (variant "b")
|
||||
* - "av.volume-up": increase volume by 2%
|
||||
* - "av.volume-down": decrease volume by 2%
|
||||
* - "av.set-volume": set volume to specified value (variant "d")
|
||||
* - "av.speed-up": increase speed (from 0.05x - 2x range to nearest quarter)
|
||||
* - "av.speed-down": decrease speed (from 0.05x - 2x range to nearest quarter)
|
||||
* - "av.set-speed": set speed to specified value (variant "d")
|
||||
* - "av.previous-item": select previous item in queue
|
||||
* - "av.next-item": select next item in queue
|
||||
* - "av.select-item": select item at specified index in queue (variant "u")
|
||||
* ```
|
||||
*
|
||||
* Since: 0.10
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#include "clapper-gtk-av.h"
|
||||
|
||||
#define PERCENTAGE_ROUND(a) (round ((gdouble) a / 0.01) * 0.01)
|
||||
|
||||
#define DEFAULT_AUTO_INHIBIT FALSE
|
||||
|
||||
#define GST_CAT_DEFAULT clapper_gtk_av_debug
|
||||
GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);
|
||||
|
||||
typedef struct _ClapperGtkAvPrivate ClapperGtkAvPrivate;
|
||||
|
||||
struct _ClapperGtkAvPrivate
|
||||
{
|
||||
ClapperPlayer *player;
|
||||
gboolean auto_inhibit;
|
||||
|
||||
guint inhibit_cookie;
|
||||
};
|
||||
|
||||
#define parent_class clapper_gtk_av_parent_class
|
||||
G_DEFINE_TYPE_WITH_PRIVATE (ClapperGtkAv, clapper_gtk_av, GTK_TYPE_WIDGET)
|
||||
|
||||
enum
|
||||
{
|
||||
PROP_0,
|
||||
PROP_PLAYER,
|
||||
PROP_AUTO_INHIBIT,
|
||||
PROP_INHIBITED,
|
||||
PROP_LAST
|
||||
};
|
||||
|
||||
static gboolean provider_added = FALSE;
|
||||
static GParamSpec *param_specs[PROP_LAST] = { NULL, };
|
||||
|
||||
static void
|
||||
toggle_play_action_cb (GtkWidget *widget, const gchar *action_name, GVariant *parameter)
|
||||
{
|
||||
ClapperGtkAv *self = CLAPPER_GTK_AV_CAST (widget);
|
||||
ClapperPlayer *player = clapper_gtk_av_get_player (self);
|
||||
|
||||
switch (clapper_player_get_state (player)) {
|
||||
case CLAPPER_PLAYER_STATE_PLAYING:
|
||||
clapper_player_pause (player);
|
||||
break;
|
||||
case CLAPPER_PLAYER_STATE_STOPPED:
|
||||
case CLAPPER_PLAYER_STATE_PAUSED:
|
||||
clapper_player_play (player);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
play_action_cb (GtkWidget *widget, const gchar *action_name, GVariant *parameter)
|
||||
{
|
||||
ClapperGtkAv *self = CLAPPER_GTK_AV_CAST (widget);
|
||||
ClapperPlayer *player = clapper_gtk_av_get_player (self);
|
||||
|
||||
clapper_player_play (player);
|
||||
}
|
||||
|
||||
static void
|
||||
pause_action_cb (GtkWidget *widget, const gchar *action_name, GVariant *parameter)
|
||||
{
|
||||
ClapperGtkAv *self = CLAPPER_GTK_AV_CAST (widget);
|
||||
ClapperPlayer *player = clapper_gtk_av_get_player (self);
|
||||
|
||||
clapper_player_pause (player);
|
||||
}
|
||||
|
||||
static void
|
||||
stop_action_cb (GtkWidget *widget, const gchar *action_name, GVariant *parameter)
|
||||
{
|
||||
ClapperGtkAv *self = CLAPPER_GTK_AV_CAST (widget);
|
||||
ClapperPlayer *player = clapper_gtk_av_get_player (self);
|
||||
|
||||
clapper_player_stop (player);
|
||||
}
|
||||
|
||||
static void
|
||||
seek_action_cb (GtkWidget *widget, const gchar *action_name, GVariant *parameter)
|
||||
{
|
||||
ClapperGtkAv *self = CLAPPER_GTK_AV_CAST (widget);
|
||||
ClapperPlayer *player = clapper_gtk_av_get_player (self);
|
||||
gdouble position = g_variant_get_double (parameter);
|
||||
|
||||
clapper_player_seek (player, position);
|
||||
}
|
||||
|
||||
static void
|
||||
seek_custom_action_cb (GtkWidget *widget, const gchar *action_name, GVariant *parameter)
|
||||
{
|
||||
ClapperGtkAv *self = CLAPPER_GTK_AV_CAST (widget);
|
||||
ClapperPlayer *player = clapper_gtk_av_get_player (self);
|
||||
ClapperPlayerSeekMethod method = CLAPPER_PLAYER_SEEK_METHOD_NORMAL;
|
||||
gdouble position = 0;
|
||||
|
||||
g_variant_get (parameter, "(di)", &position, &method);
|
||||
clapper_player_seek_custom (player, position, method);
|
||||
}
|
||||
|
||||
static void
|
||||
toggle_mute_action_cb (GtkWidget *widget, const gchar *action_name, GVariant *parameter)
|
||||
{
|
||||
ClapperGtkAv *self = CLAPPER_GTK_AV_CAST (widget);
|
||||
ClapperPlayer *player = clapper_gtk_av_get_player (self);
|
||||
|
||||
clapper_player_set_mute (player, !clapper_player_get_mute (player));
|
||||
}
|
||||
|
||||
static void
|
||||
set_mute_action_cb (GtkWidget *widget, const gchar *action_name, GVariant *parameter)
|
||||
{
|
||||
ClapperGtkAv *self = CLAPPER_GTK_AV_CAST (widget);
|
||||
ClapperPlayer *player = clapper_gtk_av_get_player (self);
|
||||
gboolean mute = g_variant_get_boolean (parameter);
|
||||
|
||||
clapper_player_set_mute (player, mute);
|
||||
}
|
||||
|
||||
static void
|
||||
volume_up_action_cb (GtkWidget *widget, const gchar *action_name, GVariant *parameter)
|
||||
{
|
||||
ClapperGtkAv *self = CLAPPER_GTK_AV_CAST (widget);
|
||||
ClapperPlayer *player = clapper_gtk_av_get_player (self);
|
||||
gdouble volume = (clapper_player_get_volume (player) + 0.02);
|
||||
|
||||
if (volume > 2.0)
|
||||
volume = 2.0;
|
||||
|
||||
clapper_player_set_volume (player, PERCENTAGE_ROUND (volume));
|
||||
}
|
||||
|
||||
static void
|
||||
volume_down_action_cb (GtkWidget *widget, const gchar *action_name, GVariant *parameter)
|
||||
{
|
||||
ClapperGtkAv *self = CLAPPER_GTK_AV_CAST (widget);
|
||||
ClapperPlayer *player = clapper_gtk_av_get_player (self);
|
||||
gdouble volume = (clapper_player_get_volume (player) - 0.02);
|
||||
|
||||
if (volume < 0)
|
||||
volume = 0;
|
||||
|
||||
clapper_player_set_volume (player, PERCENTAGE_ROUND (volume));
|
||||
}
|
||||
|
||||
static void
|
||||
set_volume_action_cb (GtkWidget *widget, const gchar *action_name, GVariant *parameter)
|
||||
{
|
||||
ClapperGtkAv *self = CLAPPER_GTK_AV_CAST (widget);
|
||||
ClapperPlayer *player = clapper_gtk_av_get_player (self);
|
||||
gdouble volume = g_variant_get_double (parameter);
|
||||
|
||||
clapper_player_set_volume (player, volume);
|
||||
}
|
||||
|
||||
static void
|
||||
speed_up_action_cb (GtkWidget *widget, const gchar *action_name, GVariant *parameter)
|
||||
{
|
||||
ClapperGtkAv *self = CLAPPER_GTK_AV_CAST (widget);
|
||||
ClapperPlayer *player = clapper_gtk_av_get_player (self);
|
||||
gdouble dest, speed = clapper_player_get_speed (player);
|
||||
|
||||
if (speed >= 2.0)
|
||||
return;
|
||||
|
||||
dest = 0.25;
|
||||
while (speed >= dest)
|
||||
dest += 0.25;
|
||||
|
||||
if (dest > 2.0)
|
||||
dest = 2.0;
|
||||
|
||||
clapper_player_set_speed (player, dest);
|
||||
}
|
||||
|
||||
static void
|
||||
speed_down_action_cb (GtkWidget *widget, const gchar *action_name, GVariant *parameter)
|
||||
{
|
||||
ClapperGtkAv *self = CLAPPER_GTK_AV_CAST (widget);
|
||||
ClapperPlayer *player = clapper_gtk_av_get_player (self);
|
||||
gdouble dest, speed = clapper_player_get_speed (player);
|
||||
|
||||
if (speed <= 0.05)
|
||||
return;
|
||||
|
||||
dest = 2.0;
|
||||
while (speed <= dest)
|
||||
dest -= 0.25;
|
||||
|
||||
if (dest < 0.05)
|
||||
dest = 0.05;
|
||||
|
||||
clapper_player_set_speed (player, dest);
|
||||
}
|
||||
|
||||
static void
|
||||
set_speed_action_cb (GtkWidget *widget, const gchar *action_name, GVariant *parameter)
|
||||
{
|
||||
ClapperGtkAv *self = CLAPPER_GTK_AV_CAST (widget);
|
||||
ClapperPlayer *player = clapper_gtk_av_get_player (self);
|
||||
gdouble speed = g_variant_get_double (parameter);
|
||||
|
||||
clapper_player_set_speed (player, speed);
|
||||
}
|
||||
|
||||
static void
|
||||
previous_item_action_cb (GtkWidget *widget, const gchar *action_name, GVariant *parameter)
|
||||
{
|
||||
ClapperGtkAv *self = CLAPPER_GTK_AV_CAST (widget);
|
||||
ClapperPlayer *player = clapper_gtk_av_get_player (self);
|
||||
|
||||
clapper_queue_select_previous_item (clapper_player_get_queue (player));
|
||||
}
|
||||
|
||||
static void
|
||||
next_item_action_cb (GtkWidget *widget, const gchar *action_name, GVariant *parameter)
|
||||
{
|
||||
ClapperGtkAv *self = CLAPPER_GTK_AV_CAST (widget);
|
||||
ClapperPlayer *player = clapper_gtk_av_get_player (self);
|
||||
|
||||
clapper_queue_select_next_item (clapper_player_get_queue (player));
|
||||
}
|
||||
|
||||
static void
|
||||
select_item_action_cb (GtkWidget *widget, const gchar *action_name, GVariant *parameter)
|
||||
{
|
||||
ClapperGtkAv *self = CLAPPER_GTK_AV_CAST (widget);
|
||||
ClapperPlayer *player = clapper_gtk_av_get_player (self);
|
||||
guint index = g_variant_get_uint32 (parameter);
|
||||
|
||||
clapper_queue_select_index (clapper_player_get_queue (player), index);
|
||||
}
|
||||
|
||||
static void
|
||||
_ensure_css_provider (void)
|
||||
{
|
||||
GdkDisplay *display;
|
||||
|
||||
if (provider_added)
|
||||
return;
|
||||
|
||||
display = gdk_display_get_default ();
|
||||
|
||||
if (G_LIKELY (display != NULL)) {
|
||||
GtkCssProvider *provider = gtk_css_provider_new ();
|
||||
gtk_css_provider_load_from_resource (provider,
|
||||
CLAPPER_GTK_RESOURCE_PREFIX "/css/styles.css");
|
||||
|
||||
gtk_style_context_add_provider_for_display (display,
|
||||
(GtkStyleProvider *) provider, GTK_STYLE_PROVIDER_PRIORITY_APPLICATION - 1);
|
||||
g_object_unref (provider);
|
||||
|
||||
provider_added = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
static inline void
|
||||
_set_inhibit_session (ClapperGtkAv *self, gboolean inhibit)
|
||||
{
|
||||
ClapperGtkAvPrivate *priv = clapper_gtk_av_get_instance_private (self);
|
||||
GtkRoot *root;
|
||||
GApplication *app;
|
||||
gboolean inhibited = (priv->inhibit_cookie != 0);
|
||||
|
||||
if (inhibited == inhibit)
|
||||
return;
|
||||
|
||||
GST_DEBUG_OBJECT (self, "Trying to %sinhibit session...", (inhibit) ? "" : "un");
|
||||
|
||||
root = gtk_widget_get_root (GTK_WIDGET (self));
|
||||
|
||||
if (!root && !GTK_IS_WINDOW (root)) {
|
||||
GST_WARNING_OBJECT (self, "Cannot %sinhibit session "
|
||||
"without root window", (inhibit) ? "" : "un");
|
||||
return;
|
||||
}
|
||||
|
||||
/* NOTE: Not using application from window prop,
|
||||
* as it goes away early when unrooting */
|
||||
app = g_application_get_default ();
|
||||
|
||||
if (!app && !GTK_IS_APPLICATION (app)) {
|
||||
GST_WARNING_OBJECT (self, "Cannot %sinhibit session "
|
||||
"without window application set", (inhibit) ? "" : "un");
|
||||
return;
|
||||
}
|
||||
|
||||
if (inhibited) {
|
||||
gtk_application_uninhibit (GTK_APPLICATION (app), priv->inhibit_cookie);
|
||||
priv->inhibit_cookie = 0;
|
||||
}
|
||||
if (inhibit) {
|
||||
priv->inhibit_cookie = gtk_application_inhibit (GTK_APPLICATION (app),
|
||||
GTK_WINDOW (root), GTK_APPLICATION_INHIBIT_IDLE,
|
||||
"Media is playing");
|
||||
}
|
||||
|
||||
GST_DEBUG_OBJECT (self, "Session %sinhibited", (inhibit) ? "" : "un");
|
||||
g_object_notify_by_pspec (G_OBJECT (self), param_specs[PROP_INHIBITED]);
|
||||
}
|
||||
|
||||
static void
|
||||
_player_state_changed_cb (ClapperPlayer *player,
|
||||
GParamSpec *pspec G_GNUC_UNUSED, ClapperGtkAv *self)
|
||||
{
|
||||
ClapperGtkAvPrivate *priv = clapper_gtk_av_get_instance_private (self);
|
||||
|
||||
if (priv->auto_inhibit) {
|
||||
ClapperPlayerState state = clapper_player_get_state (player);
|
||||
_set_inhibit_session (self, state == CLAPPER_PLAYER_STATE_PLAYING);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* clapper_gtk_av_get_player:
|
||||
* @av: a #ClapperGtkAv
|
||||
*
|
||||
* Get #ClapperPlayer used by this #ClapperGtkAv instance.
|
||||
*
|
||||
* Returns: (transfer none): a #ClapperPlayer used by widget.
|
||||
*
|
||||
* Since: 0.10
|
||||
*/
|
||||
ClapperPlayer *
|
||||
clapper_gtk_av_get_player (ClapperGtkAv *self)
|
||||
{
|
||||
ClapperGtkAvPrivate *priv;
|
||||
|
||||
g_return_val_if_fail (CLAPPER_GTK_IS_AV (self), NULL);
|
||||
|
||||
priv = clapper_gtk_av_get_instance_private (self);
|
||||
|
||||
return priv->player;
|
||||
}
|
||||
|
||||
/**
|
||||
* clapper_gtk_av_set_auto_inhibit:
|
||||
* @av: a #ClapperGtkAv
|
||||
* @inhibit: whether to enable automatic session inhibit
|
||||
*
|
||||
* Set whether widget should try to automatically inhibit session
|
||||
* from idling (and possibly screen going black) when media is playing.
|
||||
*
|
||||
* Since: 0.10
|
||||
*/
|
||||
void
|
||||
clapper_gtk_av_set_auto_inhibit (ClapperGtkAv *self, gboolean inhibit)
|
||||
{
|
||||
ClapperGtkAvPrivate *priv;
|
||||
|
||||
g_return_if_fail (CLAPPER_GTK_IS_AV (self));
|
||||
|
||||
priv = clapper_gtk_av_get_instance_private (self);
|
||||
|
||||
if (priv->auto_inhibit != inhibit) {
|
||||
priv->auto_inhibit = inhibit;
|
||||
|
||||
/* Uninhibit if we were auto inhibited earlier */
|
||||
if (!priv->auto_inhibit)
|
||||
_set_inhibit_session (self, FALSE);
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (self), param_specs[PROP_AUTO_INHIBIT]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* clapper_gtk_av_get_auto_inhibit:
|
||||
* @av: a #ClapperGtkAv
|
||||
*
|
||||
* Get whether automatic session inhibit is enabled.
|
||||
*
|
||||
* Returns: %TRUE if enabled, %FALSE otherwise.
|
||||
*
|
||||
* Since: 0.10
|
||||
*/
|
||||
gboolean
|
||||
clapper_gtk_av_get_auto_inhibit (ClapperGtkAv *self)
|
||||
{
|
||||
ClapperGtkAvPrivate *priv;
|
||||
|
||||
g_return_val_if_fail (CLAPPER_GTK_IS_AV (self), FALSE);
|
||||
|
||||
priv = clapper_gtk_av_get_instance_private (self);
|
||||
|
||||
return priv->auto_inhibit;
|
||||
}
|
||||
|
||||
/**
|
||||
* clapper_gtk_av_get_inhibited:
|
||||
* @av: a #ClapperGtkAv
|
||||
*
|
||||
* Get whether session is currently inhibited by
|
||||
* [property@ClapperGtk.Av:auto-inhibit].
|
||||
*
|
||||
* Returns: %TRUE if inhibited, %FALSE otherwise.
|
||||
*
|
||||
* Since: 0.10
|
||||
*/
|
||||
gboolean
|
||||
clapper_gtk_av_get_inhibited (ClapperGtkAv *self)
|
||||
{
|
||||
ClapperGtkAvPrivate *priv;
|
||||
|
||||
g_return_val_if_fail (CLAPPER_GTK_IS_AV (self), FALSE);
|
||||
|
||||
priv = clapper_gtk_av_get_instance_private (self);
|
||||
|
||||
return (priv->inhibit_cookie != 0);
|
||||
}
|
||||
|
||||
static void
|
||||
clapper_gtk_av_root (GtkWidget *widget)
|
||||
{
|
||||
ClapperGtkAv *self = CLAPPER_GTK_AV_CAST (widget);
|
||||
ClapperGtkAvPrivate *priv = clapper_gtk_av_get_instance_private (self);
|
||||
|
||||
_ensure_css_provider ();
|
||||
|
||||
GTK_WIDGET_CLASS (parent_class)->root (widget);
|
||||
|
||||
if (priv->auto_inhibit) {
|
||||
ClapperPlayerState state = clapper_player_get_state (priv->player);
|
||||
_set_inhibit_session (self, state == CLAPPER_PLAYER_STATE_PLAYING);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
clapper_gtk_av_unroot (GtkWidget *widget)
|
||||
{
|
||||
ClapperGtkAv *self = CLAPPER_GTK_AV_CAST (widget);
|
||||
|
||||
_set_inhibit_session (self, FALSE);
|
||||
|
||||
GTK_WIDGET_CLASS (parent_class)->unroot (widget);
|
||||
}
|
||||
|
||||
static void
|
||||
clapper_gtk_av_init (ClapperGtkAv *self)
|
||||
{
|
||||
ClapperGtkAvPrivate *priv = clapper_gtk_av_get_instance_private (self);
|
||||
|
||||
priv->auto_inhibit = DEFAULT_AUTO_INHIBIT;
|
||||
}
|
||||
|
||||
static void
|
||||
clapper_gtk_av_constructed (GObject *object)
|
||||
{
|
||||
ClapperGtkAv *self = CLAPPER_GTK_AV_CAST (object);
|
||||
ClapperGtkAvPrivate *priv = clapper_gtk_av_get_instance_private (self);
|
||||
GstElement *afilter;
|
||||
|
||||
priv->player = clapper_player_new ();
|
||||
|
||||
g_signal_connect (priv->player, "notify::state",
|
||||
G_CALLBACK (_player_state_changed_cb), self);
|
||||
|
||||
afilter = gst_element_factory_make ("scaletempo", NULL);
|
||||
if (G_LIKELY (afilter != NULL))
|
||||
clapper_player_set_audio_filter (priv->player, afilter);
|
||||
|
||||
G_OBJECT_CLASS (parent_class)->constructed (object);
|
||||
}
|
||||
|
||||
static void
|
||||
clapper_gtk_av_dispose (GObject *object)
|
||||
{
|
||||
ClapperGtkAv *self = CLAPPER_GTK_AV_CAST (object);
|
||||
ClapperGtkAvPrivate *priv = clapper_gtk_av_get_instance_private (self);
|
||||
|
||||
/* Something else might still be holding a reference on the player,
|
||||
* thus we should disconnect everything before disposing template */
|
||||
if (priv->player) {
|
||||
g_signal_handlers_disconnect_by_func (priv->player,
|
||||
_player_state_changed_cb, self);
|
||||
}
|
||||
|
||||
gst_clear_object (&priv->player);
|
||||
|
||||
G_OBJECT_CLASS (parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
clapper_gtk_av_get_property (GObject *object, guint prop_id,
|
||||
GValue *value, GParamSpec *pspec)
|
||||
{
|
||||
ClapperGtkAv *self = CLAPPER_GTK_AV_CAST (object);
|
||||
|
||||
switch (prop_id) {
|
||||
case PROP_PLAYER:
|
||||
g_value_set_object (value, clapper_gtk_av_get_player (self));
|
||||
break;
|
||||
case PROP_AUTO_INHIBIT:
|
||||
g_value_set_boolean (value, clapper_gtk_av_get_auto_inhibit (self));
|
||||
break;
|
||||
case PROP_INHIBITED:
|
||||
g_value_set_boolean (value, clapper_gtk_av_get_inhibited (self));
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
clapper_gtk_av_set_property (GObject *object, guint prop_id,
|
||||
const GValue *value, GParamSpec *pspec)
|
||||
{
|
||||
ClapperGtkAv *self = CLAPPER_GTK_AV_CAST (object);
|
||||
|
||||
switch (prop_id) {
|
||||
case PROP_AUTO_INHIBIT:
|
||||
clapper_gtk_av_set_auto_inhibit (self, g_value_get_boolean (value));
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
clapper_gtk_av_class_init (ClapperGtkAvClass *klass)
|
||||
{
|
||||
GObjectClass *gobject_class = (GObjectClass *) klass;
|
||||
GtkWidgetClass *widget_class = (GtkWidgetClass *) klass;
|
||||
|
||||
GST_DEBUG_CATEGORY_INIT (GST_CAT_DEFAULT, "clappergtkav", GST_DEBUG_FG_MAGENTA,
|
||||
"Clapper GTK AV");
|
||||
|
||||
widget_class->root = clapper_gtk_av_root;
|
||||
widget_class->unroot = clapper_gtk_av_unroot;
|
||||
|
||||
gobject_class->constructed = clapper_gtk_av_constructed;
|
||||
gobject_class->get_property = clapper_gtk_av_get_property;
|
||||
gobject_class->set_property = clapper_gtk_av_set_property;
|
||||
gobject_class->dispose = clapper_gtk_av_dispose;
|
||||
|
||||
/**
|
||||
* ClapperGtkAv:player:
|
||||
*
|
||||
* A #ClapperPlayer used by widget.
|
||||
*/
|
||||
param_specs[PROP_PLAYER] = g_param_spec_object ("player",
|
||||
NULL, NULL, CLAPPER_TYPE_PLAYER,
|
||||
G_PARAM_READABLE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
|
||||
|
||||
/**
|
||||
* ClapperGtkAv:auto-inhibit:
|
||||
*
|
||||
* Try to automatically inhibit session when media is playing.
|
||||
*/
|
||||
param_specs[PROP_AUTO_INHIBIT] = g_param_spec_boolean ("auto-inhibit",
|
||||
NULL, NULL, DEFAULT_AUTO_INHIBIT,
|
||||
G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
|
||||
|
||||
/**
|
||||
* ClapperGtkAv:inhibited:
|
||||
*
|
||||
* Get whether session is currently inhibited by playback.
|
||||
*/
|
||||
param_specs[PROP_INHIBITED] = g_param_spec_boolean ("inhibited",
|
||||
NULL, NULL, FALSE,
|
||||
G_PARAM_READABLE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
|
||||
|
||||
g_object_class_install_properties (gobject_class, PROP_LAST, param_specs);
|
||||
|
||||
gtk_widget_class_install_action (widget_class, "av.toggle-play", NULL, toggle_play_action_cb);
|
||||
gtk_widget_class_install_action (widget_class, "av.play", NULL, play_action_cb);
|
||||
gtk_widget_class_install_action (widget_class, "av.pause", NULL, pause_action_cb);
|
||||
gtk_widget_class_install_action (widget_class, "av.stop", NULL, stop_action_cb);
|
||||
gtk_widget_class_install_action (widget_class, "av.seek", "d", seek_action_cb);
|
||||
gtk_widget_class_install_action (widget_class, "av.seek-custom", "(di)", seek_custom_action_cb);
|
||||
gtk_widget_class_install_action (widget_class, "av.toggle-mute", NULL, toggle_mute_action_cb);
|
||||
gtk_widget_class_install_action (widget_class, "av.set-mute", "b", set_mute_action_cb);
|
||||
gtk_widget_class_install_action (widget_class, "av.volume-up", NULL, volume_up_action_cb);
|
||||
gtk_widget_class_install_action (widget_class, "av.volume-down", NULL, volume_down_action_cb);
|
||||
gtk_widget_class_install_action (widget_class, "av.set-volume", "d", set_volume_action_cb);
|
||||
gtk_widget_class_install_action (widget_class, "av.speed-up", NULL, speed_up_action_cb);
|
||||
gtk_widget_class_install_action (widget_class, "av.speed-down", NULL, speed_down_action_cb);
|
||||
gtk_widget_class_install_action (widget_class, "av.set-speed", "d", set_speed_action_cb);
|
||||
gtk_widget_class_install_action (widget_class, "av.previous-item", NULL, previous_item_action_cb);
|
||||
gtk_widget_class_install_action (widget_class, "av.next-item", NULL, next_item_action_cb);
|
||||
gtk_widget_class_install_action (widget_class, "av.select-item", "u", select_item_action_cb);
|
||||
|
||||
gtk_widget_class_set_layout_manager_type (widget_class, GTK_TYPE_BIN_LAYOUT);
|
||||
gtk_widget_class_set_accessible_role (widget_class, GTK_ACCESSIBLE_ROLE_GENERIC);
|
||||
gtk_widget_class_set_css_name (widget_class, "clapper-gtk-av");
|
||||
}
|
@@ -1,60 +0,0 @@
|
||||
/* Clapper GTK Integration Library
|
||||
* Copyright (C) 2025 Rafał Dzięgiel <rafostar.github@gmail.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, see
|
||||
* <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#if !defined(__CLAPPER_GTK_INSIDE__) && !defined(CLAPPER_GTK_COMPILATION)
|
||||
#error "Only <clapper-gtk/clapper-gtk.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#include <glib.h>
|
||||
#include <glib-object.h>
|
||||
#include <gtk/gtk.h>
|
||||
#include <clapper/clapper.h>
|
||||
|
||||
#include <clapper-gtk/clapper-gtk-visibility.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define CLAPPER_GTK_TYPE_AV (clapper_gtk_av_get_type())
|
||||
#define CLAPPER_GTK_AV_CAST(obj) ((ClapperGtkAv *)(obj))
|
||||
|
||||
CLAPPER_GTK_API
|
||||
G_DECLARE_DERIVABLE_TYPE (ClapperGtkAv, clapper_gtk_av, CLAPPER_GTK, AV, GtkWidget)
|
||||
|
||||
struct _ClapperGtkAvClass
|
||||
{
|
||||
GtkWidgetClass parent_class;
|
||||
|
||||
/*< private >*/
|
||||
gpointer padding[4];
|
||||
};
|
||||
|
||||
CLAPPER_GTK_API
|
||||
ClapperPlayer * clapper_gtk_av_get_player (ClapperGtkAv *av);
|
||||
|
||||
CLAPPER_GTK_API
|
||||
void clapper_gtk_av_set_auto_inhibit (ClapperGtkAv *av, gboolean inhibit);
|
||||
|
||||
CLAPPER_GTK_API
|
||||
gboolean clapper_gtk_av_get_auto_inhibit (ClapperGtkAv *av);
|
||||
|
||||
CLAPPER_GTK_API
|
||||
gboolean clapper_gtk_av_get_inhibited (ClapperGtkAv *av);
|
||||
|
||||
G_END_DECLS
|
@@ -12,8 +12,9 @@
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, see
|
||||
* <https://www.gnu.org/licenses/>.
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
/**
|
||||
|
@@ -12,8 +12,9 @@
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, see
|
||||
* <https://www.gnu.org/licenses/>.
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
@@ -12,8 +12,9 @@
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, see
|
||||
* <https://www.gnu.org/licenses/>.
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
@@ -12,8 +12,9 @@
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, see
|
||||
* <https://www.gnu.org/licenses/>.
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include <clapper/clapper.h>
|
||||
|
@@ -12,8 +12,9 @@
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, see
|
||||
* <https://www.gnu.org/licenses/>.
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
@@ -12,8 +12,9 @@
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, see
|
||||
* <https://www.gnu.org/licenses/>.
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include "clapper-gtk-buffering-paintable-private.h"
|
||||
|
@@ -12,8 +12,9 @@
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, see
|
||||
* <https://www.gnu.org/licenses/>.
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
@@ -12,8 +12,9 @@
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, see
|
||||
* <https://www.gnu.org/licenses/>.
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
/**
|
||||
|
@@ -12,8 +12,9 @@
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, see
|
||||
* <https://www.gnu.org/licenses/>.
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
@@ -12,8 +12,9 @@
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, see
|
||||
* <https://www.gnu.org/licenses/>.
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
@@ -12,8 +12,9 @@
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, see
|
||||
* <https://www.gnu.org/licenses/>.
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
/**
|
||||
|
@@ -12,8 +12,9 @@
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, see
|
||||
* <https://www.gnu.org/licenses/>.
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
@@ -12,8 +12,9 @@
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, see
|
||||
* <https://www.gnu.org/licenses/>.
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
/**
|
||||
|
@@ -12,8 +12,9 @@
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, see
|
||||
* <https://www.gnu.org/licenses/>.
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
@@ -12,8 +12,9 @@
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, see
|
||||
* <https://www.gnu.org/licenses/>.
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
@@ -12,8 +12,9 @@
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, see
|
||||
* <https://www.gnu.org/licenses/>.
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include <clapper/clapper.h>
|
||||
|
@@ -12,8 +12,9 @@
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, see
|
||||
* <https://www.gnu.org/licenses/>.
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -82,7 +83,7 @@ clapper_gtk_next_item_button_init (ClapperGtkNextItemButton *self)
|
||||
{
|
||||
gtk_widget_set_sensitive (GTK_WIDGET (self), FALSE);
|
||||
gtk_button_set_icon_name (GTK_BUTTON (self), "media-skip-forward-symbolic");
|
||||
gtk_actionable_set_action_name (GTK_ACTIONABLE (self), "av.next-item");
|
||||
gtk_actionable_set_action_name (GTK_ACTIONABLE (self), "video.next-item");
|
||||
}
|
||||
|
||||
static void
|
||||
|
@@ -12,8 +12,9 @@
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, see
|
||||
* <https://www.gnu.org/licenses/>.
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
@@ -12,8 +12,9 @@
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, see
|
||||
* <https://www.gnu.org/licenses/>.
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -82,7 +83,7 @@ clapper_gtk_previous_item_button_init (ClapperGtkPreviousItemButton *self)
|
||||
{
|
||||
gtk_widget_set_sensitive (GTK_WIDGET (self), FALSE);
|
||||
gtk_button_set_icon_name (GTK_BUTTON (self), "media-skip-backward-symbolic");
|
||||
gtk_actionable_set_action_name (GTK_ACTIONABLE (self), "av.previous-item");
|
||||
gtk_actionable_set_action_name (GTK_ACTIONABLE (self), "video.previous-item");
|
||||
}
|
||||
|
||||
static void
|
||||
|
@@ -12,8 +12,9 @@
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, see
|
||||
* <https://www.gnu.org/licenses/>.
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
@@ -12,8 +12,9 @@
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, see
|
||||
* <https://www.gnu.org/licenses/>.
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -395,47 +396,6 @@ _update_duration_label (ClapperGtkSeekBar *self, gdouble duration)
|
||||
gtk_adjustment_set_upper (adjustment, duration);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
_find_marks_in_widget (GtkWidget *widget, GtkWidget **top_marks, GtkWidget **bottom_marks)
|
||||
{
|
||||
GtkWidget *child;
|
||||
|
||||
if (g_strcmp0 (gtk_widget_get_css_name (widget), "marks") == 0) {
|
||||
if (gtk_widget_has_css_class (widget, "top"))
|
||||
*top_marks = widget;
|
||||
else if (gtk_widget_has_css_class (widget, "bottom"))
|
||||
*bottom_marks = widget;
|
||||
|
||||
/* Its unexpected to have marks within marks,
|
||||
* so do not iterate children of marks widget */
|
||||
return (*top_marks && *bottom_marks);
|
||||
}
|
||||
|
||||
child = gtk_widget_get_first_child (widget);
|
||||
|
||||
while (child != NULL) {
|
||||
if (_find_marks_in_widget (child, top_marks, bottom_marks))
|
||||
return TRUE;
|
||||
|
||||
child = gtk_widget_get_next_sibling (child);
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
_find_last_mark_in_marks (GtkWidget *marks, GtkWidget **last_mark)
|
||||
{
|
||||
GtkWidget *widget = gtk_widget_get_last_child (marks);
|
||||
|
||||
if (widget && g_strcmp0 (gtk_widget_get_css_name (widget), "mark") == 0) {
|
||||
*last_mark = widget;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
_update_scale_marks (ClapperGtkSeekBar *self, ClapperTimeline *timeline)
|
||||
{
|
||||
@@ -464,43 +424,11 @@ _update_scale_marks (ClapperGtkSeekBar *self, ClapperTimeline *timeline)
|
||||
|
||||
for (i = 0; i < n_markers; ++i) {
|
||||
ClapperMarker *marker = clapper_timeline_get_marker (timeline, i);
|
||||
ClapperMarkerType marker_type = clapper_marker_get_marker_type (marker);
|
||||
gdouble start = clapper_marker_get_start (marker);
|
||||
|
||||
gtk_scale_add_mark (GTK_SCALE (self->scale), start, GTK_POS_TOP, NULL);
|
||||
gtk_scale_add_mark (GTK_SCALE (self->scale), start, GTK_POS_BOTTOM, NULL);
|
||||
|
||||
if (marker_type >= CLAPPER_MARKER_TYPE_CUSTOM_1) {
|
||||
GtkWidget *top_marks = NULL, *bottom_marks = NULL;
|
||||
GtkWidget *top_mark = NULL, *bottom_mark = NULL;
|
||||
|
||||
if (_find_marks_in_widget (self->scale, &top_marks, &bottom_marks)
|
||||
&& _find_last_mark_in_marks (top_marks, &top_mark)
|
||||
&& _find_last_mark_in_marks (bottom_marks, &bottom_mark)) {
|
||||
const gchar *custom_name;
|
||||
|
||||
switch (marker_type) {
|
||||
case CLAPPER_MARKER_TYPE_CUSTOM_1:
|
||||
custom_name = "custom1";
|
||||
break;
|
||||
case CLAPPER_MARKER_TYPE_CUSTOM_2:
|
||||
custom_name = "custom2";
|
||||
break;
|
||||
case CLAPPER_MARKER_TYPE_CUSTOM_3:
|
||||
custom_name = "custom3";
|
||||
break;
|
||||
default:
|
||||
custom_name = NULL;
|
||||
break;
|
||||
}
|
||||
|
||||
if (G_LIKELY (custom_name != NULL)) {
|
||||
gtk_widget_add_css_class (top_mark, custom_name);
|
||||
gtk_widget_add_css_class (bottom_mark, custom_name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
gst_object_unref (marker);
|
||||
}
|
||||
|
||||
|
@@ -12,8 +12,9 @@
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, see
|
||||
* <https://www.gnu.org/licenses/>.
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
@@ -12,8 +12,9 @@
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, see
|
||||
* <https://www.gnu.org/licenses/>.
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
/**
|
||||
|
@@ -12,8 +12,9 @@
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, see
|
||||
* <https://www.gnu.org/licenses/>.
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
@@ -12,8 +12,9 @@
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, see
|
||||
* <https://www.gnu.org/licenses/>.
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
@@ -12,8 +12,9 @@
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, see
|
||||
* <https://www.gnu.org/licenses/>.
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
@@ -12,8 +12,9 @@
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, see
|
||||
* <https://www.gnu.org/licenses/>.
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
@@ -12,8 +12,9 @@
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, see
|
||||
* <https://www.gnu.org/licenses/>.
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
@@ -12,8 +12,9 @@
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, see
|
||||
* <https://www.gnu.org/licenses/>.
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
/**
|
||||
|
@@ -12,8 +12,9 @@
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, see
|
||||
* <https://www.gnu.org/licenses/>.
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
@@ -12,8 +12,9 @@
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, see
|
||||
* <https://www.gnu.org/licenses/>.
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
/**
|
||||
|
@@ -12,8 +12,9 @@
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, see
|
||||
* <https://www.gnu.org/licenses/>.
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
@@ -12,8 +12,9 @@
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, see
|
||||
* <https://www.gnu.org/licenses/>.
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
/**
|
||||
|
@@ -12,8 +12,9 @@
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, see
|
||||
* <https://www.gnu.org/licenses/>.
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
@@ -12,8 +12,9 @@
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, see
|
||||
* <https://www.gnu.org/licenses/>.
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -83,7 +84,7 @@ static void
|
||||
clapper_gtk_toggle_play_button_init (ClapperGtkTogglePlayButton *self)
|
||||
{
|
||||
gtk_button_set_icon_name (GTK_BUTTON (self), PLAY_ICON_NAME);
|
||||
gtk_actionable_set_action_name (GTK_ACTIONABLE (self), "av.toggle-play");
|
||||
gtk_actionable_set_action_name (GTK_ACTIONABLE (self), "video.toggle-play");
|
||||
}
|
||||
|
||||
static void
|
||||
|
@@ -12,8 +12,9 @@
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, see
|
||||
* <https://www.gnu.org/licenses/>.
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
@@ -12,8 +12,9 @@
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, see
|
||||
* <https://www.gnu.org/licenses/>.
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
@@ -12,8 +12,9 @@
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, see
|
||||
* <https://www.gnu.org/licenses/>.
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
@@ -21,7 +22,7 @@
|
||||
#include <glib/gi18n-lib.h>
|
||||
|
||||
#include "clapper-gtk-utils-private.h"
|
||||
#include "clapper-gtk-av.h"
|
||||
#include "clapper-gtk-video.h"
|
||||
|
||||
static gboolean initialized = FALSE;
|
||||
|
||||
@@ -29,18 +30,18 @@ static gboolean initialized = FALSE;
|
||||
* clapper_gtk_get_player_from_ancestor:
|
||||
* @widget: a #GtkWidget
|
||||
*
|
||||
* Get [class@Clapper.Player] used by [class@ClapperGtk.Av] ancestor of @widget.
|
||||
* Get [class@Clapper.Player] used by [class@ClapperGtk.Video] ancestor of @widget.
|
||||
*
|
||||
* This utility is a convenience wrapper for calling [method@Gtk.Widget.get_ancestor]
|
||||
* of type `CLAPPER_GTK_TYPE_AV` and [method@ClapperGtk.Av.get_player] with
|
||||
* of type `CLAPPER_GTK_TYPE_VIDEO` and [method@ClapperGtk.Video.get_player] with
|
||||
* additional %NULL checking and type casting.
|
||||
*
|
||||
* This is meant to be used mainly for custom widget development as an easy access to the
|
||||
* underlying parent [class@Clapper.Player] object. If you want to get the player from
|
||||
* [class@ClapperGtk.Av] widget itself, use [method@ClapperGtk.Av.get_player] instead.
|
||||
* [class@ClapperGtk.Video] widget itself, use [method@ClapperGtk.Video.get_player] instead.
|
||||
*
|
||||
* Rememeber that this function will return %NULL when widget does not have
|
||||
* a [class@ClapperGtk.Av] ancestor in widget hierarchy (widget is not yet placed).
|
||||
* a [class@ClapperGtk.Video] ancestor in widget hierarchy (widget is not yet placed).
|
||||
*
|
||||
* Returns: (transfer none) (nullable): a #ClapperPlayer from ancestor of a @widget.
|
||||
*/
|
||||
@@ -52,8 +53,8 @@ clapper_gtk_get_player_from_ancestor (GtkWidget *widget)
|
||||
|
||||
g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
|
||||
|
||||
if ((parent = gtk_widget_get_ancestor (widget, CLAPPER_GTK_TYPE_AV)))
|
||||
player = clapper_gtk_av_get_player (CLAPPER_GTK_AV_CAST (parent));
|
||||
if ((parent = gtk_widget_get_ancestor (widget, CLAPPER_GTK_TYPE_VIDEO)))
|
||||
player = clapper_gtk_video_get_player (CLAPPER_GTK_VIDEO_CAST (parent));
|
||||
|
||||
return player;
|
||||
}
|
||||
|
@@ -12,8 +12,9 @@
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, see
|
||||
* <https://www.gnu.org/licenses/>.
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
@@ -1,95 +0,0 @@
|
||||
/* Clapper GTK Integration Library
|
||||
* Copyright (C) 2025 Rafał Dzięgiel <rafostar.github@gmail.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, see
|
||||
* <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "clapper-gtk-version.h"
|
||||
|
||||
/**
|
||||
* clapper_gtk_get_major_version:
|
||||
*
|
||||
* ClapperGtk runtime major version component
|
||||
*
|
||||
* This returns the ClapperGtk library version your code is
|
||||
* running against unlike [const@ClapperGtk.MAJOR_VERSION]
|
||||
* which represents compile time version.
|
||||
*
|
||||
* Returns: the major version number of the ClapperGtk library
|
||||
*
|
||||
* Since: 0.10
|
||||
*/
|
||||
guint
|
||||
clapper_gtk_get_major_version (void)
|
||||
{
|
||||
return CLAPPER_GTK_MAJOR_VERSION;
|
||||
}
|
||||
|
||||
/**
|
||||
* clapper_gtk_get_minor_version:
|
||||
*
|
||||
* ClapperGtk runtime minor version component
|
||||
*
|
||||
* This returns the ClapperGtk library version your code is
|
||||
* running against unlike [const@ClapperGtk.MINOR_VERSION]
|
||||
* which represents compile time version.
|
||||
*
|
||||
* Returns: the minor version number of the ClapperGtk library
|
||||
*
|
||||
* Since: 0.10
|
||||
*/
|
||||
guint
|
||||
clapper_gtk_get_minor_version (void)
|
||||
{
|
||||
return CLAPPER_GTK_MINOR_VERSION;
|
||||
}
|
||||
|
||||
/**
|
||||
* clapper_gtk_get_micro_version:
|
||||
*
|
||||
* ClapperGtk runtime micro version component
|
||||
*
|
||||
* This returns the ClapperGtk library version your code is
|
||||
* running against unlike [const@ClapperGtk.MICRO_VERSION]
|
||||
* which represents compile time version.
|
||||
*
|
||||
* Returns: the micro version number of the ClapperGtk library
|
||||
*
|
||||
* Since: 0.10
|
||||
*/
|
||||
guint
|
||||
clapper_gtk_get_micro_version (void)
|
||||
{
|
||||
return CLAPPER_GTK_MICRO_VERSION;
|
||||
}
|
||||
|
||||
/**
|
||||
* clapper_gtk_get_version_s:
|
||||
*
|
||||
* ClapperGtk runtime version as string
|
||||
*
|
||||
* This returns the ClapperGtk library version your code is
|
||||
* running against unlike [const@ClapperGtk.VERSION_S]
|
||||
* which represents compile time version.
|
||||
*
|
||||
* Returns: the version of the ClapperGtk library as string
|
||||
*
|
||||
* Since: 0.10
|
||||
*/
|
||||
const gchar *
|
||||
clapper_gtk_get_version_s (void)
|
||||
{
|
||||
return CLAPPER_GTK_VERSION_S;
|
||||
}
|
@@ -12,8 +12,9 @@
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, see
|
||||
* <https://www.gnu.org/licenses/>.
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
@@ -22,8 +23,6 @@
|
||||
#error "Only <clapper-gtk/clapper-gtk.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
/**
|
||||
* CLAPPER_GTK_MAJOR_VERSION:
|
||||
*
|
||||
@@ -75,15 +74,3 @@
|
||||
(CLAPPER_GTK_MAJOR_VERSION == (major) && CLAPPER_GTK_MINOR_VERSION > (minor)) || \
|
||||
(CLAPPER_GTK_MAJOR_VERSION == (major) && CLAPPER_GTK_MINOR_VERSION == (minor) && \
|
||||
CLAPPER_GTK_MICRO_VERSION >= (micro)))
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
guint clapper_gtk_get_major_version (void);
|
||||
|
||||
guint clapper_gtk_get_minor_version (void);
|
||||
|
||||
guint clapper_gtk_get_micro_version (void);
|
||||
|
||||
const gchar * clapper_gtk_get_version_s (void);
|
||||
|
||||
G_END_DECLS
|
||||
|
@@ -12,8 +12,9 @@
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, see
|
||||
* <https://www.gnu.org/licenses/>.
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
@@ -12,8 +12,9 @@
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, see
|
||||
* <https://www.gnu.org/licenses/>.
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
@@ -12,8 +12,9 @@
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, see
|
||||
* <https://www.gnu.org/licenses/>.
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -22,8 +23,8 @@
|
||||
* A ready to be used GTK video widget implementing Clapper API.
|
||||
*
|
||||
* #ClapperGtkVideo is the main widget exposed by `ClapperGtk` API. It both displays
|
||||
* videos played by [class@Clapper.Player] (exposed as [property@ClapperGtk.Av:player] property)
|
||||
* and manages revealing and fading of any additional widgets overlaid on top of it.
|
||||
* videos played by [class@Clapper.Player] (exposed as its property) and manages
|
||||
* revealing and fading of any additional widgets overlaid on top of it.
|
||||
*
|
||||
* Other widgets provided by `ClapperGtk` library, once placed anywhere on video
|
||||
* (including nesting within another widget like [class@Gtk.Box]) will automatically
|
||||
@@ -34,7 +35,7 @@
|
||||
* # Basic usage
|
||||
*
|
||||
* A typical use case is to embed video widget as part of your app where video playback
|
||||
* is needed. Get the [class@Clapper.Player] belonging to the AV widget and start adding
|
||||
* is needed. Get the [class@Clapper.Player] belonging to the video widget and start adding
|
||||
* new [class@Clapper.MediaItem] items to the [class@Clapper.Queue] for playback.
|
||||
* For more information please refer to the Clapper playback library documentation.
|
||||
*
|
||||
@@ -46,8 +47,27 @@
|
||||
*
|
||||
* # Actions
|
||||
*
|
||||
* You can use built-in actions of parent [class@ClapperGtk.Av].
|
||||
* See its documentation, for the list of available ones.
|
||||
* #ClapperGtkVideo defines a set of built-in actions:
|
||||
*
|
||||
* ```yaml
|
||||
* - "video.toggle-play": toggle play/pause
|
||||
* - "video.play": start/resume playback
|
||||
* - "video.pause": pause playback
|
||||
* - "video.stop": stop playback
|
||||
* - "video.seek": seek to position (variant "d")
|
||||
* - "video.seek-custom": seek to position using seek method (variant "(di)")
|
||||
* - "video.toggle-mute": toggle mute state
|
||||
* - "video.set-mute": set mute state (variant "b")
|
||||
* - "video.volume-up": increase volume by 2%
|
||||
* - "video.volume-down": decrease volume by 2%
|
||||
* - "video.set-volume": set volume to specified value (variant "d")
|
||||
* - "video.speed-up": increase speed (from 0.05x - 2x range to nearest quarter)
|
||||
* - "video.speed-down": decrease speed (from 0.05x - 2x range to nearest quarter)
|
||||
* - "video.set-speed": set speed to specified value (variant "d")
|
||||
* - "video.previous-item": select previous item in queue
|
||||
* - "video.next-item": select next item in queue
|
||||
* - "video.select-item": select item at specified index in queue (variant "u")
|
||||
* ```
|
||||
*
|
||||
* # ClapperGtkVideo as GtkBuildable
|
||||
*
|
||||
@@ -74,6 +94,8 @@
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#include "clapper-gtk-enums.h"
|
||||
#include "clapper-gtk-video.h"
|
||||
#include "clapper-gtk-lead-container.h"
|
||||
@@ -81,8 +103,11 @@
|
||||
#include "clapper-gtk-buffering-animation-private.h"
|
||||
#include "clapper-gtk-video-placeholder-private.h"
|
||||
|
||||
#define PERCENTAGE_ROUND(a) (round ((gdouble) a / 0.01) * 0.01)
|
||||
|
||||
#define DEFAULT_FADE_DELAY 3000
|
||||
#define DEFAULT_TOUCH_FADE_DELAY 5000
|
||||
#define DEFAULT_AUTO_INHIBIT FALSE
|
||||
|
||||
#define MIN_MOTION_DELAY 100000
|
||||
|
||||
@@ -91,7 +116,7 @@ GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);
|
||||
|
||||
struct _ClapperGtkVideo
|
||||
{
|
||||
ClapperGtkAv parent;
|
||||
GtkWidget parent;
|
||||
|
||||
GtkWidget *overlay;
|
||||
GtkWidget *status;
|
||||
@@ -101,8 +126,10 @@ struct _ClapperGtkVideo
|
||||
GtkGesture *click_gesture;
|
||||
|
||||
/* Props */
|
||||
ClapperPlayer *player;
|
||||
guint fade_delay;
|
||||
guint touch_fade_delay;
|
||||
gboolean auto_inhibit;
|
||||
|
||||
GPtrArray *overlays;
|
||||
GPtrArray *fading_overlays;
|
||||
@@ -114,6 +141,8 @@ struct _ClapperGtkVideo
|
||||
guint fade_timeout;
|
||||
gboolean reveal, revealed;
|
||||
|
||||
guint inhibit_cookie;
|
||||
|
||||
/* Current pointer coords and type */
|
||||
gdouble x, y;
|
||||
gboolean is_touch;
|
||||
@@ -146,14 +175,17 @@ _buildable_iface_init (GtkBuildableIface *iface)
|
||||
}
|
||||
|
||||
#define parent_class clapper_gtk_video_parent_class
|
||||
G_DEFINE_TYPE_WITH_CODE (ClapperGtkVideo, clapper_gtk_video, CLAPPER_GTK_TYPE_AV,
|
||||
G_DEFINE_TYPE_WITH_CODE (ClapperGtkVideo, clapper_gtk_video, GTK_TYPE_WIDGET,
|
||||
G_IMPLEMENT_INTERFACE (GTK_TYPE_BUILDABLE, _buildable_iface_init))
|
||||
|
||||
enum
|
||||
{
|
||||
PROP_0,
|
||||
PROP_PLAYER,
|
||||
PROP_FADE_DELAY,
|
||||
PROP_TOUCH_FADE_DELAY,
|
||||
PROP_AUTO_INHIBIT,
|
||||
PROP_INHIBITED,
|
||||
PROP_LAST
|
||||
};
|
||||
|
||||
@@ -164,111 +196,209 @@ enum
|
||||
SIGNAL_LAST
|
||||
};
|
||||
|
||||
static gboolean provider_added = FALSE;
|
||||
static GParamSpec *param_specs[PROP_LAST] = { NULL, };
|
||||
static guint signals[SIGNAL_LAST] = { 0, };
|
||||
|
||||
/* FIXME: 1.0: Remove these compat actions, since they were moved to base class */
|
||||
|
||||
static void
|
||||
toggle_play_action_cb (GtkWidget *widget, const gchar *action_name, GVariant *parameter)
|
||||
{
|
||||
gtk_widget_activate_action_variant (widget, "av.toggle-play", parameter);
|
||||
ClapperGtkVideo *self = CLAPPER_GTK_VIDEO_CAST (widget);
|
||||
ClapperPlayer *player = clapper_gtk_video_get_player (self);
|
||||
|
||||
switch (clapper_player_get_state (player)) {
|
||||
case CLAPPER_PLAYER_STATE_PLAYING:
|
||||
clapper_player_pause (player);
|
||||
break;
|
||||
case CLAPPER_PLAYER_STATE_STOPPED:
|
||||
case CLAPPER_PLAYER_STATE_PAUSED:
|
||||
clapper_player_play (player);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
play_action_cb (GtkWidget *widget, const gchar *action_name, GVariant *parameter)
|
||||
{
|
||||
gtk_widget_activate_action_variant (widget, "av.play", parameter);
|
||||
ClapperGtkVideo *self = CLAPPER_GTK_VIDEO_CAST (widget);
|
||||
ClapperPlayer *player = clapper_gtk_video_get_player (self);
|
||||
|
||||
clapper_player_play (player);
|
||||
}
|
||||
|
||||
static void
|
||||
pause_action_cb (GtkWidget *widget, const gchar *action_name, GVariant *parameter)
|
||||
{
|
||||
gtk_widget_activate_action_variant (widget, "av.pause", parameter);
|
||||
ClapperGtkVideo *self = CLAPPER_GTK_VIDEO_CAST (widget);
|
||||
ClapperPlayer *player = clapper_gtk_video_get_player (self);
|
||||
|
||||
clapper_player_pause (player);
|
||||
}
|
||||
|
||||
static void
|
||||
stop_action_cb (GtkWidget *widget, const gchar *action_name, GVariant *parameter)
|
||||
{
|
||||
gtk_widget_activate_action_variant (widget, "av.stop", parameter);
|
||||
ClapperGtkVideo *self = CLAPPER_GTK_VIDEO_CAST (widget);
|
||||
ClapperPlayer *player = clapper_gtk_video_get_player (self);
|
||||
|
||||
clapper_player_stop (player);
|
||||
}
|
||||
|
||||
static void
|
||||
seek_action_cb (GtkWidget *widget, const gchar *action_name, GVariant *parameter)
|
||||
{
|
||||
gtk_widget_activate_action_variant (widget, "av.seek", parameter);
|
||||
ClapperGtkVideo *self = CLAPPER_GTK_VIDEO_CAST (widget);
|
||||
ClapperPlayer *player = clapper_gtk_video_get_player (self);
|
||||
gdouble position = g_variant_get_double (parameter);
|
||||
|
||||
clapper_player_seek (player, position);
|
||||
}
|
||||
|
||||
static void
|
||||
seek_custom_action_cb (GtkWidget *widget, const gchar *action_name, GVariant *parameter)
|
||||
{
|
||||
gtk_widget_activate_action_variant (widget, "av.seek-custom", parameter);
|
||||
ClapperGtkVideo *self = CLAPPER_GTK_VIDEO_CAST (widget);
|
||||
ClapperPlayer *player = clapper_gtk_video_get_player (self);
|
||||
ClapperPlayerSeekMethod method = CLAPPER_PLAYER_SEEK_METHOD_NORMAL;
|
||||
gdouble position = 0;
|
||||
|
||||
g_variant_get (parameter, "(di)", &position, &method);
|
||||
clapper_player_seek_custom (player, position, method);
|
||||
}
|
||||
|
||||
static void
|
||||
toggle_mute_action_cb (GtkWidget *widget, const gchar *action_name, GVariant *parameter)
|
||||
{
|
||||
gtk_widget_activate_action_variant (widget, "av.toggle-mute", parameter);
|
||||
ClapperGtkVideo *self = CLAPPER_GTK_VIDEO_CAST (widget);
|
||||
ClapperPlayer *player = clapper_gtk_video_get_player (self);
|
||||
|
||||
clapper_player_set_mute (player, !clapper_player_get_mute (player));
|
||||
}
|
||||
|
||||
static void
|
||||
set_mute_action_cb (GtkWidget *widget, const gchar *action_name, GVariant *parameter)
|
||||
{
|
||||
gtk_widget_activate_action_variant (widget, "av.set-mute", parameter);
|
||||
ClapperGtkVideo *self = CLAPPER_GTK_VIDEO_CAST (widget);
|
||||
ClapperPlayer *player = clapper_gtk_video_get_player (self);
|
||||
gboolean mute = g_variant_get_boolean (parameter);
|
||||
|
||||
clapper_player_set_mute (player, mute);
|
||||
}
|
||||
|
||||
static void
|
||||
volume_up_action_cb (GtkWidget *widget, const gchar *action_name, GVariant *parameter)
|
||||
{
|
||||
gtk_widget_activate_action_variant (widget, "av.volume-up", parameter);
|
||||
ClapperGtkVideo *self = CLAPPER_GTK_VIDEO_CAST (widget);
|
||||
ClapperPlayer *player = clapper_gtk_video_get_player (self);
|
||||
gdouble volume = (clapper_player_get_volume (player) + 0.02);
|
||||
|
||||
if (volume > 2.0)
|
||||
volume = 2.0;
|
||||
|
||||
clapper_player_set_volume (player, PERCENTAGE_ROUND (volume));
|
||||
}
|
||||
|
||||
static void
|
||||
volume_down_action_cb (GtkWidget *widget, const gchar *action_name, GVariant *parameter)
|
||||
{
|
||||
gtk_widget_activate_action_variant (widget, "av.volume-down", parameter);
|
||||
ClapperGtkVideo *self = CLAPPER_GTK_VIDEO_CAST (widget);
|
||||
ClapperPlayer *player = clapper_gtk_video_get_player (self);
|
||||
gdouble volume = (clapper_player_get_volume (player) - 0.02);
|
||||
|
||||
if (volume < 0)
|
||||
volume = 0;
|
||||
|
||||
clapper_player_set_volume (player, PERCENTAGE_ROUND (volume));
|
||||
}
|
||||
|
||||
static void
|
||||
set_volume_action_cb (GtkWidget *widget, const gchar *action_name, GVariant *parameter)
|
||||
{
|
||||
gtk_widget_activate_action_variant (widget, "av.set-volume", parameter);
|
||||
ClapperGtkVideo *self = CLAPPER_GTK_VIDEO_CAST (widget);
|
||||
ClapperPlayer *player = clapper_gtk_video_get_player (self);
|
||||
gdouble volume = g_variant_get_double (parameter);
|
||||
|
||||
clapper_player_set_volume (player, volume);
|
||||
}
|
||||
|
||||
static void
|
||||
speed_up_action_cb (GtkWidget *widget, const gchar *action_name, GVariant *parameter)
|
||||
{
|
||||
gtk_widget_activate_action_variant (widget, "av.speed-up", parameter);
|
||||
ClapperGtkVideo *self = CLAPPER_GTK_VIDEO_CAST (widget);
|
||||
ClapperPlayer *player = clapper_gtk_video_get_player (self);
|
||||
gdouble dest, speed = clapper_player_get_speed (player);
|
||||
|
||||
if (speed >= 2.0)
|
||||
return;
|
||||
|
||||
dest = 0.25;
|
||||
while (speed >= dest)
|
||||
dest += 0.25;
|
||||
|
||||
if (dest > 2.0)
|
||||
dest = 2.0;
|
||||
|
||||
clapper_player_set_speed (player, dest);
|
||||
}
|
||||
|
||||
static void
|
||||
speed_down_action_cb (GtkWidget *widget, const gchar *action_name, GVariant *parameter)
|
||||
{
|
||||
gtk_widget_activate_action_variant (widget, "av.speed-down", parameter);
|
||||
ClapperGtkVideo *self = CLAPPER_GTK_VIDEO_CAST (widget);
|
||||
ClapperPlayer *player = clapper_gtk_video_get_player (self);
|
||||
gdouble dest, speed = clapper_player_get_speed (player);
|
||||
|
||||
if (speed <= 0.05)
|
||||
return;
|
||||
|
||||
dest = 2.0;
|
||||
while (speed <= dest)
|
||||
dest -= 0.25;
|
||||
|
||||
if (dest < 0.05)
|
||||
dest = 0.05;
|
||||
|
||||
clapper_player_set_speed (player, dest);
|
||||
}
|
||||
|
||||
static void
|
||||
set_speed_action_cb (GtkWidget *widget, const gchar *action_name, GVariant *parameter)
|
||||
{
|
||||
gtk_widget_activate_action_variant (widget, "av.set-speed", parameter);
|
||||
ClapperGtkVideo *self = CLAPPER_GTK_VIDEO_CAST (widget);
|
||||
ClapperPlayer *player = clapper_gtk_video_get_player (self);
|
||||
gdouble speed = g_variant_get_double (parameter);
|
||||
|
||||
clapper_player_set_speed (player, speed);
|
||||
}
|
||||
|
||||
static void
|
||||
previous_item_action_cb (GtkWidget *widget, const gchar *action_name, GVariant *parameter)
|
||||
{
|
||||
gtk_widget_activate_action_variant (widget, "av.previous-item", parameter);
|
||||
ClapperGtkVideo *self = CLAPPER_GTK_VIDEO_CAST (widget);
|
||||
ClapperPlayer *player = clapper_gtk_video_get_player (self);
|
||||
|
||||
clapper_queue_select_previous_item (clapper_player_get_queue (player));
|
||||
}
|
||||
|
||||
static void
|
||||
next_item_action_cb (GtkWidget *widget, const gchar *action_name, GVariant *parameter)
|
||||
{
|
||||
gtk_widget_activate_action_variant (widget, "av.next-item", parameter);
|
||||
ClapperGtkVideo *self = CLAPPER_GTK_VIDEO_CAST (widget);
|
||||
ClapperPlayer *player = clapper_gtk_video_get_player (self);
|
||||
|
||||
clapper_queue_select_next_item (clapper_player_get_queue (player));
|
||||
}
|
||||
|
||||
static void
|
||||
select_item_action_cb (GtkWidget *widget, const gchar *action_name, GVariant *parameter)
|
||||
{
|
||||
gtk_widget_activate_action_variant (widget, "av.select-item", parameter);
|
||||
ClapperGtkVideo *self = CLAPPER_GTK_VIDEO_CAST (widget);
|
||||
ClapperPlayer *player = clapper_gtk_video_get_player (self);
|
||||
guint index = g_variant_get_uint32 (parameter);
|
||||
|
||||
clapper_queue_select_index (clapper_player_get_queue (player), index);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -742,6 +872,73 @@ touch_released_cb (GtkGestureClick *click, gint n_press,
|
||||
_reset_fade_timeout (self);
|
||||
}
|
||||
|
||||
static void
|
||||
_ensure_css_provider (void)
|
||||
{
|
||||
GdkDisplay *display;
|
||||
|
||||
if (provider_added)
|
||||
return;
|
||||
|
||||
display = gdk_display_get_default ();
|
||||
|
||||
if (G_LIKELY (display != NULL)) {
|
||||
GtkCssProvider *provider = gtk_css_provider_new ();
|
||||
gtk_css_provider_load_from_resource (provider,
|
||||
CLAPPER_GTK_RESOURCE_PREFIX "/css/styles.css");
|
||||
|
||||
gtk_style_context_add_provider_for_display (display,
|
||||
(GtkStyleProvider *) provider, GTK_STYLE_PROVIDER_PRIORITY_APPLICATION - 1);
|
||||
g_object_unref (provider);
|
||||
|
||||
provider_added = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
static inline void
|
||||
_set_inhibit_session (ClapperGtkVideo *self, gboolean inhibit)
|
||||
{
|
||||
GtkRoot *root;
|
||||
GApplication *app;
|
||||
gboolean inhibited = (self->inhibit_cookie != 0);
|
||||
|
||||
if (inhibited == inhibit)
|
||||
return;
|
||||
|
||||
GST_DEBUG_OBJECT (self, "Trying to %sinhibit session...", (inhibit) ? "" : "un");
|
||||
|
||||
root = gtk_widget_get_root (GTK_WIDGET (self));
|
||||
|
||||
if (!root && !GTK_IS_WINDOW (root)) {
|
||||
GST_WARNING_OBJECT (self, "Cannot %sinhibit session "
|
||||
"without root window", (inhibit) ? "" : "un");
|
||||
return;
|
||||
}
|
||||
|
||||
/* NOTE: Not using application from window prop,
|
||||
* as it goes away early when unrooting */
|
||||
app = g_application_get_default ();
|
||||
|
||||
if (!app && !GTK_IS_APPLICATION (app)) {
|
||||
GST_WARNING_OBJECT (self, "Cannot %sinhibit session "
|
||||
"without window application set", (inhibit) ? "" : "un");
|
||||
return;
|
||||
}
|
||||
|
||||
if (inhibited) {
|
||||
gtk_application_uninhibit (GTK_APPLICATION (app), self->inhibit_cookie);
|
||||
self->inhibit_cookie = 0;
|
||||
}
|
||||
if (inhibit) {
|
||||
self->inhibit_cookie = gtk_application_inhibit (GTK_APPLICATION (app),
|
||||
GTK_WINDOW (root), GTK_APPLICATION_INHIBIT_IDLE,
|
||||
"Video is playing");
|
||||
}
|
||||
|
||||
GST_DEBUG_OBJECT (self, "Session %sinhibited", (inhibit) ? "" : "un");
|
||||
g_object_notify_by_pspec (G_OBJECT (self), param_specs[PROP_INHIBITED]);
|
||||
}
|
||||
|
||||
static inline void
|
||||
_set_buffering_animation_enabled (ClapperGtkVideo *self, gboolean enabled)
|
||||
{
|
||||
@@ -767,6 +964,9 @@ _player_state_changed_cb (ClapperPlayer *player,
|
||||
{
|
||||
ClapperPlayerState state = clapper_player_get_state (player);
|
||||
|
||||
if (self->auto_inhibit)
|
||||
_set_inhibit_session (self, state == CLAPPER_PLAYER_STATE_PLAYING);
|
||||
|
||||
_set_buffering_animation_enabled (self, state == CLAPPER_PLAYER_STATE_BUFFERING);
|
||||
}
|
||||
|
||||
@@ -907,7 +1107,7 @@ _fading_overlay_revealed_cb (GtkRevealer *revealer,
|
||||
*
|
||||
* Creates a new #ClapperGtkVideo instance.
|
||||
*
|
||||
* Newly created video widget will also have set some default GStreamer elements
|
||||
* Newly created video widget will also set some default GStreamer elements
|
||||
* on its [class@Clapper.Player]. This includes Clapper own video sink and
|
||||
* a "scaletempo" element as audio filter. Both can still be changed after
|
||||
* construction by setting corresponding player properties.
|
||||
@@ -988,21 +1188,19 @@ clapper_gtk_video_add_fading_overlay (ClapperGtkVideo *self, GtkWidget *widget)
|
||||
}
|
||||
|
||||
/**
|
||||
* clapper_gtk_video_get_player: (skip)
|
||||
* clapper_gtk_video_get_player:
|
||||
* @video: a #ClapperGtkVideo
|
||||
*
|
||||
* Get #ClapperPlayer used by this #ClapperGtkVideo instance.
|
||||
*
|
||||
* Returns: (transfer none): a #ClapperPlayer used by video.
|
||||
*
|
||||
* Deprecated: 0.10: Use [method@ClapperGtk.Av.get_player] instead.
|
||||
*/
|
||||
ClapperPlayer *
|
||||
clapper_gtk_video_get_player (ClapperGtkVideo *self)
|
||||
{
|
||||
g_return_val_if_fail (CLAPPER_GTK_IS_VIDEO (self), NULL);
|
||||
|
||||
return clapper_gtk_av_get_player (CLAPPER_GTK_AV_CAST (self));
|
||||
return self->player;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1078,58 +1276,60 @@ clapper_gtk_video_get_touch_fade_delay (ClapperGtkVideo *self)
|
||||
}
|
||||
|
||||
/**
|
||||
* clapper_gtk_video_set_auto_inhibit: (skip)
|
||||
* clapper_gtk_video_set_auto_inhibit:
|
||||
* @video: a #ClapperGtkVideo
|
||||
* @inhibit: whether to enable automatic session inhibit
|
||||
*
|
||||
* Set whether video should try to automatically inhibit session
|
||||
* from idling (and possibly screen going black) when video is playing.
|
||||
*
|
||||
* Deprecated: 0.10: Use [method@ClapperGtk.Av.set_auto_inhibit] instead.
|
||||
*/
|
||||
void
|
||||
clapper_gtk_video_set_auto_inhibit (ClapperGtkVideo *self, gboolean inhibit)
|
||||
{
|
||||
g_return_if_fail (CLAPPER_GTK_IS_VIDEO (self));
|
||||
|
||||
clapper_gtk_av_set_auto_inhibit (CLAPPER_GTK_AV_CAST (self), inhibit);
|
||||
if (self->auto_inhibit != inhibit) {
|
||||
self->auto_inhibit = inhibit;
|
||||
|
||||
/* Uninhibit if we were auto inhibited earlier */
|
||||
if (!self->auto_inhibit)
|
||||
_set_inhibit_session (self, FALSE);
|
||||
|
||||
g_object_notify_by_pspec (G_OBJECT (self), param_specs[PROP_AUTO_INHIBIT]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* clapper_gtk_video_get_auto_inhibit: (skip)
|
||||
* clapper_gtk_video_get_auto_inhibit:
|
||||
* @video: a #ClapperGtkVideo
|
||||
*
|
||||
* Get whether automatic session inhibit is enabled.
|
||||
*
|
||||
* Returns: %TRUE if enabled, %FALSE otherwise.
|
||||
*
|
||||
* Deprecated: 0.10: Use [method@ClapperGtk.Av.get_auto_inhibit] instead.
|
||||
*/
|
||||
gboolean
|
||||
clapper_gtk_video_get_auto_inhibit (ClapperGtkVideo *self)
|
||||
{
|
||||
g_return_val_if_fail (CLAPPER_GTK_IS_VIDEO (self), FALSE);
|
||||
|
||||
return clapper_gtk_av_get_auto_inhibit (CLAPPER_GTK_AV_CAST (self));
|
||||
return self->auto_inhibit;
|
||||
}
|
||||
|
||||
/**
|
||||
* clapper_gtk_video_get_inhibited: (skip)
|
||||
* clapper_gtk_video_get_inhibited:
|
||||
* @video: a #ClapperGtkVideo
|
||||
*
|
||||
* Get whether session is currently inhibited by
|
||||
* [property@ClapperGtk.Av:auto-inhibit].
|
||||
* [property@ClapperGtk.Video:auto-inhibit].
|
||||
*
|
||||
* Returns: %TRUE if inhibited, %FALSE otherwise.
|
||||
*
|
||||
* Deprecated: 0.10: Use [method@ClapperGtk.Av.get_inhibited] instead.
|
||||
*/
|
||||
gboolean
|
||||
clapper_gtk_video_get_inhibited (ClapperGtkVideo *self)
|
||||
{
|
||||
g_return_val_if_fail (CLAPPER_GTK_IS_VIDEO (self), FALSE);
|
||||
|
||||
return clapper_gtk_av_get_inhibited (CLAPPER_GTK_AV_CAST (self));
|
||||
return (self->inhibit_cookie != 0);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1138,6 +1338,8 @@ clapper_gtk_video_root (GtkWidget *widget)
|
||||
ClapperGtkVideo *self = CLAPPER_GTK_VIDEO_CAST (widget);
|
||||
GtkRoot *root;
|
||||
|
||||
_ensure_css_provider ();
|
||||
|
||||
GTK_WIDGET_CLASS (parent_class)->root (widget);
|
||||
|
||||
root = gtk_widget_get_root (widget);
|
||||
@@ -1149,6 +1351,11 @@ clapper_gtk_video_root (GtkWidget *widget)
|
||||
G_CALLBACK (_window_is_active_cb), self);
|
||||
_window_is_active_cb (window, NULL, self);
|
||||
}
|
||||
|
||||
if (self->auto_inhibit) {
|
||||
ClapperPlayerState state = clapper_player_get_state (self->player);
|
||||
_set_inhibit_session (self, state == CLAPPER_PLAYER_STATE_PLAYING);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1162,6 +1369,8 @@ clapper_gtk_video_unroot (GtkWidget *widget)
|
||||
_window_is_active_cb, self);
|
||||
}
|
||||
|
||||
_set_inhibit_session (self, FALSE);
|
||||
|
||||
GTK_WIDGET_CLASS (parent_class)->unroot (widget);
|
||||
}
|
||||
|
||||
@@ -1177,6 +1386,7 @@ clapper_gtk_video_init (ClapperGtkVideo *self)
|
||||
|
||||
self->fade_delay = DEFAULT_FADE_DELAY;
|
||||
self->touch_fade_delay = DEFAULT_TOUCH_FADE_DELAY;
|
||||
self->auto_inhibit = DEFAULT_AUTO_INHIBIT;
|
||||
|
||||
/* Ensure private types */
|
||||
g_type_ensure (CLAPPER_GTK_TYPE_STATUS);
|
||||
@@ -1191,18 +1401,15 @@ static void
|
||||
clapper_gtk_video_constructed (GObject *object)
|
||||
{
|
||||
ClapperGtkVideo *self = CLAPPER_GTK_VIDEO_CAST (object);
|
||||
GstElement *vsink;
|
||||
ClapperPlayer *player;
|
||||
GstElement *afilter, *vsink;
|
||||
ClapperQueue *queue;
|
||||
|
||||
G_OBJECT_CLASS (parent_class)->constructed (object);
|
||||
self->player = clapper_player_new ();
|
||||
queue = clapper_player_get_queue (self->player);
|
||||
|
||||
player = clapper_gtk_av_get_player (CLAPPER_GTK_AV_CAST (self));
|
||||
queue = clapper_player_get_queue (player);
|
||||
|
||||
g_signal_connect (player, "notify::state",
|
||||
g_signal_connect (self->player, "notify::state",
|
||||
G_CALLBACK (_player_state_changed_cb), self);
|
||||
g_signal_connect (player, "notify::video-sink",
|
||||
g_signal_connect (self->player, "notify::video-sink",
|
||||
G_CALLBACK (_video_sink_changed_cb), self);
|
||||
|
||||
vsink = gst_element_factory_make ("clappersink", NULL);
|
||||
@@ -1222,23 +1429,28 @@ clapper_gtk_video_constructed (GObject *object)
|
||||
}
|
||||
}
|
||||
|
||||
clapper_player_set_video_sink (player, vsink);
|
||||
clapper_player_set_video_sink (self->player, vsink);
|
||||
}
|
||||
|
||||
g_signal_connect (player, "error",
|
||||
afilter = gst_element_factory_make ("scaletempo", NULL);
|
||||
if (G_LIKELY (afilter != NULL))
|
||||
clapper_player_set_audio_filter (self->player, afilter);
|
||||
|
||||
g_signal_connect (self->player, "error",
|
||||
G_CALLBACK (_player_error_cb), self);
|
||||
g_signal_connect (player, "missing-plugin",
|
||||
g_signal_connect (self->player, "missing-plugin",
|
||||
G_CALLBACK (_player_missing_plugin_cb), self);
|
||||
|
||||
g_signal_connect (queue, "notify::current-item",
|
||||
G_CALLBACK (_queue_current_item_changed_cb), self);
|
||||
|
||||
G_OBJECT_CLASS (parent_class)->constructed (object);
|
||||
}
|
||||
|
||||
static void
|
||||
clapper_gtk_video_dispose (GObject *object)
|
||||
{
|
||||
ClapperGtkVideo *self = CLAPPER_GTK_VIDEO_CAST (object);
|
||||
ClapperPlayer *player;
|
||||
|
||||
if (self->notify_revealed_id != 0) {
|
||||
GtkRevealer *revealer = GTK_REVEALER (g_ptr_array_index (self->fading_overlays, 0));
|
||||
@@ -1249,20 +1461,18 @@ clapper_gtk_video_dispose (GObject *object)
|
||||
|
||||
g_clear_handle_id (&self->fade_timeout, g_source_remove);
|
||||
|
||||
player = clapper_gtk_av_get_player (CLAPPER_GTK_AV_CAST (self));
|
||||
|
||||
/* Something else might still be holding a reference on the player,
|
||||
* thus we should disconnect everything before disposing template */
|
||||
if (player) { // NULL if dispose run multiple times
|
||||
ClapperQueue *queue = clapper_player_get_queue (player);
|
||||
if (self->player) {
|
||||
ClapperQueue *queue = clapper_player_get_queue (self->player);
|
||||
|
||||
g_signal_handlers_disconnect_by_func (player,
|
||||
g_signal_handlers_disconnect_by_func (self->player,
|
||||
_player_state_changed_cb, self);
|
||||
g_signal_handlers_disconnect_by_func (player,
|
||||
g_signal_handlers_disconnect_by_func (self->player,
|
||||
_video_sink_changed_cb, self);
|
||||
g_signal_handlers_disconnect_by_func (player,
|
||||
g_signal_handlers_disconnect_by_func (self->player,
|
||||
_player_error_cb, self);
|
||||
g_signal_handlers_disconnect_by_func (player,
|
||||
g_signal_handlers_disconnect_by_func (self->player,
|
||||
_player_missing_plugin_cb, self);
|
||||
|
||||
g_signal_handlers_disconnect_by_func (queue,
|
||||
@@ -1272,6 +1482,7 @@ clapper_gtk_video_dispose (GObject *object)
|
||||
gtk_widget_dispose_template (GTK_WIDGET (object), CLAPPER_GTK_TYPE_VIDEO);
|
||||
|
||||
g_clear_pointer (&self->overlay, gtk_widget_unparent);
|
||||
gst_clear_object (&self->player);
|
||||
|
||||
G_OBJECT_CLASS (parent_class)->dispose (object);
|
||||
}
|
||||
@@ -1294,12 +1505,21 @@ clapper_gtk_video_get_property (GObject *object, guint prop_id,
|
||||
ClapperGtkVideo *self = CLAPPER_GTK_VIDEO_CAST (object);
|
||||
|
||||
switch (prop_id) {
|
||||
case PROP_PLAYER:
|
||||
g_value_set_object (value, clapper_gtk_video_get_player (self));
|
||||
break;
|
||||
case PROP_FADE_DELAY:
|
||||
g_value_set_uint (value, clapper_gtk_video_get_fade_delay (self));
|
||||
break;
|
||||
case PROP_TOUCH_FADE_DELAY:
|
||||
g_value_set_uint (value, clapper_gtk_video_get_touch_fade_delay (self));
|
||||
break;
|
||||
case PROP_AUTO_INHIBIT:
|
||||
g_value_set_boolean (value, clapper_gtk_video_get_auto_inhibit (self));
|
||||
break;
|
||||
case PROP_INHIBITED:
|
||||
g_value_set_boolean (value, clapper_gtk_video_get_inhibited (self));
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
@@ -1319,6 +1539,9 @@ clapper_gtk_video_set_property (GObject *object, guint prop_id,
|
||||
case PROP_TOUCH_FADE_DELAY:
|
||||
clapper_gtk_video_set_touch_fade_delay (self, g_value_get_uint (value));
|
||||
break;
|
||||
case PROP_AUTO_INHIBIT:
|
||||
clapper_gtk_video_set_auto_inhibit (self, g_value_get_boolean (value));
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
@@ -1343,6 +1566,15 @@ clapper_gtk_video_class_init (ClapperGtkVideoClass *klass)
|
||||
gobject_class->dispose = clapper_gtk_video_dispose;
|
||||
gobject_class->finalize = clapper_gtk_video_finalize;
|
||||
|
||||
/**
|
||||
* ClapperGtkVideo:player:
|
||||
*
|
||||
* A #ClapperPlayer used by video.
|
||||
*/
|
||||
param_specs[PROP_PLAYER] = g_param_spec_object ("player",
|
||||
NULL, NULL, CLAPPER_TYPE_PLAYER,
|
||||
G_PARAM_READABLE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
|
||||
|
||||
/**
|
||||
* ClapperGtkVideo:fade-delay:
|
||||
*
|
||||
@@ -1362,6 +1594,24 @@ clapper_gtk_video_class_init (ClapperGtkVideoClass *klass)
|
||||
NULL, NULL, 1, G_MAXUINT, DEFAULT_TOUCH_FADE_DELAY,
|
||||
G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
|
||||
|
||||
/**
|
||||
* ClapperGtkVideo:auto-inhibit:
|
||||
*
|
||||
* Try to automatically inhibit session when video is playing.
|
||||
*/
|
||||
param_specs[PROP_AUTO_INHIBIT] = g_param_spec_boolean ("auto-inhibit",
|
||||
NULL, NULL, DEFAULT_AUTO_INHIBIT,
|
||||
G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
|
||||
|
||||
/**
|
||||
* ClapperGtkVideo:inhibited:
|
||||
*
|
||||
* Get whether session is currently inhibited by the video.
|
||||
*/
|
||||
param_specs[PROP_INHIBITED] = g_param_spec_boolean ("inhibited",
|
||||
NULL, NULL, FALSE,
|
||||
G_PARAM_READABLE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
|
||||
|
||||
/**
|
||||
* ClapperGtkVideo::toggle-fullscreen:
|
||||
* @video: a #ClapperGtkVideo
|
||||
@@ -1393,8 +1643,6 @@ clapper_gtk_video_class_init (ClapperGtkVideoClass *klass)
|
||||
|
||||
g_object_class_install_properties (gobject_class, PROP_LAST, param_specs);
|
||||
|
||||
/* FIXME: 1.0: Remove these actions, since they were moved to
|
||||
* base class AV widget, but are here for compat reasons. */
|
||||
gtk_widget_class_install_action (widget_class, "video.toggle-play", NULL, toggle_play_action_cb);
|
||||
gtk_widget_class_install_action (widget_class, "video.play", NULL, play_action_cb);
|
||||
gtk_widget_class_install_action (widget_class, "video.pause", NULL, pause_action_cb);
|
||||
|
@@ -12,8 +12,9 @@
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, see
|
||||
* <https://www.gnu.org/licenses/>.
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
@@ -27,7 +28,6 @@
|
||||
#include <gtk/gtk.h>
|
||||
#include <clapper/clapper.h>
|
||||
|
||||
#include <clapper-gtk/clapper-gtk-av.h>
|
||||
#include <clapper-gtk/clapper-gtk-visibility.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
@@ -36,7 +36,7 @@ G_BEGIN_DECLS
|
||||
#define CLAPPER_GTK_VIDEO_CAST(obj) ((ClapperGtkVideo *)(obj))
|
||||
|
||||
CLAPPER_GTK_API
|
||||
G_DECLARE_FINAL_TYPE (ClapperGtkVideo, clapper_gtk_video, CLAPPER_GTK, VIDEO, ClapperGtkAv)
|
||||
G_DECLARE_FINAL_TYPE (ClapperGtkVideo, clapper_gtk_video, CLAPPER_GTK, VIDEO, GtkWidget)
|
||||
|
||||
CLAPPER_GTK_API
|
||||
GtkWidget * clapper_gtk_video_new (void);
|
||||
@@ -47,7 +47,7 @@ void clapper_gtk_video_add_overlay (ClapperGtkVideo *video, GtkWidget *widget);
|
||||
CLAPPER_GTK_API
|
||||
void clapper_gtk_video_add_fading_overlay (ClapperGtkVideo *video, GtkWidget *widget);
|
||||
|
||||
CLAPPER_GTK_DEPRECATED_FOR(clapper_gtk_av_get_player)
|
||||
CLAPPER_GTK_API
|
||||
ClapperPlayer * clapper_gtk_video_get_player (ClapperGtkVideo *video);
|
||||
|
||||
CLAPPER_GTK_API
|
||||
@@ -62,13 +62,13 @@ void clapper_gtk_video_set_touch_fade_delay (ClapperGtkVideo *video, guint delay
|
||||
CLAPPER_GTK_API
|
||||
guint clapper_gtk_video_get_touch_fade_delay (ClapperGtkVideo *video);
|
||||
|
||||
CLAPPER_GTK_DEPRECATED_FOR(clapper_gtk_av_set_auto_inhibit)
|
||||
CLAPPER_GTK_API
|
||||
void clapper_gtk_video_set_auto_inhibit (ClapperGtkVideo *video, gboolean inhibit);
|
||||
|
||||
CLAPPER_GTK_DEPRECATED_FOR(clapper_gtk_av_get_auto_inhibit)
|
||||
CLAPPER_GTK_API
|
||||
gboolean clapper_gtk_video_get_auto_inhibit (ClapperGtkVideo *video);
|
||||
|
||||
CLAPPER_GTK_DEPRECATED_FOR(clapper_gtk_av_get_inhibited)
|
||||
CLAPPER_GTK_API
|
||||
gboolean clapper_gtk_video_get_inhibited (ClapperGtkVideo *video);
|
||||
|
||||
G_END_DECLS
|
||||
|
@@ -12,8 +12,9 @@
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, see
|
||||
* <https://www.gnu.org/licenses/>.
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
@@ -23,8 +24,6 @@
|
||||
#include <clapper-gtk/clapper-gtk-enums.h>
|
||||
#include <clapper-gtk/clapper-gtk-version.h>
|
||||
|
||||
#include <clapper-gtk/clapper-gtk-audio.h>
|
||||
#include <clapper-gtk/clapper-gtk-av.h>
|
||||
#include <clapper-gtk/clapper-gtk-billboard.h>
|
||||
#include <clapper-gtk/clapper-gtk-container.h>
|
||||
#include <clapper-gtk/clapper-gtk-extra-menu-button.h>
|
||||
|
@@ -129,15 +129,6 @@ clapper-gtk-seek-bar label {
|
||||
margin-left: 2px;
|
||||
margin-right: 2px;
|
||||
}
|
||||
clapper-gtk-seek-bar scale marks .custom1 indicator {
|
||||
color: tomato;
|
||||
}
|
||||
clapper-gtk-seek-bar scale marks .custom2 indicator {
|
||||
color: goldenrod;
|
||||
}
|
||||
clapper-gtk-seek-bar scale marks .custom3 indicator {
|
||||
color: limegreen;
|
||||
}
|
||||
|
||||
clapper-gtk-extra-menu-button popover .spinsidebutton {
|
||||
min-width: 28px;
|
||||
|
@@ -90,8 +90,6 @@ clappergtk_conf_inc = [
|
||||
|
||||
clappergtk_headers = [
|
||||
'clapper-gtk.h',
|
||||
'clapper-gtk-audio.h',
|
||||
'clapper-gtk-av.h',
|
||||
'clapper-gtk-enums.h',
|
||||
'clapper-gtk-billboard.h',
|
||||
'clapper-gtk-container.h',
|
||||
@@ -111,8 +109,6 @@ clappergtk_headers = [
|
||||
clappergtk_visibility_header,
|
||||
]
|
||||
clappergtk_sources = [
|
||||
'clapper-gtk-audio.c',
|
||||
'clapper-gtk-av.c',
|
||||
'clapper-gtk-billboard.c',
|
||||
'clapper-gtk-buffering-animation.c',
|
||||
'clapper-gtk-buffering-paintable.c',
|
||||
@@ -131,7 +127,6 @@ clappergtk_sources = [
|
||||
'clapper-gtk-toggle-fullscreen-button.c',
|
||||
'clapper-gtk-toggle-play-button.c',
|
||||
'clapper-gtk-utils.c',
|
||||
'clapper-gtk-version.c',
|
||||
'clapper-gtk-video.c',
|
||||
'clapper-gtk-video-placeholder.c',
|
||||
clappergtk_resources,
|
||||
@@ -181,6 +176,7 @@ if build_gir
|
||||
clappergtk_enums,
|
||||
],
|
||||
extra_args: [
|
||||
gir_init_section,
|
||||
'--quiet',
|
||||
'--warn-all',
|
||||
'-DCLAPPER_GTK_COMPILATION',
|
||||
|
@@ -3,7 +3,7 @@ msgstr ""
|
||||
"Project-Id-Version: clapper\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2025-01-07 19:03+0100\n"
|
||||
"PO-Revision-Date: 2025-01-07 18:31\n"
|
||||
"PO-Revision-Date: 2025-06-14 15:48\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: Arabic\n"
|
||||
"Language: ar_SA\n"
|
||||
@@ -20,7 +20,7 @@ msgstr ""
|
||||
#: src/lib/clapper-gtk/ui/clapper-gtk-extra-menu-button.ui:9
|
||||
#: src/lib/clapper-gtk/clapper-gtk-extra-menu-button.c:228
|
||||
msgid "Video"
|
||||
msgstr ""
|
||||
msgstr "الفيديو"
|
||||
|
||||
#: src/lib/clapper-gtk/ui/clapper-gtk-extra-menu-button.ui:17
|
||||
#: src/lib/clapper-gtk/clapper-gtk-extra-menu-button.c:229
|
||||
@@ -30,50 +30,50 @@ msgstr "الصوت"
|
||||
#: src/lib/clapper-gtk/ui/clapper-gtk-extra-menu-button.ui:25
|
||||
#: src/lib/clapper-gtk/clapper-gtk-extra-menu-button.c:230
|
||||
msgid "Subtitles"
|
||||
msgstr "التَّرْجَمَةً"
|
||||
msgstr "الترجَمة"
|
||||
|
||||
#: src/lib/clapper-gtk/ui/clapper-gtk-extra-menu-button.ui:28
|
||||
msgid "Show Subtitles"
|
||||
msgstr ""
|
||||
msgstr "اعرض الترجَمة"
|
||||
|
||||
#: src/lib/clapper-gtk/ui/clapper-gtk-extra-menu-button.ui:32
|
||||
msgid "Open…"
|
||||
msgstr ""
|
||||
msgstr "افتح…"
|
||||
|
||||
#: src/lib/clapper-gtk/ui/clapper-gtk-extra-menu-button.ui:75
|
||||
msgid "Mute"
|
||||
msgstr ""
|
||||
msgstr "اكتم"
|
||||
|
||||
#: src/lib/clapper-gtk/ui/clapper-gtk-extra-menu-button.ui:119
|
||||
msgid "Reset"
|
||||
msgstr ""
|
||||
msgstr "صفِّر"
|
||||
|
||||
#: src/lib/clapper-gtk/ui/clapper-gtk-video-placeholder.ui:25
|
||||
msgid "External video output"
|
||||
msgstr ""
|
||||
msgstr "مخرج الفيديو الخارجي"
|
||||
|
||||
#: src/lib/clapper-gtk/ui/clapper-gtk-video-placeholder.ui:37
|
||||
msgid "Used video sink cannot be embedded within application window"
|
||||
msgstr ""
|
||||
msgstr "لا يمكن تضمين بالوعة الفيديو المستخدمة في نافذة التطبيق"
|
||||
|
||||
#: src/lib/clapper-gtk/clapper-gtk-status.c:79
|
||||
msgid "Unplayable Content"
|
||||
msgstr ""
|
||||
msgstr "محتوى غير قابل للتشغيل"
|
||||
|
||||
#. TRANSLATORS: Please do not try to translate "GStreamer" (it is a library name).
|
||||
#: src/lib/clapper-gtk/clapper-gtk-status.c:89
|
||||
#, c-format
|
||||
msgid "Your GStreamer installation is missing a plugin: %s"
|
||||
msgstr ""
|
||||
msgstr "يفتقد تنصيبك لـGStreamer ملحقًا: %s"
|
||||
|
||||
#: src/lib/clapper-gtk/clapper-gtk-status.c:90
|
||||
msgid "Missing Plugin"
|
||||
msgstr ""
|
||||
msgstr "ملحق مفقود"
|
||||
|
||||
#: src/lib/clapper-gtk/clapper-gtk-stream-check-button.c:82
|
||||
#: src/lib/clapper-gtk/clapper-gtk-stream-check-button.c:126
|
||||
msgid "Undetermined"
|
||||
msgstr "غير محدّد"
|
||||
msgstr "غير محدَّد"
|
||||
|
||||
#: src/lib/clapper-gtk/clapper-gtk-stream-check-button.c:82
|
||||
msgid "Channels"
|
||||
@@ -81,9 +81,9 @@ msgstr "قنوات"
|
||||
|
||||
#: src/lib/clapper-gtk/clapper-gtk-title-label.c:91
|
||||
msgid "No media"
|
||||
msgstr ""
|
||||
msgstr "لا وسائط"
|
||||
|
||||
#: src/lib/clapper-gtk/clapper-gtk-title-label.c:103
|
||||
msgid "Unknown title"
|
||||
msgstr ""
|
||||
msgstr "عنوان مجهول"
|
||||
|
||||
|
@@ -3,7 +3,7 @@ msgstr ""
|
||||
"Project-Id-Version: clapper\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2025-01-07 19:03+0100\n"
|
||||
"PO-Revision-Date: 2025-01-07 18:32\n"
|
||||
"PO-Revision-Date: 2025-05-08 07:56\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: Chinese Simplified\n"
|
||||
"Language: zh_CN\n"
|
||||
@@ -50,11 +50,11 @@ msgstr "重置"
|
||||
|
||||
#: src/lib/clapper-gtk/ui/clapper-gtk-video-placeholder.ui:25
|
||||
msgid "External video output"
|
||||
msgstr ""
|
||||
msgstr "外部视频输出"
|
||||
|
||||
#: src/lib/clapper-gtk/ui/clapper-gtk-video-placeholder.ui:37
|
||||
msgid "Used video sink cannot be embedded within application window"
|
||||
msgstr ""
|
||||
msgstr "已使用的视频接受器不能嵌入到应用程序窗口"
|
||||
|
||||
#: src/lib/clapper-gtk/clapper-gtk-status.c:79
|
||||
msgid "Unplayable Content"
|
||||
|
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface domain="clapper-gtk">
|
||||
<template class="ClapperGtkVideo" parent="ClapperGtkAv">
|
||||
<template class="ClapperGtkVideo" parent="GtkWidget">
|
||||
<child type="overlay">
|
||||
<object class="ClapperGtkStatus" id="status">
|
||||
<property name="halign">center</property>
|
||||
|
@@ -12,8 +12,9 @@
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, see
|
||||
* <https://www.gnu.org/licenses/>.
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
@@ -44,16 +45,12 @@ void clapper_app_bus_post_refresh_streams (ClapperAppBus *app_bus, GstObject *sr
|
||||
|
||||
void clapper_app_bus_post_refresh_timeline (ClapperAppBus *app_bus, GstObject *src);
|
||||
|
||||
void clapper_app_bus_post_insert_playlist (ClapperAppBus *app_bus, GstObject *src, GstObject *playlist_item, GObject *playlist);
|
||||
|
||||
void clapper_app_bus_post_simple_signal (ClapperAppBus *app_bus, GstObject *src, guint signal_id);
|
||||
|
||||
void clapper_app_bus_post_object_desc_signal (ClapperAppBus *app_bus, GstObject *src, guint signal_id, GstObject *object, const gchar *desc);
|
||||
|
||||
void clapper_app_bus_post_desc_with_details_signal (ClapperAppBus *app_bus, GstObject *src, guint signal_id, const gchar *desc, const gchar *details);
|
||||
|
||||
void clapper_app_bus_post_message_signal (ClapperAppBus *app_bus, GstObject *src, guint signal_id, GstMessage *msg);
|
||||
|
||||
void clapper_app_bus_post_error_signal (ClapperAppBus *app_bus, GstObject *src, guint signal_id, GError *error, const gchar *debug_info);
|
||||
|
||||
G_END_DECLS
|
||||
|
@@ -12,8 +12,9 @@
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, see
|
||||
* <https://www.gnu.org/licenses/>.
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include <gio/gio.h>
|
||||
@@ -21,7 +22,6 @@
|
||||
#include "clapper-bus-private.h"
|
||||
#include "clapper-app-bus-private.h"
|
||||
#include "clapper-player-private.h"
|
||||
#include "clapper-queue-private.h"
|
||||
#include "clapper-media-item-private.h"
|
||||
#include "clapper-timeline-private.h"
|
||||
|
||||
@@ -42,11 +42,9 @@ enum
|
||||
CLAPPER_APP_BUS_STRUCTURE_PROP_NOTIFY,
|
||||
CLAPPER_APP_BUS_STRUCTURE_REFRESH_STREAMS,
|
||||
CLAPPER_APP_BUS_STRUCTURE_REFRESH_TIMELINE,
|
||||
CLAPPER_APP_BUS_STRUCTURE_INSERT_PLAYLIST,
|
||||
CLAPPER_APP_BUS_STRUCTURE_SIMPLE_SIGNAL,
|
||||
CLAPPER_APP_BUS_STRUCTURE_OBJECT_DESC_SIGNAL,
|
||||
CLAPPER_APP_BUS_STRUCTURE_DESC_WITH_DETAILS_SIGNAL,
|
||||
CLAPPER_APP_BUS_STRUCTURE_MESSAGE_SIGNAL,
|
||||
CLAPPER_APP_BUS_STRUCTURE_ERROR_SIGNAL
|
||||
};
|
||||
|
||||
@@ -55,11 +53,9 @@ static ClapperBusQuark _structure_quarks[] = {
|
||||
{"prop-notify", 0},
|
||||
{"refresh-streams", 0},
|
||||
{"refresh-timeline", 0},
|
||||
{"insert-playlist", 0},
|
||||
{"simple-signal", 0},
|
||||
{"object-desc-signal", 0},
|
||||
{"desc-with-details-signal", 0},
|
||||
{"message", 0},
|
||||
{"error-signal", 0},
|
||||
{NULL, 0}
|
||||
};
|
||||
@@ -70,7 +66,6 @@ enum
|
||||
CLAPPER_APP_BUS_FIELD_PSPEC,
|
||||
CLAPPER_APP_BUS_FIELD_SIGNAL_ID,
|
||||
CLAPPER_APP_BUS_FIELD_OBJECT,
|
||||
CLAPPER_APP_BUS_FIELD_OTHER_OBJECT,
|
||||
CLAPPER_APP_BUS_FIELD_DESC,
|
||||
CLAPPER_APP_BUS_FIELD_DETAILS,
|
||||
CLAPPER_APP_BUS_FIELD_ERROR,
|
||||
@@ -82,7 +77,6 @@ static ClapperBusQuark _field_quarks[] = {
|
||||
{"pspec", 0},
|
||||
{"signal-id", 0},
|
||||
{"object", 0},
|
||||
{"other-object", 0},
|
||||
{"desc", 0},
|
||||
{"details", 0},
|
||||
{"error", 0},
|
||||
@@ -167,36 +161,6 @@ _handle_refresh_timeline_msg (GstMessage *msg, const GstStructure *structure)
|
||||
clapper_timeline_refresh (timeline);
|
||||
}
|
||||
|
||||
void
|
||||
clapper_app_bus_post_insert_playlist (ClapperAppBus *self, GstObject *src,
|
||||
GstObject *playlist_item, GObject *playlist)
|
||||
{
|
||||
GstStructure *structure = gst_structure_new_id (_STRUCTURE_QUARK (INSERT_PLAYLIST),
|
||||
_FIELD_QUARK (OBJECT), GST_TYPE_OBJECT, playlist_item,
|
||||
_FIELD_QUARK (OTHER_OBJECT), G_TYPE_OBJECT, playlist,
|
||||
NULL);
|
||||
gst_bus_post (GST_BUS_CAST (self), gst_message_new_application (src, structure));
|
||||
}
|
||||
|
||||
static inline void
|
||||
_handle_insert_playlist_msg (GstMessage *msg, const GstStructure *structure)
|
||||
{
|
||||
ClapperPlayer *player = CLAPPER_PLAYER_CAST (GST_MESSAGE_SRC (msg));
|
||||
ClapperQueue *queue = clapper_player_get_queue (player);
|
||||
GstObject *playlist_item;
|
||||
GObject *playlist;
|
||||
|
||||
gst_structure_id_get (structure,
|
||||
_FIELD_QUARK (OBJECT), GST_TYPE_OBJECT, &playlist_item,
|
||||
_FIELD_QUARK (OTHER_OBJECT), G_TYPE_OBJECT, &playlist,
|
||||
NULL);
|
||||
clapper_queue_handle_playlist (queue,
|
||||
CLAPPER_MEDIA_ITEM (playlist_item), G_LIST_STORE (playlist));
|
||||
|
||||
gst_object_unref (playlist_item);
|
||||
g_object_unref (playlist);
|
||||
}
|
||||
|
||||
void
|
||||
clapper_app_bus_post_simple_signal (ClapperAppBus *self, GstObject *src, guint signal_id)
|
||||
{
|
||||
@@ -278,53 +242,6 @@ _handle_desc_with_details_signal_msg (GstMessage *msg, const GstStructure *struc
|
||||
g_free (details);
|
||||
}
|
||||
|
||||
void
|
||||
clapper_app_bus_post_message_signal (ClapperAppBus *self,
|
||||
GstObject *src, guint signal_id, GstMessage *msg)
|
||||
{
|
||||
/* Check for any "message" signal connection */
|
||||
if (g_signal_handler_find (src, G_SIGNAL_MATCH_ID,
|
||||
signal_id, 0, NULL, NULL, NULL) != 0) {
|
||||
const GstStructure *structure = gst_message_get_structure (msg);
|
||||
GQuark detail;
|
||||
|
||||
if (G_UNLIKELY (structure == NULL))
|
||||
return;
|
||||
|
||||
detail = g_quark_from_string (gst_structure_get_name (structure));
|
||||
|
||||
/* If specific detail is connected or ALL "message" handler */
|
||||
if (g_signal_handler_find (src, G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_DETAIL,
|
||||
signal_id, detail, NULL, NULL, NULL) != 0
|
||||
|| g_signal_handler_find (src, G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_DETAIL,
|
||||
signal_id, 0, NULL, NULL, NULL) != 0) {
|
||||
GstStructure *structure = gst_structure_new_id (_STRUCTURE_QUARK (MESSAGE_SIGNAL),
|
||||
_FIELD_QUARK (SIGNAL_ID), G_TYPE_UINT, signal_id,
|
||||
_FIELD_QUARK (DETAILS), G_TYPE_UINT, detail,
|
||||
_FIELD_QUARK (OBJECT), GST_TYPE_MESSAGE, msg,
|
||||
NULL);
|
||||
gst_bus_post (GST_BUS_CAST (self), gst_message_new_application (src, structure));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static inline void
|
||||
_handle_message_signal_msg (GstMessage *msg, const GstStructure *structure)
|
||||
{
|
||||
guint signal_id = 0;
|
||||
GQuark detail = 0;
|
||||
GstMessage *fwd_message = NULL;
|
||||
|
||||
gst_structure_id_get (structure,
|
||||
_FIELD_QUARK (SIGNAL_ID), G_TYPE_UINT, &signal_id,
|
||||
_FIELD_QUARK (DETAILS), G_TYPE_UINT, &detail,
|
||||
_FIELD_QUARK (OBJECT), GST_TYPE_MESSAGE, &fwd_message,
|
||||
NULL);
|
||||
g_signal_emit (_MESSAGE_SRC_GOBJECT (msg), signal_id, detail, fwd_message);
|
||||
|
||||
gst_message_unref (fwd_message);
|
||||
}
|
||||
|
||||
void
|
||||
clapper_app_bus_post_error_signal (ClapperAppBus *self,
|
||||
GstObject *src, guint signal_id,
|
||||
@@ -369,14 +286,10 @@ clapper_app_bus_message_func (GstBus *bus, GstMessage *msg, gpointer user_data G
|
||||
_handle_refresh_streams_msg (msg, structure);
|
||||
else if (quark == _STRUCTURE_QUARK (REFRESH_TIMELINE))
|
||||
_handle_refresh_timeline_msg (msg, structure);
|
||||
else if (quark == _STRUCTURE_QUARK (INSERT_PLAYLIST))
|
||||
_handle_insert_playlist_msg (msg, structure);
|
||||
else if (quark == _STRUCTURE_QUARK (SIMPLE_SIGNAL))
|
||||
_handle_simple_signal_msg (msg, structure);
|
||||
else if (quark == _STRUCTURE_QUARK (OBJECT_DESC_SIGNAL))
|
||||
_handle_object_desc_signal_msg (msg, structure);
|
||||
else if (quark == _STRUCTURE_QUARK (MESSAGE_SIGNAL))
|
||||
_handle_message_signal_msg (msg, structure);
|
||||
else if (quark == _STRUCTURE_QUARK (ERROR_SIGNAL))
|
||||
_handle_error_signal_msg (msg, structure);
|
||||
else if (quark == _STRUCTURE_QUARK (DESC_WITH_DETAILS_SIGNAL))
|
||||
|
@@ -12,8 +12,9 @@
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, see
|
||||
* <https://www.gnu.org/licenses/>.
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
@@ -12,8 +12,9 @@
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, see
|
||||
* <https://www.gnu.org/licenses/>.
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
/**
|
||||
|
@@ -12,8 +12,9 @@
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, see
|
||||
* <https://www.gnu.org/licenses/>.
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
@@ -1,45 +0,0 @@
|
||||
/* Clapper Playback Library
|
||||
* Copyright (C) 2025 Rafał Dzięgiel <rafostar.github@gmail.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, see
|
||||
* <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#if !defined(__CLAPPER_INSIDE__) && !defined(CLAPPER_COMPILATION)
|
||||
#error "Only <clapper/clapper.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#include <glib.h>
|
||||
#include <glib-object.h>
|
||||
|
||||
#include <clapper/clapper-visibility.h>
|
||||
#include <clapper/clapper-enhancer-proxy-list.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
CLAPPER_API
|
||||
void clapper_init (int *argc, char **argv[]);
|
||||
|
||||
CLAPPER_API
|
||||
gboolean clapper_init_check (int *argc, char **argv[]);
|
||||
|
||||
CLAPPER_DEPRECATED
|
||||
gboolean clapper_enhancer_check (GType iface_type, const gchar *scheme, const gchar *host, const gchar **name);
|
||||
|
||||
CLAPPER_API
|
||||
ClapperEnhancerProxyList * clapper_get_global_enhancer_proxies (void);
|
||||
|
||||
G_END_DECLS
|
@@ -12,8 +12,9 @@
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, see
|
||||
* <https://www.gnu.org/licenses/>.
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
@@ -1,107 +0,0 @@
|
||||
/* Clapper Playback Library
|
||||
* Copyright (C) 2025 Rafał Dzięgiel <rafostar.github@gmail.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, see
|
||||
* <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <glib.h>
|
||||
#include <glib-object.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
void clapper_cache_initialize (void);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
gboolean clapper_cache_is_disabled (void);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
GMappedFile * clapper_cache_open (const gchar *filename, const gchar **data, GError **error);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
gboolean clapper_cache_read_boolean (const gchar **data);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
gint clapper_cache_read_int (const gchar **data);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
guint clapper_cache_read_uint (const gchar **data);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
gint64 clapper_cache_read_int64 (const gchar **data);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
gdouble clapper_cache_read_double (const gchar **data);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
const gchar * clapper_cache_read_string (const gchar **data);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
const guint8 * clapper_cache_read_data (const gchar **data, gsize *size);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
GType clapper_cache_read_enum (const gchar **data);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
GType clapper_cache_read_flags (const gchar **data);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
GType clapper_cache_read_iface (const gchar **data);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
GParamSpec * clapper_cache_read_pspec (const gchar **data);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
GByteArray * clapper_cache_create (void);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
void clapper_cache_store_boolean (GByteArray *bytes, gboolean val);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
void clapper_cache_store_int (GByteArray *bytes, gint val);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
void clapper_cache_store_uint (GByteArray *bytes, guint val);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
void clapper_cache_store_int64 (GByteArray *bytes, gint64 val);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
void clapper_cache_store_double (GByteArray *bytes, gdouble val);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
void clapper_cache_store_string (GByteArray *bytes, const gchar *val);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
void clapper_cache_store_data (GByteArray *bytes, const guint8 *val, gsize val_size);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
void clapper_cache_store_enum (GByteArray *bytes, GType enum_type);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
void clapper_cache_store_flags (GByteArray *bytes, GType flags_type);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
gboolean clapper_cache_store_iface (GByteArray *bytes, GType iface);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
gboolean clapper_cache_store_pspec (GByteArray *bytes, GParamSpec *pspec);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
gboolean clapper_cache_write (const gchar *filename, GByteArray *bytes, GError **error);
|
||||
|
||||
G_END_DECLS
|
@@ -1,548 +0,0 @@
|
||||
/* Clapper Playback Library
|
||||
* Copyright (C) 2025 Rafał Dzięgiel <rafostar.github@gmail.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, see
|
||||
* <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "clapper-cache-private.h"
|
||||
#include "clapper-version.h"
|
||||
|
||||
#include "clapper-extractable.h"
|
||||
#include "clapper-playlistable.h"
|
||||
#include "clapper-reactable.h"
|
||||
|
||||
#define CLAPPER_CACHE_HEADER "CLAPPER"
|
||||
|
||||
typedef enum
|
||||
{
|
||||
CLAPPER_CACHE_IFACE_EXTRACTABLE = 1,
|
||||
CLAPPER_CACHE_IFACE_PLAYLISTABLE,
|
||||
CLAPPER_CACHE_IFACE_REACTABLE,
|
||||
} ClapperCacheIfaces;
|
||||
|
||||
static GArray *enum_registry = NULL;
|
||||
static GArray *flags_registry = NULL;
|
||||
static gboolean cache_disabled = FALSE;
|
||||
|
||||
void
|
||||
clapper_cache_initialize (void)
|
||||
{
|
||||
const gchar *env = g_getenv ("CLAPPER_DISABLE_CACHE");
|
||||
|
||||
if (G_LIKELY (!env || !g_str_has_prefix (env, "1"))) {
|
||||
enum_registry = g_array_new (FALSE, TRUE, sizeof (GEnumValue *));
|
||||
flags_registry = g_array_new (FALSE, TRUE, sizeof (GFlagsValue *));
|
||||
} else {
|
||||
cache_disabled = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
gboolean
|
||||
clapper_cache_is_disabled (void)
|
||||
{
|
||||
return cache_disabled;
|
||||
}
|
||||
|
||||
GMappedFile *
|
||||
clapper_cache_open (const gchar *filename, const gchar **data, GError **error)
|
||||
{
|
||||
GMappedFile *file;
|
||||
|
||||
if (G_UNLIKELY (cache_disabled))
|
||||
return NULL;
|
||||
|
||||
if (!(file = g_mapped_file_new (filename, FALSE, error)))
|
||||
return NULL;
|
||||
|
||||
if (G_UNLIKELY (g_mapped_file_get_length (file) == 0)) {
|
||||
g_mapped_file_unref (file);
|
||||
g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
|
||||
"File is empty");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
*data = g_mapped_file_get_contents (file);
|
||||
|
||||
/* Header name check */
|
||||
if (G_UNLIKELY (g_strcmp0 (*data, CLAPPER_CACHE_HEADER) != 0)) {
|
||||
g_mapped_file_unref (file);
|
||||
g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
|
||||
"Invalid file header");
|
||||
return NULL;
|
||||
}
|
||||
*data += strlen (*data) + 1;
|
||||
|
||||
/* Header version check */
|
||||
if (clapper_cache_read_uint (data) != CLAPPER_VERSION_HEX) {
|
||||
g_mapped_file_unref (file);
|
||||
/* Just different version, so no error set */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return file;
|
||||
}
|
||||
|
||||
inline gboolean
|
||||
clapper_cache_read_boolean (const gchar **data)
|
||||
{
|
||||
gboolean val = *(const gboolean *) *data;
|
||||
*data += sizeof (gboolean);
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
inline gint
|
||||
clapper_cache_read_int (const gchar **data)
|
||||
{
|
||||
gint val = *(const gint *) *data;
|
||||
*data += sizeof (gint);
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
inline guint
|
||||
clapper_cache_read_uint (const gchar **data)
|
||||
{
|
||||
guint val = *(const guint *) *data;
|
||||
*data += sizeof (guint);
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
inline gint64
|
||||
clapper_cache_read_int64 (const gchar **data)
|
||||
{
|
||||
gint64 val = *(const gint64 *) *data;
|
||||
*data += sizeof (gint64);
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
inline gdouble
|
||||
clapper_cache_read_double (const gchar **data)
|
||||
{
|
||||
gdouble val = *(const gdouble *) *data;
|
||||
*data += sizeof (gdouble);
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
inline const gchar *
|
||||
clapper_cache_read_string (const gchar **data)
|
||||
{
|
||||
const gboolean is_null = clapper_cache_read_boolean (data);
|
||||
const gchar *str = NULL;
|
||||
|
||||
if (!is_null) {
|
||||
str = *data;
|
||||
*data += strlen (str) + 1;
|
||||
}
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
inline const guint8 *
|
||||
clapper_cache_read_data (const gchar **data, gsize *size)
|
||||
{
|
||||
const guint8 *val = NULL;
|
||||
|
||||
*size = *(const gsize *) *data;
|
||||
*data += sizeof (gsize);
|
||||
|
||||
if (G_LIKELY (*size > 0)) {
|
||||
val = (const guint8 *) *data;
|
||||
*data += *size;
|
||||
}
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
inline GType
|
||||
clapper_cache_read_enum (const gchar **data)
|
||||
{
|
||||
GType type;
|
||||
const gchar *enum_name;
|
||||
guint i, n_values;
|
||||
|
||||
enum_name = clapper_cache_read_string (data);
|
||||
n_values = clapper_cache_read_uint (data);
|
||||
|
||||
/* If not registered yet */
|
||||
if ((type = g_type_from_name (enum_name)) == 0) {
|
||||
GEnumValue *values = g_new0 (GEnumValue, n_values + 1);
|
||||
|
||||
for (i = 0; i < n_values; ++i) {
|
||||
values[i].value = clapper_cache_read_int (data);
|
||||
values[i].value_name = g_intern_string (clapper_cache_read_string (data));
|
||||
values[i].value_nick = g_intern_string (clapper_cache_read_string (data));
|
||||
}
|
||||
g_array_append_val (enum_registry, values); // store statically
|
||||
|
||||
type = g_enum_register_static (g_intern_string (enum_name),
|
||||
g_array_index (enum_registry, GEnumValue *, enum_registry->len - 1));
|
||||
} else {
|
||||
/* Skip over data */
|
||||
for (i = 0; i < n_values; ++i) {
|
||||
clapper_cache_read_int (data); // value
|
||||
clapper_cache_read_string (data); // value_name
|
||||
clapper_cache_read_string (data); // value_nick
|
||||
}
|
||||
}
|
||||
|
||||
return type;
|
||||
}
|
||||
|
||||
inline GType
|
||||
clapper_cache_read_flags (const gchar **data)
|
||||
{
|
||||
GType type;
|
||||
const gchar *flags_name;
|
||||
guint i, n_values;
|
||||
|
||||
flags_name = clapper_cache_read_string (data);
|
||||
n_values = clapper_cache_read_uint (data);
|
||||
|
||||
/* If not registered yet */
|
||||
if ((type = g_type_from_name (flags_name)) == 0) {
|
||||
GFlagsValue *values = g_new0 (GFlagsValue, n_values + 1);
|
||||
|
||||
for (i = 0; i < n_values; ++i) {
|
||||
values[i].value = clapper_cache_read_int (data);
|
||||
values[i].value_name = g_intern_string (clapper_cache_read_string (data));
|
||||
values[i].value_nick = g_intern_string (clapper_cache_read_string (data));
|
||||
}
|
||||
g_array_append_val (flags_registry, values); // store statically
|
||||
|
||||
type = g_flags_register_static (g_intern_string (flags_name),
|
||||
g_array_index (flags_registry, GFlagsValue *, flags_registry->len - 1));
|
||||
} else {
|
||||
/* Skip over data */
|
||||
for (i = 0; i < n_values; ++i) {
|
||||
clapper_cache_read_int (data); // value
|
||||
clapper_cache_read_string (data); // value_name
|
||||
clapper_cache_read_string (data); // value_nick
|
||||
}
|
||||
}
|
||||
|
||||
return type;
|
||||
}
|
||||
|
||||
GType
|
||||
clapper_cache_read_iface (const gchar **data)
|
||||
{
|
||||
gint iface_id = clapper_cache_read_int (data);
|
||||
|
||||
switch (iface_id) {
|
||||
case CLAPPER_CACHE_IFACE_EXTRACTABLE:
|
||||
return CLAPPER_TYPE_EXTRACTABLE;
|
||||
case CLAPPER_CACHE_IFACE_PLAYLISTABLE:
|
||||
return CLAPPER_TYPE_PLAYLISTABLE;
|
||||
case CLAPPER_CACHE_IFACE_REACTABLE:
|
||||
return CLAPPER_TYPE_REACTABLE;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
GParamSpec *
|
||||
clapper_cache_read_pspec (const gchar **data)
|
||||
{
|
||||
GParamSpec *pspec;
|
||||
GType value_type;
|
||||
const gchar *name, *nick, *blurb;
|
||||
GParamFlags flags;
|
||||
|
||||
value_type = *(const GType *) *data;
|
||||
*data += sizeof (GType);
|
||||
|
||||
name = clapper_cache_read_string (data);
|
||||
nick = clapper_cache_read_string (data);
|
||||
blurb = clapper_cache_read_string (data);
|
||||
|
||||
flags = *(const GParamFlags *) *data;
|
||||
*data += sizeof (GParamFlags);
|
||||
|
||||
/* NOTE: C does not guarantee order in which function arguments
|
||||
* are evaluated, so read into variables and then create pspec */
|
||||
|
||||
switch (value_type) {
|
||||
case G_TYPE_BOOLEAN:
|
||||
pspec = g_param_spec_boolean (name, nick, blurb,
|
||||
clapper_cache_read_boolean (data), flags);
|
||||
break;
|
||||
case G_TYPE_INT:{
|
||||
gint minimum = clapper_cache_read_int (data);
|
||||
gint maximum = clapper_cache_read_int (data);
|
||||
gint default_value = clapper_cache_read_int (data);
|
||||
|
||||
pspec = g_param_spec_int (name, nick, blurb,
|
||||
minimum, maximum, default_value, flags);
|
||||
break;
|
||||
}
|
||||
case G_TYPE_UINT:{
|
||||
guint minimum = clapper_cache_read_uint (data);
|
||||
guint maximum = clapper_cache_read_uint (data);
|
||||
guint default_value = clapper_cache_read_uint (data);
|
||||
|
||||
pspec = g_param_spec_uint (name, nick, blurb,
|
||||
minimum, maximum, default_value, flags);
|
||||
break;
|
||||
}
|
||||
case G_TYPE_DOUBLE:{
|
||||
gdouble minimum = clapper_cache_read_double (data);
|
||||
gdouble maximum = clapper_cache_read_double (data);
|
||||
gdouble default_value = clapper_cache_read_double (data);
|
||||
|
||||
pspec = g_param_spec_double (name, nick, blurb,
|
||||
minimum, maximum, default_value, flags);
|
||||
break;
|
||||
}
|
||||
case G_TYPE_STRING:
|
||||
pspec = g_param_spec_string (name, nick, blurb,
|
||||
clapper_cache_read_string (data), flags);
|
||||
break;
|
||||
case G_TYPE_ENUM:{
|
||||
GType enum_type = clapper_cache_read_enum (data);
|
||||
gint default_value = clapper_cache_read_int (data);
|
||||
|
||||
pspec = g_param_spec_enum (name, nick, blurb,
|
||||
enum_type, default_value, flags);
|
||||
break;
|
||||
}
|
||||
case G_TYPE_FLAGS:{
|
||||
GType flags_type = clapper_cache_read_flags (data);
|
||||
guint default_value = clapper_cache_read_uint (data);
|
||||
|
||||
pspec = g_param_spec_flags (name, nick, blurb,
|
||||
flags_type, default_value, flags);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return g_param_spec_ref_sink (pspec);
|
||||
}
|
||||
|
||||
GByteArray *
|
||||
clapper_cache_create (void)
|
||||
{
|
||||
GByteArray *bytes;
|
||||
|
||||
if (G_UNLIKELY (cache_disabled))
|
||||
return NULL;
|
||||
|
||||
bytes = g_byte_array_new ();
|
||||
|
||||
/* NOTE: We do not store whether string is NULL here, since it never is */
|
||||
g_byte_array_append (bytes, (const guint8 *) CLAPPER_CACHE_HEADER, 8); // 7 + 1
|
||||
clapper_cache_store_uint (bytes, CLAPPER_VERSION_HEX);
|
||||
|
||||
return bytes;
|
||||
}
|
||||
|
||||
inline void
|
||||
clapper_cache_store_boolean (GByteArray *bytes, gboolean val)
|
||||
{
|
||||
g_byte_array_append (bytes, (const guint8 *) &val, sizeof (gboolean));
|
||||
}
|
||||
|
||||
inline void
|
||||
clapper_cache_store_int (GByteArray *bytes, gint val)
|
||||
{
|
||||
g_byte_array_append (bytes, (const guint8 *) &val, sizeof (gint));
|
||||
}
|
||||
|
||||
inline void
|
||||
clapper_cache_store_uint (GByteArray *bytes, guint val)
|
||||
{
|
||||
g_byte_array_append (bytes, (const guint8 *) &val, sizeof (guint));
|
||||
}
|
||||
|
||||
inline void
|
||||
clapper_cache_store_int64 (GByteArray *bytes, gint64 val)
|
||||
{
|
||||
g_byte_array_append (bytes, (const guint8 *) &val, sizeof (gint64));
|
||||
}
|
||||
|
||||
inline void
|
||||
clapper_cache_store_double (GByteArray *bytes, gdouble val)
|
||||
{
|
||||
g_byte_array_append (bytes, (const guint8 *) &val, sizeof (gdouble));
|
||||
}
|
||||
|
||||
inline void
|
||||
clapper_cache_store_string (GByteArray *bytes, const gchar *val)
|
||||
{
|
||||
/* Distinguish empty string from NULL */
|
||||
const gboolean is_null = (val == NULL);
|
||||
|
||||
clapper_cache_store_boolean (bytes, is_null);
|
||||
if (!is_null)
|
||||
g_byte_array_append (bytes, (const guint8 *) val, strlen (val) + 1);
|
||||
}
|
||||
|
||||
inline void
|
||||
clapper_cache_store_data (GByteArray *bytes, const guint8 *val, gsize val_size)
|
||||
{
|
||||
g_byte_array_append (bytes, (const guint8 *) &val_size, sizeof (gsize));
|
||||
if (G_LIKELY (val_size > 0))
|
||||
g_byte_array_append (bytes, val, val_size);
|
||||
}
|
||||
|
||||
inline void
|
||||
clapper_cache_store_enum (GByteArray *bytes, GType enum_type)
|
||||
{
|
||||
GEnumClass *enum_class = G_ENUM_CLASS (g_type_class_peek (enum_type));
|
||||
guint i;
|
||||
|
||||
clapper_cache_store_string (bytes, g_type_name (enum_type));
|
||||
clapper_cache_store_uint (bytes, enum_class->n_values);
|
||||
|
||||
for (i = 0; i < enum_class->n_values; ++i) {
|
||||
clapper_cache_store_int (bytes, enum_class->values[i].value);
|
||||
clapper_cache_store_string (bytes, enum_class->values[i].value_name);
|
||||
clapper_cache_store_string (bytes, enum_class->values[i].value_nick);
|
||||
}
|
||||
}
|
||||
|
||||
inline void
|
||||
clapper_cache_store_flags (GByteArray *bytes, GType flags_type)
|
||||
{
|
||||
GFlagsClass *flags_class = G_FLAGS_CLASS (g_type_class_peek (flags_type));
|
||||
guint i;
|
||||
|
||||
clapper_cache_store_string (bytes, g_type_name (flags_type));
|
||||
clapper_cache_store_uint (bytes, flags_class->n_values);
|
||||
|
||||
for (i = 0; i < flags_class->n_values; ++i) {
|
||||
clapper_cache_store_int (bytes, flags_class->values[i].value);
|
||||
clapper_cache_store_string (bytes, flags_class->values[i].value_name);
|
||||
clapper_cache_store_string (bytes, flags_class->values[i].value_nick);
|
||||
}
|
||||
}
|
||||
|
||||
gboolean
|
||||
clapper_cache_store_iface (GByteArray *bytes, GType iface)
|
||||
{
|
||||
gint iface_id = 0;
|
||||
|
||||
if (iface == CLAPPER_TYPE_EXTRACTABLE)
|
||||
iface_id = CLAPPER_CACHE_IFACE_EXTRACTABLE;
|
||||
else if (iface == CLAPPER_TYPE_PLAYLISTABLE)
|
||||
iface_id = CLAPPER_CACHE_IFACE_PLAYLISTABLE;
|
||||
else if (iface == CLAPPER_TYPE_REACTABLE)
|
||||
iface_id = CLAPPER_CACHE_IFACE_REACTABLE;
|
||||
else
|
||||
return FALSE;
|
||||
|
||||
clapper_cache_store_int (bytes, iface_id);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
clapper_cache_store_pspec (GByteArray *bytes, GParamSpec *pspec)
|
||||
{
|
||||
GParamFlags flags;
|
||||
const gboolean is_enum = G_IS_PARAM_SPEC_ENUM (pspec);
|
||||
const gboolean is_flags = (!is_enum && G_IS_PARAM_SPEC_FLAGS (pspec));
|
||||
|
||||
if (is_enum) {
|
||||
GType enum_type = G_TYPE_ENUM;
|
||||
g_byte_array_append (bytes, (const guint8 *) &enum_type, sizeof (GType));
|
||||
} else if (is_flags) {
|
||||
GType flags_type = G_TYPE_FLAGS;
|
||||
g_byte_array_append (bytes, (const guint8 *) &flags_type, sizeof (GType));
|
||||
} else {
|
||||
g_byte_array_append (bytes, (const guint8 *) &pspec->value_type, sizeof (GType));
|
||||
}
|
||||
|
||||
clapper_cache_store_string (bytes, g_param_spec_get_name (pspec));
|
||||
clapper_cache_store_string (bytes, g_param_spec_get_nick (pspec));
|
||||
clapper_cache_store_string (bytes, g_param_spec_get_blurb (pspec));
|
||||
|
||||
flags = pspec->flags;
|
||||
flags &= ~G_PARAM_STATIC_STRINGS; // Data read from cache is never static
|
||||
g_byte_array_append (bytes, (const guint8 *) &flags, sizeof (GParamFlags));
|
||||
|
||||
switch (pspec->value_type) {
|
||||
case G_TYPE_BOOLEAN:{
|
||||
GParamSpecBoolean *p = (GParamSpecBoolean *) pspec;
|
||||
clapper_cache_store_boolean (bytes, p->default_value);
|
||||
break;
|
||||
}
|
||||
case G_TYPE_INT:{
|
||||
GParamSpecInt *p = (GParamSpecInt *) pspec;
|
||||
clapper_cache_store_int (bytes, p->minimum);
|
||||
clapper_cache_store_int (bytes, p->maximum);
|
||||
clapper_cache_store_int (bytes, p->default_value);
|
||||
break;
|
||||
}
|
||||
case G_TYPE_UINT:{
|
||||
GParamSpecUInt *p = (GParamSpecUInt *) pspec;
|
||||
clapper_cache_store_uint (bytes, p->minimum);
|
||||
clapper_cache_store_uint (bytes, p->maximum);
|
||||
clapper_cache_store_uint (bytes, p->default_value);
|
||||
break;
|
||||
}
|
||||
case G_TYPE_DOUBLE:{
|
||||
GParamSpecDouble *p = (GParamSpecDouble *) pspec;
|
||||
clapper_cache_store_double (bytes, p->minimum);
|
||||
clapper_cache_store_double (bytes, p->maximum);
|
||||
clapper_cache_store_double (bytes, p->default_value);
|
||||
break;
|
||||
}
|
||||
case G_TYPE_STRING:{
|
||||
GParamSpecString *p = (GParamSpecString *) pspec;
|
||||
clapper_cache_store_string (bytes, p->default_value);
|
||||
break;
|
||||
}
|
||||
default:{
|
||||
if (is_enum) {
|
||||
GParamSpecEnum *p = (GParamSpecEnum *) pspec;
|
||||
clapper_cache_store_enum (bytes, pspec->value_type);
|
||||
clapper_cache_store_int (bytes, p->default_value);
|
||||
break;
|
||||
} else if (is_flags) {
|
||||
GParamSpecFlags *p = (GParamSpecFlags *) pspec;
|
||||
clapper_cache_store_flags (bytes, pspec->value_type);
|
||||
clapper_cache_store_uint (bytes, p->default_value);
|
||||
break;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
clapper_cache_write (const gchar *filename, GByteArray *bytes, GError **error)
|
||||
{
|
||||
gchar *dirname = g_path_get_dirname (filename);
|
||||
gboolean has_dir;
|
||||
|
||||
has_dir = (g_mkdir_with_parents (dirname, 0755) == 0);
|
||||
g_free (dirname);
|
||||
|
||||
if (!has_dir) {
|
||||
g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
|
||||
"Could not create directory to store cache content");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Using "g_file_set_contents" to replace file atomically */
|
||||
return g_file_set_contents (filename, (const gchar *) bytes->data, bytes->len, error);
|
||||
}
|
@@ -1,44 +0,0 @@
|
||||
/* Clapper Playback Library
|
||||
* Copyright (C) 2025 Rafał Dzięgiel <rafostar.github@gmail.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, see
|
||||
* <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <glib.h>
|
||||
#include <glib-object.h>
|
||||
|
||||
#include "clapper-enhancer-proxy-list.h"
|
||||
#include "clapper-enhancer-proxy.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
ClapperEnhancerProxyList * clapper_enhancer_proxy_list_new_named (const gchar *name);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
void clapper_enhancer_proxy_list_take_proxy (ClapperEnhancerProxyList *list, ClapperEnhancerProxy *proxy);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
void clapper_enhancer_proxy_list_fill_from_global_proxies (ClapperEnhancerProxyList *list);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
void clapper_enhancer_proxy_list_sort (ClapperEnhancerProxyList *list);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
gboolean clapper_enhancer_proxy_list_has_proxy_with_interface (ClapperEnhancerProxyList *list, GType iface_type);
|
||||
|
||||
G_END_DECLS
|
@@ -1,351 +0,0 @@
|
||||
/* Clapper Playback Library
|
||||
* Copyright (C) 2025 Rafał Dzięgiel <rafostar.github@gmail.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, see
|
||||
* <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* ClapperEnhancerProxyList:
|
||||
*
|
||||
* A list of enhancer proxies.
|
||||
*
|
||||
* Since: 0.10
|
||||
*/
|
||||
|
||||
#include <gio/gio.h>
|
||||
|
||||
#include "clapper-basic-functions.h"
|
||||
#include "clapper-enhancer-proxy-list-private.h"
|
||||
#include "clapper-enhancer-proxy-private.h"
|
||||
|
||||
#define GST_CAT_DEFAULT clapper_enhancer_proxy_list_debug
|
||||
GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);
|
||||
|
||||
struct _ClapperEnhancerProxyList
|
||||
{
|
||||
GstObject parent;
|
||||
|
||||
GPtrArray *proxies;
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
PROP_0,
|
||||
PROP_N_PROXIES,
|
||||
PROP_LAST
|
||||
};
|
||||
|
||||
static void clapper_enhancer_proxy_list_model_iface_init (GListModelInterface *iface);
|
||||
|
||||
#define parent_class clapper_enhancer_proxy_list_parent_class
|
||||
G_DEFINE_TYPE_WITH_CODE (ClapperEnhancerProxyList, clapper_enhancer_proxy_list, GST_TYPE_OBJECT,
|
||||
G_IMPLEMENT_INTERFACE (G_TYPE_LIST_MODEL, clapper_enhancer_proxy_list_model_iface_init));
|
||||
|
||||
static GParamSpec *param_specs[PROP_LAST] = { NULL, };
|
||||
|
||||
static GType
|
||||
clapper_enhancer_proxy_list_model_get_item_type (GListModel *model)
|
||||
{
|
||||
return CLAPPER_TYPE_ENHANCER_PROXY;
|
||||
}
|
||||
|
||||
static guint
|
||||
clapper_enhancer_proxy_list_model_get_n_items (GListModel *model)
|
||||
{
|
||||
return CLAPPER_ENHANCER_PROXY_LIST_CAST (model)->proxies->len;
|
||||
}
|
||||
|
||||
static gpointer
|
||||
clapper_enhancer_proxy_list_model_get_item (GListModel *model, guint index)
|
||||
{
|
||||
ClapperEnhancerProxyList *self = CLAPPER_ENHANCER_PROXY_LIST_CAST (model);
|
||||
ClapperEnhancerProxy *proxy = NULL;
|
||||
|
||||
if (G_LIKELY (index < self->proxies->len))
|
||||
proxy = gst_object_ref (g_ptr_array_index (self->proxies, index));
|
||||
|
||||
return proxy;
|
||||
}
|
||||
|
||||
static void
|
||||
clapper_enhancer_proxy_list_model_iface_init (GListModelInterface *iface)
|
||||
{
|
||||
iface->get_item_type = clapper_enhancer_proxy_list_model_get_item_type;
|
||||
iface->get_n_items = clapper_enhancer_proxy_list_model_get_n_items;
|
||||
iface->get_item = clapper_enhancer_proxy_list_model_get_item;
|
||||
}
|
||||
|
||||
/*
|
||||
* clapper_enhancer_proxy_list_new_named:
|
||||
* @name: (nullable): name of the #GstObject
|
||||
*
|
||||
* Returns: (transfer full): a new #ClapperEnhancerProxyList instance
|
||||
*/
|
||||
ClapperEnhancerProxyList *
|
||||
clapper_enhancer_proxy_list_new_named (const gchar *name)
|
||||
{
|
||||
ClapperEnhancerProxyList *list;
|
||||
|
||||
list = g_object_new (CLAPPER_TYPE_ENHANCER_PROXY_LIST,
|
||||
"name", name, NULL);
|
||||
gst_object_ref_sink (list);
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
void
|
||||
clapper_enhancer_proxy_list_take_proxy (ClapperEnhancerProxyList *self, ClapperEnhancerProxy *proxy)
|
||||
{
|
||||
g_ptr_array_add (self->proxies, proxy);
|
||||
gst_object_set_parent (GST_OBJECT_CAST (proxy), GST_OBJECT_CAST (self));
|
||||
}
|
||||
|
||||
/*
|
||||
* clapper_enhancer_proxy_list_fill_from_global_proxies:
|
||||
*
|
||||
* Fill list with unconfigured proxies from global proxies list.
|
||||
*/
|
||||
void
|
||||
clapper_enhancer_proxy_list_fill_from_global_proxies (ClapperEnhancerProxyList *self)
|
||||
{
|
||||
ClapperEnhancerProxyList *global_list = clapper_get_global_enhancer_proxies ();
|
||||
static guint _list_id = 0;
|
||||
guint i;
|
||||
|
||||
for (i = 0; i < global_list->proxies->len; ++i) {
|
||||
ClapperEnhancerProxy *proxy, *proxy_copy;
|
||||
gchar obj_name[64];
|
||||
|
||||
proxy = clapper_enhancer_proxy_list_peek_proxy (global_list, i);
|
||||
|
||||
/* Name newly created proxy, very useful for debugging. Keep index per
|
||||
* list, so it will be the same as the player that proxy belongs to. */
|
||||
g_snprintf (obj_name, sizeof (obj_name), "%s-proxy%u",
|
||||
clapper_enhancer_proxy_get_friendly_name (proxy), _list_id);
|
||||
proxy_copy = clapper_enhancer_proxy_copy (proxy, obj_name);
|
||||
|
||||
clapper_enhancer_proxy_list_take_proxy (self, proxy_copy);
|
||||
}
|
||||
_list_id++;
|
||||
}
|
||||
|
||||
static gint
|
||||
_sort_values_by_name (ClapperEnhancerProxy *proxy_a, ClapperEnhancerProxy *proxy_b)
|
||||
{
|
||||
return g_ascii_strcasecmp (
|
||||
clapper_enhancer_proxy_get_friendly_name (proxy_a),
|
||||
clapper_enhancer_proxy_get_friendly_name (proxy_b));
|
||||
}
|
||||
|
||||
/*
|
||||
* clapper_enhancer_proxy_list_sort:
|
||||
*
|
||||
* Sort all list elements by enhancer friendly name.
|
||||
*/
|
||||
void
|
||||
clapper_enhancer_proxy_list_sort (ClapperEnhancerProxyList *self)
|
||||
{
|
||||
g_ptr_array_sort_values (self->proxies, (GCompareFunc) _sort_values_by_name);
|
||||
}
|
||||
|
||||
/*
|
||||
* clapper_enhancer_proxy_list_has_proxy_with_interface:
|
||||
* @iface_type: an interface #GType
|
||||
*
|
||||
* Check if any enhancer implementing given interface type is available.
|
||||
*
|
||||
* Returns: whether any enhancer proxy was found.
|
||||
*/
|
||||
gboolean
|
||||
clapper_enhancer_proxy_list_has_proxy_with_interface (ClapperEnhancerProxyList *self, GType iface_type)
|
||||
{
|
||||
guint i;
|
||||
|
||||
for (i = 0; i < self->proxies->len; ++i) {
|
||||
ClapperEnhancerProxy *proxy = clapper_enhancer_proxy_list_peek_proxy (self, i);
|
||||
|
||||
if (clapper_enhancer_proxy_target_has_interface (proxy, iface_type))
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* clapper_enhancer_proxy_list_get_proxy:
|
||||
* @list: a #ClapperEnhancerProxyList
|
||||
* @index: an enhancer proxy index
|
||||
*
|
||||
* Get the #ClapperEnhancerProxy at index.
|
||||
*
|
||||
* This behaves the same as [method@Gio.ListModel.get_item], and is here
|
||||
* for code uniformity and convenience to avoid type casting by user.
|
||||
*
|
||||
* Returns: (transfer full) (nullable): The #ClapperEnhancerProxy at @index.
|
||||
*
|
||||
* Since: 0.10
|
||||
*/
|
||||
ClapperEnhancerProxy *
|
||||
clapper_enhancer_proxy_list_get_proxy (ClapperEnhancerProxyList *self, guint index)
|
||||
{
|
||||
g_return_val_if_fail (CLAPPER_IS_ENHANCER_PROXY_LIST (self), NULL);
|
||||
|
||||
return g_list_model_get_item (G_LIST_MODEL (self), index);
|
||||
}
|
||||
|
||||
/**
|
||||
* clapper_enhancer_proxy_list_peek_proxy: (skip)
|
||||
* @list: a #ClapperEnhancerProxyList
|
||||
* @index: an enhancer proxy index
|
||||
*
|
||||
* Get the #ClapperEnhancerProxy at index.
|
||||
*
|
||||
* Similar to [method@Clapper.EnhancerProxyList.get_proxy], but does not take
|
||||
* a new reference on proxy.
|
||||
*
|
||||
* Proxies in a list are only removed when a [class@Clapper.Player] instance
|
||||
* they originate from is destroyed, so do not use returned object afterwards
|
||||
* unless you take an additional reference on it.
|
||||
*
|
||||
* Returns: (transfer none) (nullable): The #ClapperEnhancerProxy at @index.
|
||||
*
|
||||
* Since: 0.10
|
||||
*/
|
||||
ClapperEnhancerProxy *
|
||||
clapper_enhancer_proxy_list_peek_proxy (ClapperEnhancerProxyList *self, guint index)
|
||||
{
|
||||
g_return_val_if_fail (CLAPPER_IS_ENHANCER_PROXY_LIST (self), NULL);
|
||||
|
||||
return g_ptr_array_index (self->proxies, index);
|
||||
}
|
||||
|
||||
/**
|
||||
* clapper_enhancer_proxy_list_get_proxy_by_module:
|
||||
* @list: a #ClapperEnhancerProxyList
|
||||
* @module_name: an enhancer module name
|
||||
*
|
||||
* Get the #ClapperEnhancerProxy by module name as defined in its plugin file.
|
||||
*
|
||||
* A convenience function to find a #ClapperEnhancerProxy by its unique
|
||||
* module name in the list.
|
||||
*
|
||||
* Returns: (transfer full) (nullable): The #ClapperEnhancerProxy with requested module name.
|
||||
*
|
||||
* Since: 0.10
|
||||
*/
|
||||
ClapperEnhancerProxy *
|
||||
clapper_enhancer_proxy_list_get_proxy_by_module (ClapperEnhancerProxyList *self, const gchar *module_name)
|
||||
{
|
||||
guint i;
|
||||
|
||||
g_return_val_if_fail (CLAPPER_IS_ENHANCER_PROXY_LIST (self), NULL);
|
||||
g_return_val_if_fail (module_name != NULL, NULL);
|
||||
|
||||
for (i = 0; i < self->proxies->len; ++i) {
|
||||
ClapperEnhancerProxy *proxy = g_ptr_array_index (self->proxies, i);
|
||||
|
||||
if (strcmp (clapper_enhancer_proxy_get_module_name (proxy), module_name) == 0)
|
||||
return gst_object_ref (proxy);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* clapper_enhancer_proxy_list_get_n_proxies:
|
||||
* @list: a #ClapperEnhancerProxyList
|
||||
*
|
||||
* Get the number of proxies in #ClapperEnhancerProxyList.
|
||||
*
|
||||
* This behaves the same as [method@Gio.ListModel.get_n_items], and is here
|
||||
* for code uniformity and convenience to avoid type casting by user.
|
||||
*
|
||||
* Returns: The number of proxies in #ClapperEnhancerProxyList.
|
||||
*
|
||||
* Since: 0.10
|
||||
*/
|
||||
guint
|
||||
clapper_enhancer_proxy_list_get_n_proxies (ClapperEnhancerProxyList *self)
|
||||
{
|
||||
g_return_val_if_fail (CLAPPER_IS_ENHANCER_PROXY_LIST (self), 0);
|
||||
|
||||
return g_list_model_get_n_items (G_LIST_MODEL (self));
|
||||
}
|
||||
|
||||
static void
|
||||
_proxy_remove_func (ClapperEnhancerProxy *proxy)
|
||||
{
|
||||
gst_object_unparent (GST_OBJECT_CAST (proxy));
|
||||
gst_object_unref (proxy);
|
||||
}
|
||||
|
||||
static void
|
||||
clapper_enhancer_proxy_list_init (ClapperEnhancerProxyList *self)
|
||||
{
|
||||
self->proxies = g_ptr_array_new_with_free_func ((GDestroyNotify) _proxy_remove_func);
|
||||
}
|
||||
|
||||
static void
|
||||
clapper_enhancer_proxy_list_finalize (GObject *object)
|
||||
{
|
||||
ClapperEnhancerProxyList *self = CLAPPER_ENHANCER_PROXY_LIST_CAST (object);
|
||||
|
||||
GST_TRACE_OBJECT (self, "Finalize");
|
||||
|
||||
g_ptr_array_unref (self->proxies);
|
||||
|
||||
G_OBJECT_CLASS (parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
clapper_enhancer_proxy_list_get_property (GObject *object, guint prop_id,
|
||||
GValue *value, GParamSpec *pspec)
|
||||
{
|
||||
ClapperEnhancerProxyList *self = CLAPPER_ENHANCER_PROXY_LIST_CAST (object);
|
||||
|
||||
switch (prop_id) {
|
||||
case PROP_N_PROXIES:
|
||||
g_value_set_uint (value, clapper_enhancer_proxy_list_get_n_proxies (self));
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
clapper_enhancer_proxy_list_class_init (ClapperEnhancerProxyListClass *klass)
|
||||
{
|
||||
GObjectClass *gobject_class = (GObjectClass *) klass;
|
||||
|
||||
GST_DEBUG_CATEGORY_INIT (GST_CAT_DEFAULT, "clapperenhancerproxylist", 0,
|
||||
"Clapper Enhancer Proxy List");
|
||||
|
||||
gobject_class->get_property = clapper_enhancer_proxy_list_get_property;
|
||||
gobject_class->finalize = clapper_enhancer_proxy_list_finalize;
|
||||
|
||||
/**
|
||||
* ClapperEnhancerProxyList:n-proxies:
|
||||
*
|
||||
* Number of proxies in the list.
|
||||
*
|
||||
* Since: 0.10
|
||||
*/
|
||||
param_specs[PROP_N_PROXIES] = g_param_spec_uint ("n-proxies",
|
||||
NULL, NULL, 0, G_MAXUINT, 0,
|
||||
G_PARAM_READABLE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
|
||||
|
||||
g_object_class_install_properties (gobject_class, PROP_LAST, param_specs);
|
||||
}
|
@@ -1,52 +0,0 @@
|
||||
/* Clapper Playback Library
|
||||
* Copyright (C) 2025 Rafał Dzięgiel <rafostar.github@gmail.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, see
|
||||
* <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#if !defined(__CLAPPER_INSIDE__) && !defined(CLAPPER_COMPILATION)
|
||||
#error "Only <clapper/clapper.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#include <glib.h>
|
||||
#include <glib-object.h>
|
||||
#include <gst/gst.h>
|
||||
|
||||
#include <clapper/clapper-visibility.h>
|
||||
#include <clapper/clapper-enhancer-proxy.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define CLAPPER_TYPE_ENHANCER_PROXY_LIST (clapper_enhancer_proxy_list_get_type())
|
||||
#define CLAPPER_ENHANCER_PROXY_LIST_CAST(obj) ((ClapperEnhancerProxyList *)(obj))
|
||||
|
||||
CLAPPER_API
|
||||
G_DECLARE_FINAL_TYPE (ClapperEnhancerProxyList, clapper_enhancer_proxy_list, CLAPPER, ENHANCER_PROXY_LIST, GstObject)
|
||||
|
||||
CLAPPER_API
|
||||
ClapperEnhancerProxy * clapper_enhancer_proxy_list_get_proxy (ClapperEnhancerProxyList *list, guint index);
|
||||
|
||||
CLAPPER_API
|
||||
ClapperEnhancerProxy * clapper_enhancer_proxy_list_peek_proxy (ClapperEnhancerProxyList *list, guint index);
|
||||
|
||||
CLAPPER_API
|
||||
ClapperEnhancerProxy * clapper_enhancer_proxy_list_get_proxy_by_module (ClapperEnhancerProxyList *list, const gchar *module_name);
|
||||
|
||||
CLAPPER_API
|
||||
guint clapper_enhancer_proxy_list_get_n_proxies (ClapperEnhancerProxyList *list);
|
||||
|
||||
G_END_DECLS
|
@@ -1,56 +0,0 @@
|
||||
/* Clapper Playback Library
|
||||
* Copyright (C) 2025 Rafał Dzięgiel <rafostar.github@gmail.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, see
|
||||
* <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <glib.h>
|
||||
#include <glib-object.h>
|
||||
#include <gst/gst.h>
|
||||
|
||||
#include "clapper-enhancer-proxy.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
ClapperEnhancerProxy * clapper_enhancer_proxy_new_global_take (GObject *peas_info); // Using parent type for building without libpeas
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
ClapperEnhancerProxy * clapper_enhancer_proxy_copy (ClapperEnhancerProxy *src_proxy, const gchar *copy_name);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
gboolean clapper_enhancer_proxy_fill_from_cache (ClapperEnhancerProxy *proxy);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
gboolean clapper_enhancer_proxy_fill_from_instance (ClapperEnhancerProxy *proxy, GObject *enhancer);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
void clapper_enhancer_proxy_export_to_cache (ClapperEnhancerProxy *proxy);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
GObject * clapper_enhancer_proxy_get_peas_info (ClapperEnhancerProxy *proxy);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
gboolean clapper_enhancer_proxy_has_locally_set (ClapperEnhancerProxy *proxy, const gchar *property_name);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
GstStructure * clapper_enhancer_proxy_make_current_config (ClapperEnhancerProxy *proxy);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
void clapper_enhancer_proxy_apply_config_to_enhancer (ClapperEnhancerProxy *proxy, const GstStructure *config, GObject *enhancer);
|
||||
|
||||
G_END_DECLS
|
File diff suppressed because it is too large
Load Diff
@@ -1,85 +0,0 @@
|
||||
/* Clapper Playback Library
|
||||
* Copyright (C) 2025 Rafał Dzięgiel <rafostar.github@gmail.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, see
|
||||
* <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#if !defined(__CLAPPER_INSIDE__) && !defined(CLAPPER_COMPILATION)
|
||||
#error "Only <clapper/clapper.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#include <glib.h>
|
||||
#include <glib-object.h>
|
||||
#include <gio/gio.h>
|
||||
#include <gst/gst.h>
|
||||
|
||||
#include <clapper/clapper-visibility.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define CLAPPER_TYPE_ENHANCER_PROXY (clapper_enhancer_proxy_get_type())
|
||||
#define CLAPPER_ENHANCER_PROXY_CAST(obj) ((ClapperEnhancerProxy *)(obj))
|
||||
|
||||
CLAPPER_API
|
||||
G_DECLARE_FINAL_TYPE (ClapperEnhancerProxy, clapper_enhancer_proxy, CLAPPER, ENHANCER_PROXY, GstObject)
|
||||
|
||||
CLAPPER_API
|
||||
const gchar * clapper_enhancer_proxy_get_friendly_name (ClapperEnhancerProxy *proxy);
|
||||
|
||||
CLAPPER_API
|
||||
const gchar * clapper_enhancer_proxy_get_module_name (ClapperEnhancerProxy *proxy);
|
||||
|
||||
CLAPPER_API
|
||||
const gchar * clapper_enhancer_proxy_get_module_dir (ClapperEnhancerProxy *proxy);
|
||||
|
||||
CLAPPER_API
|
||||
const gchar * clapper_enhancer_proxy_get_description (ClapperEnhancerProxy *proxy);
|
||||
|
||||
CLAPPER_API
|
||||
const gchar * clapper_enhancer_proxy_get_version (ClapperEnhancerProxy *proxy);
|
||||
|
||||
CLAPPER_API
|
||||
const gchar * clapper_enhancer_proxy_get_extra_data (ClapperEnhancerProxy *proxy, const gchar *key);
|
||||
|
||||
CLAPPER_API
|
||||
gboolean clapper_enhancer_proxy_extra_data_lists_value (ClapperEnhancerProxy *proxy, const gchar *key, const gchar *value);
|
||||
|
||||
CLAPPER_API
|
||||
GType * clapper_enhancer_proxy_get_target_interfaces (ClapperEnhancerProxy *proxy, guint *n_interfaces);
|
||||
|
||||
CLAPPER_API
|
||||
gboolean clapper_enhancer_proxy_target_has_interface (ClapperEnhancerProxy *proxy, GType iface_type);
|
||||
|
||||
CLAPPER_API
|
||||
GParamSpec ** clapper_enhancer_proxy_get_target_properties (ClapperEnhancerProxy *proxy, guint *n_properties);
|
||||
|
||||
CLAPPER_API
|
||||
GSettings * clapper_enhancer_proxy_get_settings (ClapperEnhancerProxy *proxy);
|
||||
|
||||
CLAPPER_API
|
||||
void clapper_enhancer_proxy_set_locally (ClapperEnhancerProxy *proxy, const gchar *first_property_name, ...) G_GNUC_NULL_TERMINATED;
|
||||
|
||||
CLAPPER_API
|
||||
void clapper_enhancer_proxy_set_locally_with_table (ClapperEnhancerProxy *proxy, GHashTable *table);
|
||||
|
||||
CLAPPER_API
|
||||
void clapper_enhancer_proxy_set_target_creation_allowed (ClapperEnhancerProxy *proxy, gboolean allowed);
|
||||
|
||||
CLAPPER_API
|
||||
gboolean clapper_enhancer_proxy_get_target_creation_allowed (ClapperEnhancerProxy *proxy);
|
||||
|
||||
G_END_DECLS
|
@@ -12,8 +12,9 @@
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, see
|
||||
* <https://www.gnu.org/licenses/>.
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
@@ -21,15 +22,21 @@
|
||||
#include <glib.h>
|
||||
#include <glib-object.h>
|
||||
|
||||
#include "clapper-enhancer-proxy-list.h"
|
||||
#include "clapper-enhancer-proxy.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
void clapper_enhancers_loader_initialize (ClapperEnhancerProxyList *proxies);
|
||||
void clapper_enhancers_loader_initialize (void);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
GObject * clapper_enhancers_loader_create_enhancer (ClapperEnhancerProxy *proxy, GType iface_type);
|
||||
gboolean clapper_enhancers_loader_has_enhancers (GType iface_type);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
gchar ** clapper_enhancers_loader_get_schemes (GType iface_type);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
gboolean clapper_enhancers_loader_check (GType iface_type, const gchar *scheme, const gchar *host, const gchar **name);
|
||||
|
||||
G_GNUC_INTERNAL
|
||||
GObject * clapper_enhancers_loader_create_enhancer_for_uri (GType iface_type, GUri *uri);
|
||||
|
||||
G_END_DECLS
|
||||
|
@@ -12,8 +12,9 @@
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, see
|
||||
* <https://www.gnu.org/licenses/>.
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
@@ -27,13 +28,11 @@ static HMODULE _enhancers_dll_handle = NULL;
|
||||
#endif
|
||||
|
||||
#include "clapper-enhancers-loader-private.h"
|
||||
#include "clapper-enhancer-proxy-list-private.h"
|
||||
#include "clapper-enhancer-proxy-private.h"
|
||||
|
||||
// Supported interfaces
|
||||
#include "clapper-extractable.h"
|
||||
#include "clapper-playlistable.h"
|
||||
#include "clapper-reactable.h"
|
||||
#define ENHANCER_INTERFACES "X-Interfaces"
|
||||
#define ENHANCER_SCHEMES "X-Schemes"
|
||||
#define ENHANCER_HOSTS "X-Hosts"
|
||||
#define ENHANCER_IFACE_NAME_FROM_TYPE(type) (g_type_name (type) + 7) // strip "Clapper" prefix
|
||||
|
||||
#define GST_CAT_DEFAULT clapper_enhancers_loader_debug
|
||||
GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);
|
||||
@@ -53,39 +52,16 @@ _import_enhancers (const gchar *enhancers_path)
|
||||
g_strfreev (dir_paths);
|
||||
}
|
||||
|
||||
static GObject *
|
||||
_force_create_enhancer (ClapperEnhancerProxy *proxy, GType iface_type)
|
||||
{
|
||||
GObject *enhancer = NULL;
|
||||
PeasPluginInfo *info = (PeasPluginInfo *) clapper_enhancer_proxy_get_peas_info (proxy);
|
||||
|
||||
g_mutex_lock (&load_lock);
|
||||
|
||||
if (!peas_plugin_info_is_loaded (info) && !peas_engine_load_plugin (_engine, info)) {
|
||||
GST_ERROR ("Could not load enhancer: %s", peas_plugin_info_get_module_name (info));
|
||||
} else if (!peas_engine_provides_extension (_engine, info, iface_type)) {
|
||||
GST_LOG ("No \"%s\" enhancer in module: %s", g_type_name (iface_type),
|
||||
peas_plugin_info_get_module_name (info));
|
||||
} else {
|
||||
enhancer = peas_engine_create_extension (_engine, info, iface_type, NULL);
|
||||
}
|
||||
|
||||
g_mutex_unlock (&load_lock);
|
||||
|
||||
return enhancer;
|
||||
}
|
||||
|
||||
/*
|
||||
* clapper_enhancers_loader_initialize:
|
||||
*
|
||||
* Initializes #PeasEngine with directories that store enhancers.
|
||||
*/
|
||||
void
|
||||
clapper_enhancers_loader_initialize (ClapperEnhancerProxyList *proxies)
|
||||
clapper_enhancers_loader_initialize (void)
|
||||
{
|
||||
const gchar *enhancers_path;
|
||||
gchar *custom_path = NULL;
|
||||
guint i, n_items;
|
||||
|
||||
GST_DEBUG_CATEGORY_INIT (GST_CAT_DEFAULT, "clapperenhancersloader", 0,
|
||||
"Clapper Enhancer Loader");
|
||||
@@ -98,8 +74,9 @@ clapper_enhancers_loader_initialize (ClapperEnhancerProxyList *proxies)
|
||||
|
||||
win_base_dir = g_win32_get_package_installation_directory_of_module (
|
||||
_enhancers_dll_handle);
|
||||
/* FIXME: Avoid hardcoded major version */
|
||||
custom_path = g_build_filename (win_base_dir,
|
||||
"lib", CLAPPER_API_NAME, "enhancers", NULL);
|
||||
"lib", "clapper-0.0", "enhancers", NULL);
|
||||
enhancers_path = custom_path; // assign temporarily
|
||||
|
||||
g_free (win_base_dir);
|
||||
@@ -127,72 +104,321 @@ clapper_enhancers_loader_initialize (ClapperEnhancerProxyList *proxies)
|
||||
_import_enhancers (enhancers_path);
|
||||
}
|
||||
|
||||
n_items = g_list_model_get_n_items ((GListModel *) _engine);
|
||||
for (i = 0; i < n_items; ++i) {
|
||||
PeasPluginInfo *info = (PeasPluginInfo *) g_list_model_get_item ((GListModel *) _engine, i);
|
||||
ClapperEnhancerProxy *proxy;
|
||||
gboolean filled;
|
||||
if (gst_debug_category_get_threshold (GST_CAT_DEFAULT) >= GST_LEVEL_INFO) {
|
||||
GListModel *list = (GListModel *) _engine;
|
||||
guint i, n_items = g_list_model_get_n_items (list);
|
||||
|
||||
/* Clapper supports only 1 proxy per plugin. Each plugin can
|
||||
* ship 1 class, but it can implement more than 1 interface. */
|
||||
proxy = clapper_enhancer_proxy_new_global_take ((GObject *) info);
|
||||
|
||||
/* Try to fill missing data from cache (fast).
|
||||
* Otherwise make an instance and fill missing data from it (slow). */
|
||||
if (!(filled = clapper_enhancer_proxy_fill_from_cache (proxy))) {
|
||||
GObject *enhancer;
|
||||
const GType main_types[] = { CLAPPER_TYPE_EXTRACTABLE, CLAPPER_TYPE_PLAYLISTABLE, CLAPPER_TYPE_REACTABLE };
|
||||
guint j;
|
||||
|
||||
/* We cannot ask libpeas for "any" of our main interfaces, so try each one until found */
|
||||
for (j = 0; j < G_N_ELEMENTS (main_types); ++j) {
|
||||
if ((enhancer = _force_create_enhancer (proxy, main_types[j]))) {
|
||||
filled = clapper_enhancer_proxy_fill_from_instance (proxy, enhancer);
|
||||
g_object_unref (enhancer);
|
||||
|
||||
clapper_enhancer_proxy_export_to_cache (proxy);
|
||||
break;
|
||||
}
|
||||
}
|
||||
for (i = 0; i < n_items; ++i) {
|
||||
PeasPluginInfo *info = (PeasPluginInfo *) g_list_model_get_item (list, i);
|
||||
GST_INFO ("Found enhancer: %s (%s)", peas_plugin_info_get_name (info),
|
||||
peas_plugin_info_get_external_data (info, ENHANCER_INTERFACES));
|
||||
g_object_unref (info);
|
||||
}
|
||||
|
||||
if (G_LIKELY (filled)) {
|
||||
GST_INFO ("Found enhancer: \"%s\" (%s)",
|
||||
clapper_enhancer_proxy_get_friendly_name (proxy),
|
||||
clapper_enhancer_proxy_get_module_name (proxy));
|
||||
clapper_enhancer_proxy_list_take_proxy (proxies, proxy);
|
||||
} else {
|
||||
GST_WARNING ("Enhancer init failed: \"%s\" (%s)",
|
||||
clapper_enhancer_proxy_get_friendly_name (proxy),
|
||||
clapper_enhancer_proxy_get_module_name (proxy));
|
||||
gst_object_unref (proxy);
|
||||
}
|
||||
GST_INFO ("Clapper enhancers initialized, found: %u", n_items);
|
||||
}
|
||||
|
||||
clapper_enhancer_proxy_list_sort (proxies);
|
||||
|
||||
GST_INFO ("Clapper enhancers initialized, found: %u",
|
||||
clapper_enhancer_proxy_list_get_n_proxies (proxies));
|
||||
|
||||
g_free (custom_path);
|
||||
}
|
||||
|
||||
static inline gboolean
|
||||
_is_name_listed (const gchar *name, const gchar *list_str)
|
||||
{
|
||||
gsize name_len = strlen (name);
|
||||
guint i = 0;
|
||||
|
||||
while (list_str[i] != '\0') {
|
||||
guint end = i;
|
||||
|
||||
while (list_str[end] != ';' && list_str[end] != '\0')
|
||||
++end;
|
||||
|
||||
/* Compare letters count until separator and prefix of whole string */
|
||||
if (end - i == name_len && g_str_has_prefix (list_str + i, name))
|
||||
return TRUE;
|
||||
|
||||
i = end;
|
||||
|
||||
/* Move to the next letter after ';' */
|
||||
if (list_str[i] != '\0')
|
||||
++i;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* clapper_enhancers_loader_create_enhancer:
|
||||
* @iface_type: a requested #GType
|
||||
* @info: a #PeasPluginInfo
|
||||
* clapper_enhancers_loader_get_info:
|
||||
* @iface_type: an interface #GType
|
||||
* @scheme: an URI scheme
|
||||
* @host: (nullable): an URI host
|
||||
*
|
||||
* Creates a new enhancer object using @info.
|
||||
* Returns: (transfer full) (nullable): available #PeasPluginInfo or %NULL.
|
||||
*/
|
||||
static PeasPluginInfo *
|
||||
clapper_enhancers_loader_get_info (GType iface_type, const gchar *scheme, const gchar *host)
|
||||
{
|
||||
GListModel *list = (GListModel *) _engine;
|
||||
PeasPluginInfo *found_info = NULL;
|
||||
guint i, n_plugins = g_list_model_get_n_items (list);
|
||||
const gchar *iface_name;
|
||||
gboolean is_https;
|
||||
|
||||
if (n_plugins == 0) {
|
||||
GST_INFO ("No Clapper enhancers found");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
iface_name = ENHANCER_IFACE_NAME_FROM_TYPE (iface_type);
|
||||
|
||||
/* Strip common subdomains, so plugins do not
|
||||
* have to list all combinations */
|
||||
if (host) {
|
||||
if (g_str_has_prefix (host, "www."))
|
||||
host += 4;
|
||||
else if (g_str_has_prefix (host, "m."))
|
||||
host += 2;
|
||||
}
|
||||
|
||||
GST_INFO ("Enhancer check, iface: %s, scheme: %s, host: %s",
|
||||
iface_name, scheme, GST_STR_NULL (host));
|
||||
|
||||
is_https = (g_str_has_prefix (scheme, "http")
|
||||
&& (scheme[4] == '\0' || (scheme[4] == 's' && scheme[5] == '\0')));
|
||||
|
||||
if (!host && is_https)
|
||||
return NULL;
|
||||
|
||||
for (i = 0; i < n_plugins; ++i) {
|
||||
PeasPluginInfo *info = (PeasPluginInfo *) g_list_model_get_item (list, i);
|
||||
const gchar *iface_names, *schemes, *hosts;
|
||||
|
||||
if (!(iface_names = peas_plugin_info_get_external_data (info, ENHANCER_INTERFACES))) {
|
||||
GST_DEBUG ("Skipping enhancer without interfaces: %s", peas_plugin_info_get_name (info));
|
||||
g_object_unref (info);
|
||||
continue;
|
||||
}
|
||||
if (!_is_name_listed (iface_name, iface_names)) {
|
||||
g_object_unref (info);
|
||||
continue;
|
||||
}
|
||||
if (!(schemes = peas_plugin_info_get_external_data (info, ENHANCER_SCHEMES))) {
|
||||
GST_DEBUG ("Skipping enhancer without schemes: %s", peas_plugin_info_get_name (info));
|
||||
g_object_unref (info);
|
||||
continue;
|
||||
}
|
||||
if (!_is_name_listed (scheme, schemes)) {
|
||||
g_object_unref (info);
|
||||
continue;
|
||||
}
|
||||
if (is_https) {
|
||||
if (!(hosts = peas_plugin_info_get_external_data (info, ENHANCER_HOSTS))) {
|
||||
GST_DEBUG ("Skipping enhancer without hosts: %s", peas_plugin_info_get_name (info));
|
||||
g_object_unref (info);
|
||||
continue;
|
||||
}
|
||||
if (!_is_name_listed (host, hosts)) {
|
||||
g_object_unref (info);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
found_info = info;
|
||||
break;
|
||||
}
|
||||
|
||||
return found_info;
|
||||
}
|
||||
|
||||
/*
|
||||
* clapper_enhancers_loader_has_enhancers:
|
||||
* @iface_type: an interface #GType
|
||||
*
|
||||
* Check if any enhancer implementing given interface type is available.
|
||||
*
|
||||
* Returns: whether any valid enhancer was found.
|
||||
*/
|
||||
gboolean
|
||||
clapper_enhancers_loader_has_enhancers (GType iface_type)
|
||||
{
|
||||
GListModel *list = (GListModel *) _engine;
|
||||
const gchar *iface_name = ENHANCER_IFACE_NAME_FROM_TYPE (iface_type);
|
||||
guint i, n_plugins;
|
||||
|
||||
GST_DEBUG ("Checking for any enhancers of type: \"%s\"", iface_name);
|
||||
|
||||
n_plugins = g_list_model_get_n_items (list);
|
||||
|
||||
for (i = 0; i < n_plugins; ++i) {
|
||||
PeasPluginInfo *info = (PeasPluginInfo *) g_list_model_get_item (list, i);
|
||||
const gchar *iface_names;
|
||||
|
||||
if (!(iface_names = peas_plugin_info_get_external_data (info, ENHANCER_INTERFACES))) {
|
||||
g_object_unref (info);
|
||||
continue;
|
||||
}
|
||||
if (!_is_name_listed (iface_name, iface_names)) {
|
||||
g_object_unref (info);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Additional validation */
|
||||
if (!peas_plugin_info_get_external_data (info, ENHANCER_SCHEMES)
|
||||
|| !peas_plugin_info_get_external_data (info, ENHANCER_HOSTS)) {
|
||||
g_object_unref (info);
|
||||
continue;
|
||||
}
|
||||
|
||||
GST_DEBUG ("Found valid enhancers of type: \"%s\"", iface_name);
|
||||
g_object_unref (info);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
GST_DEBUG ("No available enhancers of type: \"%s\"", iface_name);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* clapper_enhancers_loader_get_schemes:
|
||||
* @iface_type: an interface #GType
|
||||
*
|
||||
* Get all supported schemes for a given interface type.
|
||||
* The returned array consists of unique strings (no duplicates).
|
||||
*
|
||||
* Returns: (transfer full): all supported schemes by enhancers of type.
|
||||
*/
|
||||
gchar **
|
||||
clapper_enhancers_loader_get_schemes (GType iface_type)
|
||||
{
|
||||
GListModel *list = (GListModel *) _engine;
|
||||
GSList *found_schemes = NULL, *fs;
|
||||
const gchar *iface_name = ENHANCER_IFACE_NAME_FROM_TYPE (iface_type);
|
||||
gchar **schemes_strv;
|
||||
guint i, n_plugins, n_schemes;
|
||||
|
||||
GST_DEBUG ("Checking supported URI schemes for \"%s\"", iface_name);
|
||||
|
||||
n_plugins = g_list_model_get_n_items (list);
|
||||
|
||||
for (i = 0; i < n_plugins; ++i) {
|
||||
PeasPluginInfo *info = (PeasPluginInfo *) g_list_model_get_item (list, i);
|
||||
const gchar *iface_names, *schemes;
|
||||
gchar **tmp_strv;
|
||||
gint j;
|
||||
|
||||
if (!(iface_names = peas_plugin_info_get_external_data (info, ENHANCER_INTERFACES))) {
|
||||
g_object_unref (info);
|
||||
continue;
|
||||
}
|
||||
if (!_is_name_listed (iface_name, iface_names)) {
|
||||
g_object_unref (info);
|
||||
continue;
|
||||
}
|
||||
if (!(schemes = peas_plugin_info_get_external_data (info, ENHANCER_SCHEMES))) {
|
||||
g_object_unref (info);
|
||||
continue;
|
||||
}
|
||||
|
||||
tmp_strv = g_strsplit (schemes, ";", 0);
|
||||
|
||||
for (j = 0; tmp_strv[j]; ++j) {
|
||||
const gchar *scheme = tmp_strv[j];
|
||||
|
||||
if (!found_schemes || !g_slist_find_custom (found_schemes,
|
||||
scheme, (GCompareFunc) strcmp)) {
|
||||
found_schemes = g_slist_append (found_schemes, g_strdup (scheme));
|
||||
GST_INFO ("Found supported URI scheme: %s", scheme);
|
||||
}
|
||||
}
|
||||
|
||||
g_strfreev (tmp_strv);
|
||||
g_object_unref (info);
|
||||
}
|
||||
|
||||
n_schemes = g_slist_length (found_schemes);
|
||||
schemes_strv = g_new0 (gchar *, n_schemes + 1);
|
||||
|
||||
fs = found_schemes;
|
||||
for (i = 0; i < n_schemes; ++i) {
|
||||
schemes_strv[i] = fs->data;
|
||||
fs = fs->next;
|
||||
}
|
||||
|
||||
GST_DEBUG ("Total found URI schemes: %u", n_schemes);
|
||||
|
||||
/* Since string pointers were taken,
|
||||
* free list without content */
|
||||
g_slist_free (found_schemes);
|
||||
|
||||
return schemes_strv;
|
||||
}
|
||||
|
||||
/*
|
||||
* clapper_enhancers_loader_check:
|
||||
* @iface_type: a requested #GType
|
||||
* @scheme: an URI scheme
|
||||
* @host: (nullable): an URI host
|
||||
* @name: (out) (optional) (transfer none): return location for found enhancer name
|
||||
*
|
||||
* Checks if any enhancer can handle @uri without initializing loader
|
||||
* or creating enhancer instance, thus this can be used freely from any thread.
|
||||
*
|
||||
* Returns: whether enhancer for given scheme and host is available.
|
||||
*/
|
||||
gboolean
|
||||
clapper_enhancers_loader_check (GType iface_type,
|
||||
const gchar *scheme, const gchar *host, const gchar **name)
|
||||
{
|
||||
PeasPluginInfo *info;
|
||||
|
||||
if ((info = clapper_enhancers_loader_get_info (iface_type, scheme, host))) {
|
||||
if (name)
|
||||
*name = peas_plugin_info_get_name (info);
|
||||
|
||||
g_object_unref (info);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* clapper_enhancers_loader_create_enhancer_for_uri:
|
||||
* @iface_type: a requested #GType
|
||||
* @uri: a #GUri
|
||||
*
|
||||
* Creates a new enhancer object for given URI.
|
||||
*
|
||||
* Enhancer should only be created and used within single thread.
|
||||
*
|
||||
* Returns: (transfer full) (nullable): a new enhancer instance.
|
||||
*/
|
||||
GObject *
|
||||
clapper_enhancers_loader_create_enhancer (ClapperEnhancerProxy *proxy, GType iface_type)
|
||||
clapper_enhancers_loader_create_enhancer_for_uri (GType iface_type, GUri *uri)
|
||||
{
|
||||
if (!clapper_enhancer_proxy_get_target_creation_allowed (proxy))
|
||||
return NULL;
|
||||
GObject *enhancer = NULL;
|
||||
PeasPluginInfo *info;
|
||||
const gchar *scheme = g_uri_get_scheme (uri);
|
||||
const gchar *host = g_uri_get_host (uri);
|
||||
|
||||
return _force_create_enhancer (proxy, iface_type);
|
||||
if ((info = clapper_enhancers_loader_get_info (iface_type, scheme, host))) {
|
||||
g_mutex_lock (&load_lock);
|
||||
|
||||
if (!peas_plugin_info_is_loaded (info) && !peas_engine_load_plugin (_engine, info)) {
|
||||
GST_ERROR ("Could not load enhancer: %s", peas_plugin_info_get_name (info));
|
||||
} else if (!peas_engine_provides_extension (_engine, info, iface_type)) {
|
||||
GST_ERROR ("No \"%s\" enhancer in plugin: %s", ENHANCER_IFACE_NAME_FROM_TYPE (iface_type),
|
||||
peas_plugin_info_get_name (info));
|
||||
} else {
|
||||
enhancer = peas_engine_create_extension (_engine, info, iface_type, NULL);
|
||||
}
|
||||
|
||||
g_mutex_unlock (&load_lock);
|
||||
g_object_unref (info);
|
||||
}
|
||||
|
||||
return enhancer;
|
||||
}
|
||||
|
@@ -12,8 +12,9 @@
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, see
|
||||
* <https://www.gnu.org/licenses/>.
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
@@ -12,8 +12,9 @@
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, see
|
||||
* <https://www.gnu.org/licenses/>.
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
@@ -126,47 +127,4 @@ typedef enum
|
||||
CLAPPER_DISCOVERER_DISCOVERY_NONCURRENT,
|
||||
} ClapperDiscovererDiscoveryMode;
|
||||
|
||||
/* NOTE: GStreamer uses param flags 8-16, so start with 17. */
|
||||
/**
|
||||
* ClapperEnhancerParamFlags:
|
||||
* @CLAPPER_ENHANCER_PARAM_GLOBAL: Use this flag for enhancer properties that should have global access scope.
|
||||
* Such are meant for application `USER` to configure.
|
||||
* @CLAPPER_ENHANCER_PARAM_LOCAL: Use this flag for enhancer properties that should have local access scope.
|
||||
* Such are meant for `APPLICATION` to configure.
|
||||
* @CLAPPER_ENHANCER_PARAM_FILEPATH: Use this flag for enhancer properties that store string with a file path.
|
||||
* Applications can use this as a hint to show file selection instead of a text entry.
|
||||
* @CLAPPER_ENHANCER_PARAM_DIRPATH: Use this flag for enhancer properties that store string with a directory path.
|
||||
* Applications can use this as a hint to show directory selection instead of a text entry.
|
||||
*
|
||||
* Additional [flags@GObject.ParamFlags] to be set in enhancer plugins implementations.
|
||||
*
|
||||
* Since: 0.10
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
CLAPPER_ENHANCER_PARAM_GLOBAL = 1 << 17,
|
||||
CLAPPER_ENHANCER_PARAM_LOCAL = 1 << 18,
|
||||
CLAPPER_ENHANCER_PARAM_FILEPATH = 1 << 19,
|
||||
CLAPPER_ENHANCER_PARAM_DIRPATH = 1 << 20,
|
||||
} ClapperEnhancerParamFlags;
|
||||
|
||||
/**
|
||||
* ClapperReactableItemUpdatedFlags:
|
||||
* @CLAPPER_REACTABLE_ITEM_UPDATED_TITLE: Media item title was updated.
|
||||
* @CLAPPER_REACTABLE_ITEM_UPDATED_DURATION: Media item duration was updated.
|
||||
* @CLAPPER_REACTABLE_ITEM_UPDATED_TIMELINE: Media item timeline was updated.
|
||||
* @CLAPPER_REACTABLE_ITEM_UPDATED_TAGS: Media item tags were updated.
|
||||
*
|
||||
* Flags informing which properties were updated within [class@Clapper.MediaItem].
|
||||
*
|
||||
* Since: 0.10
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
CLAPPER_REACTABLE_ITEM_UPDATED_TITLE = 1 << 0,
|
||||
CLAPPER_REACTABLE_ITEM_UPDATED_DURATION = 1 << 1,
|
||||
CLAPPER_REACTABLE_ITEM_UPDATED_TIMELINE = 1 << 2,
|
||||
CLAPPER_REACTABLE_ITEM_UPDATED_TAGS = 1 << 3,
|
||||
} ClapperReactableItemUpdatedFlags;
|
||||
|
||||
G_END_DECLS
|
||||
|
@@ -12,8 +12,9 @@
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, see
|
||||
* <https://www.gnu.org/licenses/>.
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
@@ -12,8 +12,9 @@
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, see
|
||||
* <https://www.gnu.org/licenses/>.
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
/**
|
||||
|
@@ -12,8 +12,9 @@
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, see
|
||||
* <https://www.gnu.org/licenses/>.
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
@@ -12,8 +12,9 @@
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, see
|
||||
* <https://www.gnu.org/licenses/>.
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user