Add a generic callback content provider

This one is convenient to use in cases where a
drag is just serving an existing GType which
is covered by content serializers.
This commit is contained in:
Matthias Clasen 2019-12-31 11:48:22 -05:00
parent 8137dea8c1
commit fdcfe0e80a
2 changed files with 93 additions and 0 deletions

View File

@ -280,3 +280,90 @@ gdk_content_provider_new_for_bytes (const char *mime_type,
return GDK_CONTENT_PROVIDER (content);
}
#define GDK_TYPE_CONTENT_PROVIDER_CALLBACK (gdk_content_provider_callback_get_type ())
#define GDK_CONTENT_PROVIDER_CALLBACK(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GDK_TYPE_CONTENT_PROVIDER_CALLBACK, GdkContentProviderCallback))
typedef struct _GdkContentProviderCallback GdkContentProviderCallback;
typedef struct _GdkContentProviderCallbackClass GdkContentProviderCallbackClass;
struct _GdkContentProviderCallback
{
GdkContentProvider parent;
GType type;
GdkContentProviderGetValueFunc func;
gpointer data;
};
struct _GdkContentProviderCallbackClass
{
GdkContentProviderClass parent_class;
};
GType gdk_content_provider_callback_get_type (void) G_GNUC_CONST;
G_DEFINE_TYPE (GdkContentProviderCallback, gdk_content_provider_callback, GDK_TYPE_CONTENT_PROVIDER)
static GdkContentFormats *
gdk_content_provider_callback_ref_formats (GdkContentProvider *provider)
{
GdkContentProviderCallback *callback = GDK_CONTENT_PROVIDER_CALLBACK (provider);
return gdk_content_formats_new_for_gtype (callback->type);
}
static gboolean
gdk_content_provider_callback_get_value (GdkContentProvider *provider,
GValue *value,
GError **error)
{
GdkContentProviderCallback *callback = GDK_CONTENT_PROVIDER_CALLBACK (provider);
if (G_VALUE_HOLDS (value, callback->type) && callback->func != NULL)
{
callback->func (value, callback->data);
return TRUE;
}
return GDK_CONTENT_PROVIDER_CLASS (gdk_content_provider_callback_parent_class)->get_value (provider, value, error);
}
static void
gdk_content_provider_callback_class_init (GdkContentProviderCallbackClass *class)
{
GdkContentProviderClass *provider_class = GDK_CONTENT_PROVIDER_CLASS (class);
provider_class->ref_formats = gdk_content_provider_callback_ref_formats;
provider_class->get_value = gdk_content_provider_callback_get_value;
}
static void
gdk_content_provider_callback_init (GdkContentProviderCallback *content)
{
}
/**
* gdk_content_provider_new_for_callback:
* @type: the type that the callback provides
* @func: callback to populate a #GValue
* @data: data that gets passed to @func
*
* Create a content provider that provides data that is provided via a callback.
*
* Returns: a new #GdkContentProvider
**/
GdkContentProvider *
gdk_content_provider_new_with_callback (GType type,
GdkContentProviderGetValueFunc func,
gpointer data)
{
GdkContentProviderCallback *content;
content = g_object_new (GDK_TYPE_CONTENT_PROVIDER_CALLBACK, NULL);
content->type = type;
content->func = func;
content->data = data;
return GDK_CONTENT_PROVIDER (content);
}

View File

@ -35,7 +35,13 @@ GDK_AVAILABLE_IN_ALL
GdkContentProvider * gdk_content_provider_new_for_bytes (const char *mime_type,
GBytes *bytes);
typedef void (*GdkContentProviderGetValueFunc) (GValue *value,
gpointer data);
GDK_AVAILABLE_IN_ALL
GdkContentProvider * gdk_content_provider_new_with_callback (GType type,
GdkContentProviderGetValueFunc func,
gpointer data);
G_END_DECLS
#endif /* __GDK_CONTENT_PROVIDER_IMPL_H__ */