diff --git a/gdk/gdk.h b/gdk/gdk.h index 59279d3011..3362f9aefc 100644 --- a/gdk/gdk.h +++ b/gdk/gdk.h @@ -46,6 +46,7 @@ #include #include #include +#include #include #include #include diff --git a/gdk/gdkdnd.c b/gdk/gdkdnd.c index 191ef7eb75..083adf9a5a 100644 --- a/gdk/gdkdnd.c +++ b/gdk/gdkdnd.c @@ -35,12 +35,16 @@ #include "gdkenumtypes.h" #include "gdkeventsprivate.h" +#define DROP_SUBCLASS 1 + typedef struct _GdkDragContextPrivate GdkDragContextPrivate; struct _GdkDragContextPrivate { +#ifndef DROP_SUBCLASS GdkDisplay *display; GdkDevice *device; +#endif GdkContentFormats *formats; }; @@ -60,9 +64,11 @@ static struct { enum { PROP_0, PROP_CONTENT, +#ifndef DROP_SUBCLASS PROP_DEVICE, PROP_DISPLAY, PROP_FORMATS, +#endif N_PROPERTIES }; @@ -78,7 +84,7 @@ static GParamSpec *properties[N_PROPERTIES] = { NULL, }; static guint signals[N_SIGNALS] = { 0 }; static GList *contexts = NULL; -G_DEFINE_TYPE_WITH_PRIVATE (GdkDragContext, gdk_drag_context, G_TYPE_OBJECT) +G_DEFINE_TYPE_WITH_PRIVATE (GdkDragContext, gdk_drag_context, GDK_TYPE_DROP) /** * SECTION:dnd @@ -114,11 +120,15 @@ G_DEFINE_TYPE_WITH_PRIVATE (GdkDragContext, gdk_drag_context, G_TYPE_OBJECT) GdkDisplay * gdk_drag_context_get_display (GdkDragContext *context) { +#ifdef DROP_SUBCLASS + return gdk_drop_get_display (GDK_DROP (context)); +#else GdkDragContextPrivate *priv = gdk_drag_context_get_instance_private (context); g_return_val_if_fail (GDK_IS_DRAG_CONTEXT (context), NULL); return priv->display; +#endif } /** @@ -136,6 +146,12 @@ gdk_drag_context_get_formats (GdkDragContext *context) g_return_val_if_fail (GDK_IS_DRAG_CONTEXT (context), NULL); +#ifdef DROP_SUBCLASS + GdkContentFormats *formats = gdk_drop_get_formats (GDK_DROP (context)); + + if (formats) + return formats; +#endif return priv->formats; } @@ -231,11 +247,15 @@ gdk_drag_context_get_dest_surface (GdkDragContext *context) GdkDevice * gdk_drag_context_get_device (GdkDragContext *context) { +#ifdef DROP_SUBCLASS + return gdk_drop_get_device (GDK_DROP (context)); +#else GdkDragContextPrivate *priv = gdk_drag_context_get_instance_private (context); g_return_val_if_fail (GDK_IS_DRAG_CONTEXT (context), NULL); return priv->device; +#endif } static void @@ -264,6 +284,7 @@ gdk_drag_context_set_property (GObject *gobject, } break; +#ifndef DROP_SUBCLASS case PROP_DEVICE: priv->device = g_value_dup_object (value); g_assert (priv->device != NULL); @@ -286,6 +307,7 @@ gdk_drag_context_set_property (GObject *gobject, g_assert (priv->formats != NULL); } break; +#endif default: G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); @@ -300,7 +322,9 @@ gdk_drag_context_get_property (GObject *gobject, GParamSpec *pspec) { GdkDragContext *context = GDK_DRAG_CONTEXT (gobject); +#ifndef DROP_SUBCLASS GdkDragContextPrivate *priv = gdk_drag_context_get_instance_private (context); +#endif switch (prop_id) { @@ -308,6 +332,7 @@ gdk_drag_context_get_property (GObject *gobject, g_value_set_object (value, context->content); break; +#ifndef DROP_SUBCLASS case PROP_DEVICE: g_value_set_object (value, priv->device); break; @@ -319,6 +344,7 @@ gdk_drag_context_get_property (GObject *gobject, case PROP_FORMATS: g_value_set_boxed (value, priv->formats); break; +#endif default: G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); @@ -405,6 +431,7 @@ gdk_drag_context_class_init (GdkDragContextClass *klass) G_PARAM_STATIC_STRINGS | G_PARAM_EXPLICIT_NOTIFY); +#ifndef DROP_SUBCLASS /** * GdkDragContext:device: * @@ -448,6 +475,7 @@ gdk_drag_context_class_init (GdkDragContextClass *klass) G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS | G_PARAM_EXPLICIT_NOTIFY); +#endif /** * GdkDragContext::cancel: diff --git a/gdk/gdkdndprivate.h b/gdk/gdkdndprivate.h index 8f779dabb2..9c240f084a 100644 --- a/gdk/gdkdndprivate.h +++ b/gdk/gdkdndprivate.h @@ -20,6 +20,8 @@ #include "gdkdnd.h" +#include "gdkdropprivate.h" + G_BEGIN_DECLS @@ -31,7 +33,7 @@ typedef struct _GdkDragContextClass GdkDragContextClass; struct _GdkDragContextClass { - GObjectClass parent_class; + GdkDropClass parent_class; void (*drag_status) (GdkDragContext *context, GdkDragAction action, @@ -77,7 +79,7 @@ struct _GdkDragContextClass { }; struct _GdkDragContext { - GObject parent_instance; + GdkDrop parent_instance; /*< private >*/ gboolean is_source; diff --git a/gdk/gdkdrop.c b/gdk/gdkdrop.c new file mode 100644 index 0000000000..0e7bb8f262 --- /dev/null +++ b/gdk/gdkdrop.c @@ -0,0 +1,242 @@ +/* + * Copyright © 2018 Benjamin Otte + * + * 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 . + * + * Authors: Benjamin Otte + */ + +#include "config.h" + +#include "gdkdndprivate.h" +#include "gdkdisplay.h" +#include "gdksurface.h" +#include "gdkintl.h" +#include "gdkcontentformats.h" +#include "gdkcontentprovider.h" +#include "gdkcontentserializer.h" +#include "gdkcursor.h" +#include "gdkenumtypes.h" +#include "gdkeventsprivate.h" + +typedef struct _GdkDropPrivate GdkDropPrivate; + +struct _GdkDropPrivate { + GdkDevice *device; + GdkContentFormats *formats; +}; + +enum { + PROP_0, + PROP_DEVICE, + PROP_DISPLAY, + PROP_FORMATS, + N_PROPERTIES +}; + +static GParamSpec *properties[N_PROPERTIES] = { NULL, }; + +G_DEFINE_TYPE_WITH_PRIVATE (GdkDrop, gdk_drop, G_TYPE_OBJECT) + +/** + * GdkDrop: + * + * The GdkDrop struct contains only private fields and + * should not be accessed directly. + */ + +static void +gdk_drop_init (GdkDrop *self) +{ +} + +static void +gdk_drop_set_property (GObject *gobject, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + GdkDrop *self = GDK_DROP (gobject); + GdkDropPrivate *priv = gdk_drop_get_instance_private (self); + + switch (prop_id) + { + case PROP_DEVICE: + priv->device = g_value_dup_object (value); + g_assert (priv->device != NULL); + break; + + case PROP_FORMATS: + priv->formats = g_value_dup_boxed (value); +#ifdef DROP_SUBCLASS + g_assert (priv->formats != NULL); +#endif + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); + break; + } +} + +static void +gdk_drop_get_property (GObject *gobject, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + GdkDrop *self = GDK_DROP (gobject); + GdkDropPrivate *priv = gdk_drop_get_instance_private (self); + + switch (prop_id) + { + case PROP_DEVICE: + g_value_set_object (value, priv->device); + break; + + case PROP_DISPLAY: + g_value_set_object (value, gdk_device_get_display (priv->device)); + break; + + case PROP_FORMATS: + g_value_set_boxed (value, priv->formats); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); + break; + } +} + +static void +gdk_drop_finalize (GObject *object) +{ + GdkDrop *self = GDK_DROP (object); + GdkDropPrivate *priv = gdk_drop_get_instance_private (self); + + g_clear_object (&priv->device); + + G_OBJECT_CLASS (gdk_drop_parent_class)->finalize (object); +} + +static void +gdk_drop_class_init (GdkDropClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->get_property = gdk_drop_get_property; + object_class->set_property = gdk_drop_set_property; + object_class->finalize = gdk_drop_finalize; + + /** + * GdkDrop:device: + * + * The #GdkDevice performing the drop + */ + properties[PROP_DEVICE] = + g_param_spec_object ("device", + "Device", + "The device performing the drop", + GDK_TYPE_DEVICE, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS | + G_PARAM_EXPLICIT_NOTIFY); + + /** + * GdkDrop:display: + * + * The #GdkDisplay that the drop belongs to. + */ + properties[PROP_DISPLAY] = + g_param_spec_object ("display", + "Display", + "Display this drag belongs to", + GDK_TYPE_DISPLAY, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS | + G_PARAM_EXPLICIT_NOTIFY); + + /** + * GdkDrop:formats: + * + * The possible formats that the drop can provide its data in. + */ + properties[PROP_FORMATS] = + g_param_spec_boxed ("formats", + "Formats", + "The possible formats for data", + GDK_TYPE_CONTENT_FORMATS, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS | + G_PARAM_EXPLICIT_NOTIFY); + g_object_class_install_properties (object_class, N_PROPERTIES, properties); +} + +/** + * gdk_drop_get_display: + * @self: a #GdkDrop + * + * Gets the #GdkDisplay that @self was created for. + * + * Returns: (transfer none): a #GdkDisplay + **/ +GdkDisplay * +gdk_drop_get_display (GdkDrop *self) +{ + GdkDropPrivate *priv = gdk_drop_get_instance_private (self); + + g_return_val_if_fail (GDK_IS_DROP (self), NULL); + + return gdk_device_get_display (priv->device); +} + +/** + * gdk_drop_get_device: + * @self: a #GdkDrop + * + * Returns the #GdkDevice performing the drop. + * + * Returns: (transfer none): The #GdkDevice performing the drop. + **/ +GdkDevice * +gdk_drop_get_device (GdkDrop *self) +{ + GdkDropPrivate *priv = gdk_drop_get_instance_private (self); + + g_return_val_if_fail (GDK_IS_DROP (self), NULL); + + return priv->device; +} + +/** + * gdk_drop_get_formats: + * @self: a #GdkDrop + * + * Returns the #GdkContentFormats that the drop offers the data + * to be read in. + * + * Returns: (transfer none): The possible #GdkContentFormats + **/ +GdkContentFormats * +gdk_drop_get_formats (GdkDrop *self) +{ + GdkDropPrivate *priv = gdk_drop_get_instance_private (self); + + g_return_val_if_fail (GDK_IS_DROP (self), NULL); + + return priv->formats; +} + diff --git a/gdk/gdkdrop.h b/gdk/gdkdrop.h new file mode 100644 index 0000000000..e8a5423e91 --- /dev/null +++ b/gdk/gdkdrop.h @@ -0,0 +1,51 @@ +/* + * Copyright © 2018 Benjamin Otte + * + * 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 . + * + * Authors: Benjamin Otte + */ + + +#ifndef __GDK_DROP_H__ +#define __GDK_DROP_H__ + +#if !defined (__GDK_H_INSIDE__) && !defined (GDK_COMPILATION) +#error "Only can be included directly." +#endif + +#include +#include + +G_BEGIN_DECLS + +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GdkDrop, g_object_unref) + +#define GDK_TYPE_DROP (gdk_drop_get_type ()) +#define GDK_DROP(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), GDK_TYPE_DROP, GdkDrop)) +#define GDK_IS_DROP(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), GDK_TYPE_DROP)) + +GDK_AVAILABLE_IN_ALL +GType gdk_drop_get_type (void) G_GNUC_CONST; + +GDK_AVAILABLE_IN_ALL +GdkDisplay * gdk_drop_get_display (GdkDrop *self); +GDK_AVAILABLE_IN_ALL +GdkDevice * gdk_drop_get_device (GdkDrop *self); +GDK_AVAILABLE_IN_ALL +GdkContentFormats * gdk_drop_get_formats (GdkDrop *self); + +G_END_DECLS + +#endif /* __GDK_DROP_H__ */ diff --git a/gdk/gdkdropprivate.h b/gdk/gdkdropprivate.h new file mode 100644 index 0000000000..6ddcfb45e9 --- /dev/null +++ b/gdk/gdkdropprivate.h @@ -0,0 +1,46 @@ +/* + * Copyright © 2018 Benjamin Otte + * + * 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 . + * + * Authors: Benjamin Otte + */ + +#ifndef __GDK_DROP_PRIVATE_H__ +#define __GDK_DROP_PRIVATE_H__ + +#include "gdkdrop.h" + +G_BEGIN_DECLS + + +#define GDK_DROP_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GDK_TYPE_DROP, GdkDropClass)) +#define GDK_IS_DROP_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GDK_TYPE_DROP)) +#define GDK_DROP_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GDK_TYPE_DROP, GdkDropClass)) + +typedef struct _GdkDropClass GdkDropClass; + + +struct _GdkDrop { + GObject parent_instance; +}; + +struct _GdkDropClass { + GObjectClass parent_class; +}; + + +G_END_DECLS + +#endif diff --git a/gdk/gdktypes.h b/gdk/gdktypes.h index f2081c1536..ba799fb4ce 100644 --- a/gdk/gdktypes.h +++ b/gdk/gdktypes.h @@ -124,6 +124,7 @@ typedef struct _GdkCursor GdkCursor; typedef struct _GdkTexture GdkTexture; typedef struct _GdkDevice GdkDevice; typedef struct _GdkDragContext GdkDragContext; +typedef struct _GdkDrop GdkDrop; typedef struct _GdkClipboard GdkClipboard; typedef struct _GdkDisplayManager GdkDisplayManager; diff --git a/gdk/meson.build b/gdk/meson.build index f4ec66a53b..4a2e24073c 100644 --- a/gdk/meson.build +++ b/gdk/meson.build @@ -17,6 +17,7 @@ gdk_public_sources = files([ 'gdkdisplaymanager.c', 'gdkdnd.c', 'gdkdrawcontext.c', + 'gdkdrop.c', 'gdkevents.c', 'gdkframeclock.c', 'gdkframeclockidle.c', @@ -66,6 +67,7 @@ gdk_public_headers = files([ 'gdkdisplaymanager.h', 'gdkdnd.h', 'gdkdrawcontext.h', + 'gdkdrop.h', 'gdkevents.h', 'gdkframeclock.h', 'gdkframetimings.h', diff --git a/testsuite/gtk/notify.c b/testsuite/gtk/notify.c index 2738cca4ae..4c340c38de 100644 --- a/testsuite/gtk/notify.c +++ b/testsuite/gtk/notify.c @@ -419,6 +419,15 @@ test_type (gconstpointer data) NULL); gdk_content_formats_unref (formats); } + else if (g_str_equal (g_type_name (type), "GdkDrop")) + { + GdkContentFormats *formats = gdk_content_formats_new_for_gtype (G_TYPE_STRING); + instance = g_object_new (type, + "device", gdk_seat_get_pointer (gdk_display_get_default_seat (gdk_display_get_default ())), + "formats", formats, + NULL); + gdk_content_formats_unref (formats); + } else instance = g_object_new (type, NULL); diff --git a/testsuite/gtk/objects-finalize.c b/testsuite/gtk/objects-finalize.c index a712ee8aba..79f81100a5 100644 --- a/testsuite/gtk/objects-finalize.c +++ b/testsuite/gtk/objects-finalize.c @@ -54,7 +54,8 @@ test_finalize_object (gconstpointer data) if (g_str_equal (g_type_name (test_type), "GdkClipboard")) object = g_object_new (test_type, "display", gdk_display_get_default (), NULL); - else if (g_str_equal (g_type_name (test_type), "GdkDragContext")) + else if (g_str_equal (g_type_name (test_type), "GdkDragContext") || + g_str_equal (g_type_name (test_type), "GdkDrop")) { GdkContentFormats *formats = gdk_content_formats_new_for_gtype (G_TYPE_STRING); object = g_object_new (test_type,