Dominique Leuenberger
7ae9183fc9
Scripted push of project GNOME:Next OBS-URL: https://build.opensuse.org/request/show/583493 OBS-URL: https://build.opensuse.org/package/show/GNOME:Factory/gtk4?expand=0&rev=30
424 lines
15 KiB
Diff
424 lines
15 KiB
Diff
From 2cbe094b919442471b54685a0fef0d6f83ce44b3 Mon Sep 17 00:00:00 2001
|
|
From: Emmanuele Bassi <ebassi@gnome.org>
|
|
Date: Thu, 1 Feb 2018 17:43:15 +0100
|
|
Subject: [PATCH] Allow binding GdkContentFormatsBuilder
|
|
|
|
GdkContentFormatsBuilder is currently not introspectable, as it does not
|
|
have a GType. We can turn it into a boxed type, but we need to implement
|
|
memory management for it.
|
|
|
|
The current gdk_content_formats_builder_free() function returns a newly
|
|
constructed value, so we cannot use it as a GBoxedFreeFunc; additionally
|
|
copying a GdkContentFormatsBuilder contents would make it a bit odd, as
|
|
you could get multiple identical GdkContentFormats out of the copies.
|
|
|
|
A simple approach is to model the GdkContentFormatsBuilder API to follow
|
|
the GBytes one: use reference counting for memory management, and have
|
|
a function to release a reference, return a GdkContentFormats, and reset
|
|
the GdkContentFormatsBuilder state.
|
|
|
|
For language bindings, we can provide a get_formats() function that
|
|
returns the GdkContentFormats instance and resets the builder instance,
|
|
leaving the reference count untouched.
|
|
|
|
For C convenience we can keep gdk_content_formats_builder_free(), and
|
|
make it a wrapper around gdk_content_formats_builder_get_formats(), with
|
|
the guarantee that it'll free the builder instance regardless of its
|
|
current reference count.
|
|
|
|
https://bugzilla.gnome.org/show_bug.cgi?id=793097
|
|
https://blogs.gnome.org/otte/2018/02/03/builders/
|
|
---
|
|
docs/reference/gdk/gdk4-sections.txt | 7 ++++++-
|
|
gdk/gdkclipboard.c | 2 +-
|
|
gdk/gdkcontentdeserializer.c | 4 ++--
|
|
gdk/gdkcontentformats.c | 115 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----------
|
|
gdk/gdkcontentformats.h | 15 +++++++++++++--
|
|
gdk/gdkcontentproviderimpl.c | 2 +-
|
|
gdk/gdkcontentserializer.c | 4 ++--
|
|
gdk/wayland/gdkprimary-wayland.c | 4 ++--
|
|
gdk/wayland/gdkselection-wayland.c | 2 +-
|
|
gdk/win32/gdkdnd-win32.c | 2 +-
|
|
gdk/x11/gdkclipboard-x11.c | 2 +-
|
|
gtk/gtkselection.c | 6 +++---
|
|
12 files changed, 138 insertions(+), 27 deletions(-)
|
|
|
|
diff --git a/docs/reference/gdk/gdk4-sections.txt b/docs/reference/gdk/gdk4-sections.txt
|
|
index d492279..cf58129 100644
|
|
--- a/docs/reference/gdk/gdk4-sections.txt
|
|
+++ b/docs/reference/gdk/gdk4-sections.txt
|
|
@@ -438,11 +438,16 @@ gdk_content_formats_union_deserialize_mime_types
|
|
<SUBSECTION>
|
|
GdkContentFormatsBuilder
|
|
gdk_content_formats_builder_new
|
|
-gdk_content_formats_builder_free
|
|
+gdk_content_formats_builder_free_to_formats
|
|
gdk_content_formats_builder_add_formats
|
|
gdk_content_formats_builder_add_gtype
|
|
gdk_content_formats_builder_add_mime_type
|
|
|
|
+<SUBSECTION>
|
|
+gdk_content_formats_builder_ref
|
|
+gdk_content_formats_builder_unref
|
|
+gdk_content_formats_builder_to_formats
|
|
+
|
|
<SUBSECTION Private>
|
|
GDK_TYPE_FILE_LIST
|
|
gdk_file_list_get_type
|
|
diff --git a/gdk/gdkclipboard.c b/gdk/gdkclipboard.c
|
|
index ee9d8e9..df82147 100644
|
|
--- a/gdk/gdkclipboard.c
|
|
+++ b/gdk/gdkclipboard.c
|
|
@@ -820,7 +820,7 @@ gdk_clipboard_read_value_internal (GdkClipboard *clipboard,
|
|
|
|
builder = gdk_content_formats_builder_new ();
|
|
gdk_content_formats_builder_add_gtype (builder, type);
|
|
- formats = gdk_content_formats_builder_free (builder);
|
|
+ formats = gdk_content_formats_builder_free_to_formats (builder);
|
|
formats = gdk_content_formats_union_deserialize_mime_types (formats);
|
|
|
|
gdk_clipboard_read_internal (clipboard,
|
|
diff --git a/gdk/gdkcontentdeserializer.c b/gdk/gdkcontentdeserializer.c
|
|
index c9df08d..b0df54c 100644
|
|
--- a/gdk/gdkcontentdeserializer.c
|
|
+++ b/gdk/gdkcontentdeserializer.c
|
|
@@ -458,7 +458,7 @@ gdk_content_formats_union_deserialize_gtypes (GdkContentFormats *formats)
|
|
|
|
gdk_content_formats_unref (formats);
|
|
|
|
- return gdk_content_formats_builder_free (builder);
|
|
+ return gdk_content_formats_builder_free_to_formats (builder);
|
|
}
|
|
|
|
/**
|
|
@@ -493,7 +493,7 @@ gdk_content_formats_union_deserialize_mime_types (GdkContentFormats *formats)
|
|
|
|
gdk_content_formats_unref (formats);
|
|
|
|
- return gdk_content_formats_builder_free (builder);
|
|
+ return gdk_content_formats_builder_free_to_formats (builder);
|
|
}
|
|
|
|
static void
|
|
diff --git a/gdk/gdkcontentformats.c b/gdk/gdkcontentformats.c
|
|
index 04bd064..cd3293f 100644
|
|
--- a/gdk/gdkcontentformats.c
|
|
+++ b/gdk/gdkcontentformats.c
|
|
@@ -307,7 +307,7 @@ gdk_content_formats_union (GdkContentFormats *first,
|
|
gdk_content_formats_unref (first);
|
|
gdk_content_formats_builder_add_formats (builder, second);
|
|
|
|
- return gdk_content_formats_builder_free (builder);
|
|
+ return gdk_content_formats_builder_free_to_formats (builder);
|
|
}
|
|
|
|
static gboolean
|
|
@@ -510,12 +510,22 @@ gdk_content_formats_get_mime_types (GdkContentFormats *formats,
|
|
|
|
struct _GdkContentFormatsBuilder
|
|
{
|
|
+ int ref_count;
|
|
+
|
|
+ /* (element-type GType) */
|
|
GSList *gtypes;
|
|
gsize n_gtypes;
|
|
+
|
|
+ /* (element-type utf8) (interned) */
|
|
GSList *mime_types;
|
|
gsize n_mime_types;
|
|
};
|
|
|
|
+G_DEFINE_BOXED_TYPE (GdkContentFormatsBuilder,
|
|
+ gdk_content_formats_builder,
|
|
+ gdk_content_formats_builder_ref,
|
|
+ gdk_content_formats_builder_unref)
|
|
+
|
|
/**
|
|
* gdk_content_formats_builder_new:
|
|
*
|
|
@@ -528,19 +538,106 @@ struct _GdkContentFormatsBuilder
|
|
GdkContentFormatsBuilder *
|
|
gdk_content_formats_builder_new (void)
|
|
{
|
|
- return g_slice_new0 (GdkContentFormatsBuilder);
|
|
+ GdkContentFormatsBuilder *builder;
|
|
+
|
|
+ builder = g_slice_new0 (GdkContentFormatsBuilder);
|
|
+ builder->ref_count = 1;
|
|
+
|
|
+ return builder;
|
|
}
|
|
|
|
/**
|
|
- * gdk_content_formats_builder_free:
|
|
+ * gdk_content_formats_builder_ref:
|
|
* @builder: a #GdkContentFormatsBuilder
|
|
*
|
|
- * Frees @builder and creates a new #GdkContentFormats from it.
|
|
+ * Acquires a reference on the given @builder.
|
|
*
|
|
- * Returns: a new #GdkContentFormats with all the formats added to @builder
|
|
- **/
|
|
+ * This function is intended primarily for bindings. #GdkContentFormatsBuilder objects
|
|
+ * should not be kept around.
|
|
+ *
|
|
+ * Returns: (transfer none): the given #GdkContentFormatsBuilder with
|
|
+ * its reference count increased
|
|
+ */
|
|
+GdkContentFormatsBuilder *
|
|
+gdk_content_formats_builder_ref (GdkContentFormatsBuilder *builder)
|
|
+{
|
|
+ g_return_val_if_fail (builder != NULL, NULL);
|
|
+ g_return_val_if_fail (builder->ref_count > 0, NULL);
|
|
+
|
|
+ builder->ref_count += 1;
|
|
+
|
|
+ return builder;
|
|
+}
|
|
+
|
|
+static void
|
|
+gdk_content_formats_builder_clear (GdkContentFormatsBuilder *builder)
|
|
+{
|
|
+ g_clear_pointer (&builder->gtypes, g_slist_free);
|
|
+ g_clear_pointer (&builder->mime_types, g_slist_free);
|
|
+}
|
|
+
|
|
+/**
|
|
+ * gdk_content_formats_builder_unref:
|
|
+ * @builder: a #GdkContentFormatsBuilder
|
|
+ *
|
|
+ * Releases a reference on the given @builder.
|
|
+ */
|
|
+void
|
|
+gdk_content_formats_builder_unref (GdkContentFormatsBuilder *builder)
|
|
+{
|
|
+ g_return_if_fail (builder != NULL);
|
|
+ g_return_if_fail (builder->ref_count > 0);
|
|
+
|
|
+ builder->ref_count -= 1;
|
|
+
|
|
+ if (builder->ref_count > 0)
|
|
+ return;
|
|
+
|
|
+ gdk_content_formats_builder_clear (builder);
|
|
+ g_slice_free (GdkContentFormatsBuilder, builder);
|
|
+}
|
|
+
|
|
+/**
|
|
+ * gdk_content_formats_builder_free_to_formats: (skip)
|
|
+ * @builder: a #GdkContentFormatsBuilder
|
|
+ *
|
|
+ * Creates a new #GdkContentFormats from the current state of the
|
|
+ * given @builder, and frees the @builder instance.
|
|
+ *
|
|
+ * Returns: (transfer full): the newly created #GdkContentFormats
|
|
+ * with all the formats added to @builder
|
|
+ */
|
|
+GdkContentFormats *
|
|
+gdk_content_formats_builder_free_to_formats (GdkContentFormatsBuilder *builder)
|
|
+{
|
|
+ GdkContentFormats *res;
|
|
+
|
|
+ g_return_val_if_fail (builder != NULL, NULL);
|
|
+
|
|
+ res = gdk_content_formats_builder_to_formats (builder);
|
|
+
|
|
+ gdk_content_formats_builder_unref (builder);
|
|
+
|
|
+ return res;
|
|
+}
|
|
+
|
|
+/**
|
|
+ * gdk_content_formats_builder_to_formats:
|
|
+ * @builder: a #GdkContentFormatsBuilder
|
|
+ *
|
|
+ * Creates a new #GdkContentFormats from the given @builder.
|
|
+ *
|
|
+ * The given #GdkContentFormatsBuilder is reset once this function returns;
|
|
+ * you cannot call this function multiple times on the same @builder instance.
|
|
+ *
|
|
+ * This function is intended primarily for bindings. C code should use
|
|
+ * gdk_content_formats_builder_free_to_formats().
|
|
+ *
|
|
+ * Returns: (transfer full): the newly created #GdkContentFormats
|
|
+ * with all the formats added to @builder
|
|
+ */
|
|
GdkContentFormats *
|
|
-gdk_content_formats_builder_free (GdkContentFormatsBuilder *builder)
|
|
+gdk_content_formats_builder_to_formats (GdkContentFormatsBuilder *builder)
|
|
{
|
|
GdkContentFormats *result;
|
|
GType *gtypes;
|
|
@@ -567,9 +664,7 @@ gdk_content_formats_builder_free (GdkContentFormatsBuilder *builder)
|
|
result = gdk_content_formats_new_take (gtypes, builder->n_gtypes,
|
|
mime_types, builder->n_mime_types);
|
|
|
|
- g_slist_free (builder->gtypes);
|
|
- g_slist_free (builder->mime_types);
|
|
- g_slice_free (GdkContentFormatsBuilder, builder);
|
|
+ gdk_content_formats_builder_clear (builder);
|
|
|
|
return result;
|
|
}
|
|
diff --git a/gdk/gdkcontentformats.h b/gdk/gdkcontentformats.h
|
|
index 58bbb10..a383434 100644
|
|
--- a/gdk/gdkcontentformats.h
|
|
+++ b/gdk/gdkcontentformats.h
|
|
@@ -77,12 +77,23 @@ GDK_AVAILABLE_IN_3_94
|
|
gboolean gdk_content_formats_contain_mime_type (const GdkContentFormats *formats,
|
|
const char *mime_type);
|
|
|
|
+#define GDK_TYPE_CONTENT_FORMATS_BUILDER (gdk_content_formats_builder_get_type ())
|
|
+
|
|
typedef struct _GdkContentFormatsBuilder GdkContentFormatsBuilder;
|
|
|
|
GDK_AVAILABLE_IN_3_94
|
|
-GdkContentFormatsBuilder*gdk_content_formats_builder_new (void);
|
|
+GType gdk_content_formats_builder_get_type (void) G_GNUC_CONST;
|
|
+
|
|
+GDK_AVAILABLE_IN_3_94
|
|
+GdkContentFormatsBuilder *gdk_content_formats_builder_new (void);
|
|
+GDK_AVAILABLE_IN_3_94
|
|
+GdkContentFormatsBuilder *gdk_content_formats_builder_ref (GdkContentFormatsBuilder *builder);
|
|
+GDK_AVAILABLE_IN_3_94
|
|
+void gdk_content_formats_builder_unref (GdkContentFormatsBuilder *builder);
|
|
+GDK_AVAILABLE_IN_3_94
|
|
+GdkContentFormats * gdk_content_formats_builder_free_to_formats (GdkContentFormatsBuilder *builder) G_GNUC_WARN_UNUSED_RESULT;
|
|
GDK_AVAILABLE_IN_3_94
|
|
-GdkContentFormats * gdk_content_formats_builder_free (GdkContentFormatsBuilder *builder) G_GNUC_WARN_UNUSED_RESULT;
|
|
+GdkContentFormats * gdk_content_formats_builder_to_formats (GdkContentFormatsBuilder *builder) G_GNUC_WARN_UNUSED_RESULT;
|
|
GDK_AVAILABLE_IN_3_94
|
|
void gdk_content_formats_builder_add_formats (GdkContentFormatsBuilder *builder,
|
|
const GdkContentFormats *formats);
|
|
diff --git a/gdk/gdkcontentproviderimpl.c b/gdk/gdkcontentproviderimpl.c
|
|
index 9ae14e0..e7b70c2 100644
|
|
--- a/gdk/gdkcontentproviderimpl.c
|
|
+++ b/gdk/gdkcontentproviderimpl.c
|
|
@@ -168,7 +168,7 @@ gdk_content_provider_bytes_ref_formats (GdkContentProvider *provider)
|
|
|
|
builder = gdk_content_formats_builder_new ();
|
|
gdk_content_formats_builder_add_mime_type (builder, content->mime_type);
|
|
- return gdk_content_formats_builder_free (builder);
|
|
+ return gdk_content_formats_builder_free_to_formats (builder);
|
|
}
|
|
|
|
static void
|
|
diff --git a/gdk/gdkcontentserializer.c b/gdk/gdkcontentserializer.c
|
|
index 843c613..92cbb2d 100644
|
|
--- a/gdk/gdkcontentserializer.c
|
|
+++ b/gdk/gdkcontentserializer.c
|
|
@@ -461,7 +461,7 @@ gdk_content_formats_union_serialize_gtypes (GdkContentFormats *formats)
|
|
|
|
gdk_content_formats_unref (formats);
|
|
|
|
- return gdk_content_formats_builder_free (builder);
|
|
+ return gdk_content_formats_builder_free_to_formats (builder);
|
|
}
|
|
|
|
/**
|
|
@@ -496,7 +496,7 @@ gdk_content_formats_union_serialize_mime_types (GdkContentFormats *formats)
|
|
|
|
gdk_content_formats_unref (formats);
|
|
|
|
- return gdk_content_formats_builder_free (builder);
|
|
+ return gdk_content_formats_builder_free_to_formats (builder);
|
|
}
|
|
|
|
static void
|
|
diff --git a/gdk/wayland/gdkprimary-wayland.c b/gdk/wayland/gdkprimary-wayland.c
|
|
index 89f02e6..62a6941 100644
|
|
--- a/gdk/wayland/gdkprimary-wayland.c
|
|
+++ b/gdk/wayland/gdkprimary-wayland.c
|
|
@@ -58,7 +58,7 @@ gdk_wayland_primary_discard_pending (GdkWaylandPrimary *cb)
|
|
{
|
|
if (cb->pending_builder)
|
|
{
|
|
- GdkContentFormats *ignore = gdk_content_formats_builder_free (cb->pending_builder);
|
|
+ GdkContentFormats *ignore = gdk_content_formats_builder_free_to_formats (cb->pending_builder);
|
|
gdk_content_formats_unref (ignore);
|
|
cb->pending_builder = NULL;
|
|
}
|
|
@@ -178,7 +178,7 @@ primary_selection_selection (void *data,
|
|
return;
|
|
}
|
|
|
|
- formats = gdk_content_formats_builder_free (cb->pending_builder);
|
|
+ formats = gdk_content_formats_builder_free_to_formats (cb->pending_builder);
|
|
cb->pending_builder = NULL;
|
|
cb->pending = NULL;
|
|
|
|
diff --git a/gdk/wayland/gdkselection-wayland.c b/gdk/wayland/gdkselection-wayland.c
|
|
index 0db6bad..9f7826e 100644
|
|
--- a/gdk/wayland/gdkselection-wayland.c
|
|
+++ b/gdk/wayland/gdkselection-wayland.c
|
|
@@ -124,7 +124,7 @@ data_offer_offer (void *data,
|
|
gdk_content_formats_builder_add_formats (builder, info->targets);
|
|
gdk_content_formats_builder_add_mime_type (builder, type);
|
|
gdk_content_formats_unref (info->targets);
|
|
- info->targets = gdk_content_formats_builder_free (builder);
|
|
+ info->targets = gdk_content_formats_builder_free_to_formats (builder);
|
|
}
|
|
|
|
static inline GdkDragAction
|
|
diff --git a/gdk/win32/gdkdnd-win32.c b/gdk/win32/gdkdnd-win32.c
|
|
index 190386c..1d844a8 100644
|
|
--- a/gdk/win32/gdkdnd-win32.c
|
|
+++ b/gdk/win32/gdkdnd-win32.c
|
|
@@ -552,7 +552,7 @@ query_targets (LPDATAOBJECT pDataObj,
|
|
for (p = g_list_reverse (result); p; p = p->next)
|
|
gdk_content_formats_builder_add_mime_type (builder, (const gchar *) p->data);
|
|
|
|
- result_formats = gdk_content_formats_builder_free (builder);
|
|
+ result_formats = gdk_content_formats_builder_free_to_formats (builder);
|
|
g_list_free (result);
|
|
|
|
return result_formats;
|
|
diff --git a/gdk/x11/gdkclipboard-x11.c b/gdk/x11/gdkclipboard-x11.c
|
|
index 02a0b4e..c7b3780 100644
|
|
--- a/gdk/x11/gdkclipboard-x11.c
|
|
+++ b/gdk/x11/gdkclipboard-x11.c
|
|
@@ -243,7 +243,7 @@ gdk_x11_clipboard_formats_from_atoms (GdkDisplay *display,
|
|
}
|
|
}
|
|
|
|
- return gdk_content_formats_builder_free (builder);
|
|
+ return gdk_content_formats_builder_free_to_formats (builder);
|
|
}
|
|
|
|
static void
|
|
diff --git a/gtk/gtkselection.c b/gtk/gtkselection.c
|
|
index 66dbd02..5dc56a7 100644
|
|
--- a/gtk/gtkselection.c
|
|
+++ b/gtk/gtkselection.c
|
|
@@ -176,7 +176,7 @@ gtk_content_formats_add_text_targets (GdkContentFormats *list)
|
|
gdk_content_formats_builder_add_mime_type (builder, text_plain_locale_atom);
|
|
gdk_content_formats_builder_add_mime_type (builder, text_plain_atom);
|
|
|
|
- return gdk_content_formats_builder_free (builder);
|
|
+ return gdk_content_formats_builder_free_to_formats (builder);
|
|
}
|
|
|
|
/**
|
|
@@ -243,7 +243,7 @@ gtk_content_formats_add_image_targets (GdkContentFormats *list,
|
|
|
|
g_slist_free (formats);
|
|
|
|
- return gdk_content_formats_builder_free (builder);
|
|
+ return gdk_content_formats_builder_free_to_formats (builder);
|
|
}
|
|
|
|
/**
|
|
@@ -270,7 +270,7 @@ gtk_content_formats_add_uri_targets (GdkContentFormats *list)
|
|
|
|
gdk_content_formats_builder_add_mime_type (builder, text_uri_list_atom);
|
|
|
|
- return gdk_content_formats_builder_free (builder);
|
|
+ return gdk_content_formats_builder_free_to_formats (builder);
|
|
}
|
|
|
|
/**
|
|
--
|
|
libgit2 0.26.0
|
|
|
|
|