1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
|
/*
* Copyright © 2020 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 <http://www.gnu.org/licenses/>.
*
* Authors: Benjamin Otte <otte@gnome.org>
*/
#include "config.h"
#include "gtkdropprivate.h"
typedef struct _GtkDrop GtkDrop;
struct _GtkDrop
{
/* TRUE if we are waiting for a gdk_drop_status() call */
gboolean waiting;
/* TRUE if begin_event() has been called but end_event() hasn't yet - purely for debugging */
gboolean active;
};
static void
gtk_drop_free (gpointer data)
{
GtkDrop *self = data;
g_slice_free (GtkDrop, self);
}
static GtkDrop *
gtk_drop_lookup (GdkDrop *drop)
{
static GQuark drop_quark = 0;
GtkDrop *result;
if (G_UNLIKELY (drop_quark == 0))
drop_quark = g_quark_from_string ("-gtk-drop-data");
result = g_object_get_qdata (G_OBJECT (drop), drop_quark);
if (result == NULL)
{
result = g_slice_new0 (GtkDrop);
g_object_set_qdata_full (G_OBJECT (drop), drop_quark, result, gtk_drop_free);
}
return result;
}
void
gtk_drop_begin_event (GdkDrop *drop,
GdkEventType event_type)
{
GtkDrop *self;
self = gtk_drop_lookup (drop);
g_assert (self->waiting == FALSE);
g_assert (self->active == FALSE);
self->active = TRUE;
if (event_type == GDK_DRAG_ENTER ||
event_type == GDK_DRAG_MOTION)
self->waiting = TRUE;
}
void
gtk_drop_end_event (GdkDrop *drop)
{
GtkDrop *self;
self = gtk_drop_lookup (drop);
g_assert (self->active == TRUE);
if (self->waiting)
{
gdk_drop_status (drop, 0, 0);
self->waiting = FALSE;
}
self->active = FALSE;
}
gboolean
gtk_drop_status (GdkDrop *drop,
GdkDragAction actions,
GdkDragAction preferred_action)
{
GtkDrop *self;
self = gtk_drop_lookup (drop);
g_assert (self->active == TRUE);
if (!self->waiting)
return FALSE;
gdk_drop_status (drop, actions, preferred_action);
self->waiting = FALSE;
return TRUE;
}
|