2017-11-24 05:17:37 +00:00
|
|
|
/* GDK - The GIMP Drawing Kit
|
|
|
|
*
|
|
|
|
* Copyright (C) 2017 Benjamin Otte <otte@gnome.org>
|
|
|
|
*
|
|
|
|
* 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 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 <http://www.gnu.org/licenses/>.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "config.h"
|
|
|
|
|
|
|
|
#include "gdkcontentprovider.h"
|
|
|
|
|
|
|
|
#include "gdkcontentformats.h"
|
|
|
|
#include "gdkintl.h"
|
|
|
|
#include "gdkcontentproviderimpl.h"
|
|
|
|
|
|
|
|
#define GDK_TYPE_CONTENT_PROVIDER_VALUE (gdk_content_provider_value_get_type ())
|
|
|
|
#define GDK_CONTENT_PROVIDER_VALUE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GDK_TYPE_CONTENT_PROVIDER_VALUE, GdkContentProviderValue))
|
|
|
|
#define GDK_IS_CONTENT_PROVIDER_VALUE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GDK_TYPE_CONTENT_PROVIDER_VALUE))
|
|
|
|
#define GDK_CONTENT_PROVIDER_VALUE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GDK_TYPE_CONTENT_PROVIDER_VALUE, GdkContentProviderValueClass))
|
|
|
|
#define GDK_IS_CONTENT_PROVIDER_VALUE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GDK_TYPE_CONTENT_PROVIDER_VALUE))
|
|
|
|
#define GDK_CONTENT_PROVIDER_VALUE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GDK_TYPE_CONTENT_PROVIDER_VALUE, GdkContentProviderValueClass))
|
|
|
|
|
|
|
|
typedef struct _GdkContentProviderValue GdkContentProviderValue;
|
|
|
|
typedef struct _GdkContentProviderValueClass GdkContentProviderValueClass;
|
|
|
|
|
|
|
|
struct _GdkContentProviderValue
|
|
|
|
{
|
|
|
|
GdkContentProvider parent;
|
|
|
|
|
|
|
|
GValue value;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct _GdkContentProviderValueClass
|
|
|
|
{
|
|
|
|
GdkContentProviderClass parent_class;
|
|
|
|
};
|
|
|
|
|
|
|
|
GType gdk_content_provider_value_get_type (void) G_GNUC_CONST;
|
|
|
|
|
|
|
|
G_DEFINE_TYPE (GdkContentProviderValue, gdk_content_provider_value, GDK_TYPE_CONTENT_PROVIDER)
|
|
|
|
|
|
|
|
static void
|
|
|
|
gdk_content_provider_value_finalize (GObject *object)
|
|
|
|
{
|
|
|
|
GdkContentProviderValue *content = GDK_CONTENT_PROVIDER_VALUE (object);
|
|
|
|
|
|
|
|
g_value_unset (&content->value);
|
|
|
|
|
|
|
|
G_OBJECT_CLASS (gdk_content_provider_value_parent_class)->finalize (object);
|
|
|
|
}
|
|
|
|
|
|
|
|
static GdkContentFormats *
|
|
|
|
gdk_content_provider_value_ref_formats (GdkContentProvider *provider)
|
|
|
|
{
|
|
|
|
GdkContentProviderValue *content = GDK_CONTENT_PROVIDER_VALUE (provider);
|
|
|
|
|
2017-11-28 01:02:06 +00:00
|
|
|
return gdk_content_formats_new_for_gtype (G_VALUE_TYPE (&content->value));
|
2017-11-24 05:17:37 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
gdk_content_provider_value_get_value (GdkContentProvider *provider,
|
|
|
|
GValue *value,
|
|
|
|
GError **error)
|
|
|
|
{
|
|
|
|
GdkContentProviderValue *content = GDK_CONTENT_PROVIDER_VALUE (provider);
|
|
|
|
|
|
|
|
if (G_VALUE_HOLDS (value, G_VALUE_TYPE (&content->value)))
|
|
|
|
{
|
|
|
|
g_value_copy (&content->value, value);
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
return GDK_CONTENT_PROVIDER_CLASS (gdk_content_provider_value_parent_class)->get_value (provider, value, error);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
gdk_content_provider_value_class_init (GdkContentProviderValueClass *class)
|
|
|
|
{
|
|
|
|
GObjectClass *object_class = G_OBJECT_CLASS (class);
|
|
|
|
GdkContentProviderClass *provider_class = GDK_CONTENT_PROVIDER_CLASS (class);
|
|
|
|
|
|
|
|
object_class->finalize = gdk_content_provider_value_finalize;
|
|
|
|
|
|
|
|
provider_class->ref_formats = gdk_content_provider_value_ref_formats;
|
|
|
|
provider_class->get_value = gdk_content_provider_value_get_value;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
gdk_content_provider_value_init (GdkContentProviderValue *content)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* gdk_content_provider_new_for_value:
|
|
|
|
* @value: a #GValue
|
|
|
|
*
|
|
|
|
* Create a content provider that provides the given @value.
|
|
|
|
*
|
|
|
|
* Returns: a new #GdkContentProvider
|
|
|
|
**/
|
|
|
|
GdkContentProvider *
|
|
|
|
gdk_content_provider_new_for_value (const GValue *value)
|
|
|
|
{
|
|
|
|
GdkContentProviderValue *content;
|
|
|
|
|
|
|
|
g_return_val_if_fail (G_IS_VALUE (value), NULL);
|
|
|
|
|
|
|
|
content = g_object_new (GDK_TYPE_CONTENT_PROVIDER_VALUE, NULL);
|
|
|
|
g_value_init (&content->value, G_VALUE_TYPE (value));
|
|
|
|
g_value_copy (value, &content->value);
|
|
|
|
|
|
|
|
return GDK_CONTENT_PROVIDER (content);
|
|
|
|
}
|
|
|
|
|
|
|
|
#define GDK_TYPE_CONTENT_PROVIDER_BYTES (gdk_content_provider_bytes_get_type ())
|
|
|
|
#define GDK_CONTENT_PROVIDER_BYTES(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GDK_TYPE_CONTENT_PROVIDER_BYTES, GdkContentProviderBytes))
|
|
|
|
#define GDK_IS_CONTENT_PROVIDER_BYTES(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GDK_TYPE_CONTENT_PROVIDER_BYTES))
|
|
|
|
#define GDK_CONTENT_PROVIDER_BYTES_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GDK_TYPE_CONTENT_PROVIDER_BYTES, GdkContentProviderBytesClass))
|
|
|
|
#define GDK_IS_CONTENT_PROVIDER_BYTES_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GDK_TYPE_CONTENT_PROVIDER_BYTES))
|
|
|
|
#define GDK_CONTENT_PROVIDER_BYTES_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GDK_TYPE_CONTENT_PROVIDER_BYTES, GdkContentProviderBytesClass))
|
|
|
|
|
|
|
|
typedef struct _GdkContentProviderBytes GdkContentProviderBytes;
|
|
|
|
typedef struct _GdkContentProviderBytesClass GdkContentProviderBytesClass;
|
|
|
|
|
|
|
|
struct _GdkContentProviderBytes
|
|
|
|
{
|
|
|
|
GdkContentProvider parent;
|
|
|
|
|
|
|
|
/* interned */const char *mime_type;
|
|
|
|
GBytes *bytes;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct _GdkContentProviderBytesClass
|
|
|
|
{
|
|
|
|
GdkContentProviderClass parent_class;
|
|
|
|
};
|
|
|
|
|
|
|
|
GType gdk_content_provider_bytes_get_type (void) G_GNUC_CONST;
|
|
|
|
|
|
|
|
G_DEFINE_TYPE (GdkContentProviderBytes, gdk_content_provider_bytes, GDK_TYPE_CONTENT_PROVIDER)
|
|
|
|
|
|
|
|
static void
|
|
|
|
gdk_content_provider_bytes_finalize (GObject *object)
|
|
|
|
{
|
|
|
|
GdkContentProviderBytes *content = GDK_CONTENT_PROVIDER_BYTES (object);
|
|
|
|
|
|
|
|
g_bytes_unref (content->bytes);
|
|
|
|
|
|
|
|
G_OBJECT_CLASS (gdk_content_provider_bytes_parent_class)->finalize (object);
|
|
|
|
}
|
|
|
|
|
|
|
|
static GdkContentFormats *
|
|
|
|
gdk_content_provider_bytes_ref_formats (GdkContentProvider *provider)
|
|
|
|
{
|
|
|
|
GdkContentProviderBytes *content = GDK_CONTENT_PROVIDER_BYTES (provider);
|
|
|
|
GdkContentFormatsBuilder *builder;
|
|
|
|
|
|
|
|
builder = gdk_content_formats_builder_new ();
|
|
|
|
gdk_content_formats_builder_add_mime_type (builder, content->mime_type);
|
|
|
|
return gdk_content_formats_builder_free (builder);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
gdk_content_provider_bytes_write_mime_type_done (GObject *stream,
|
|
|
|
GAsyncResult *result,
|
|
|
|
gpointer task)
|
|
|
|
{
|
|
|
|
GError *error = NULL;
|
|
|
|
|
|
|
|
if (!g_output_stream_write_all_finish (G_OUTPUT_STREAM (stream),
|
|
|
|
result,
|
|
|
|
NULL,
|
|
|
|
&error))
|
|
|
|
{
|
|
|
|
g_task_return_error (task, error);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
g_task_return_boolean (task, TRUE);
|
|
|
|
}
|
|
|
|
|
|
|
|
g_object_unref (task);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
gdk_content_provider_bytes_write_mime_type_async (GdkContentProvider *provider,
|
|
|
|
const char *mime_type,
|
|
|
|
GOutputStream *stream,
|
|
|
|
int io_priority,
|
|
|
|
GCancellable *cancellable,
|
|
|
|
GAsyncReadyCallback callback,
|
|
|
|
gpointer user_data)
|
|
|
|
{
|
|
|
|
GdkContentProviderBytes *content = GDK_CONTENT_PROVIDER_BYTES (provider);
|
|
|
|
GTask *task;
|
|
|
|
|
|
|
|
task = g_task_new (content, cancellable, callback, user_data);
|
|
|
|
g_task_set_priority (task, io_priority);
|
|
|
|
g_task_set_source_tag (task, gdk_content_provider_bytes_write_mime_type_async);
|
|
|
|
|
|
|
|
if (mime_type != content->mime_type)
|
|
|
|
{
|
|
|
|
g_task_return_new_error (task, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
|
2017-12-03 17:38:39 +00:00
|
|
|
_("Cannot provide contents as “%s”"), mime_type);
|
2017-11-24 05:17:37 +00:00
|
|
|
g_object_unref (task);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
g_output_stream_write_all_async (stream,
|
|
|
|
g_bytes_get_data (content->bytes, NULL),
|
|
|
|
g_bytes_get_size (content->bytes),
|
|
|
|
io_priority,
|
|
|
|
cancellable,
|
|
|
|
gdk_content_provider_bytes_write_mime_type_done,
|
|
|
|
task);
|
|
|
|
}
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
gdk_content_provider_bytes_write_mime_type_finish (GdkContentProvider *provider,
|
|
|
|
GAsyncResult *result,
|
|
|
|
GError **error)
|
|
|
|
{
|
|
|
|
g_return_val_if_fail (g_task_is_valid (result, provider), FALSE);
|
|
|
|
g_return_val_if_fail (g_task_get_source_tag (G_TASK (result)) == gdk_content_provider_bytes_write_mime_type_async, FALSE);
|
|
|
|
|
|
|
|
return g_task_propagate_boolean (G_TASK (result), error);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
gdk_content_provider_bytes_class_init (GdkContentProviderBytesClass *class)
|
|
|
|
{
|
|
|
|
GObjectClass *object_class = G_OBJECT_CLASS (class);
|
|
|
|
GdkContentProviderClass *provider_class = GDK_CONTENT_PROVIDER_CLASS (class);
|
|
|
|
|
|
|
|
object_class->finalize = gdk_content_provider_bytes_finalize;
|
|
|
|
|
|
|
|
provider_class->ref_formats = gdk_content_provider_bytes_ref_formats;
|
|
|
|
provider_class->write_mime_type_async = gdk_content_provider_bytes_write_mime_type_async;
|
|
|
|
provider_class->write_mime_type_finish = gdk_content_provider_bytes_write_mime_type_finish;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
gdk_content_provider_bytes_init (GdkContentProviderBytes *content)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* gdk_content_provider_new_for_bytes:
|
|
|
|
* @mime_type: the mime type
|
|
|
|
* @bytes: (transfer none): a #GBytes with the data for @mime_type
|
|
|
|
*
|
|
|
|
* Create a content provider that provides the given @bytes as data for
|
|
|
|
* the given @mime_type.
|
|
|
|
*
|
|
|
|
* Returns: a new #GdkContentProvider
|
|
|
|
**/
|
|
|
|
GdkContentProvider *
|
|
|
|
gdk_content_provider_new_for_bytes (const char *mime_type,
|
|
|
|
GBytes *bytes)
|
|
|
|
{
|
|
|
|
GdkContentProviderBytes *content;
|
|
|
|
|
|
|
|
g_return_val_if_fail (mime_type != NULL, NULL);
|
|
|
|
g_return_val_if_fail (bytes != NULL, NULL);
|
|
|
|
|
|
|
|
content = g_object_new (GDK_TYPE_CONTENT_PROVIDER_BYTES, NULL);
|
|
|
|
content->mime_type = g_intern_string (mime_type);
|
|
|
|
content->bytes = g_bytes_ref (bytes);
|
|
|
|
|
|
|
|
return GDK_CONTENT_PROVIDER (content);
|
|
|
|
}
|