/* DragDropAction.c generated by valac 0.56.3, the Vala compiler
 * generated from DragDropAction.vala, do not modify */

/**/
/*  Copyright (C) 2013 Tom Beckmann*/
/**/
/*  This program is free software: you can redistribute it and/or modify*/
/*  it under the terms of the GNU General Public License as published by*/
/*  the Free Software Foundation, either version 3 of the License, or*/
/*  (at your option) any later version.*/
/**/
/*  This program 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 General Public License for more details.*/
/**/
/*  You should have received a copy of the GNU General Public License*/
/*  along with this program.  If not, see <http://www.gnu.org/licenses/>.*/
/**/

#include "gala.h"
#include <stdlib.h>
#include <string.h>
#include <glib.h>
#include <clutter/clutter.h>
#include <float.h>
#include <math.h>
#include <gee.h>
#include <glib-object.h>

enum  {
	GALA_DRAG_DROP_ACTION_0_PROPERTY,
	GALA_DRAG_DROP_ACTION_DRAG_TYPE_PROPERTY,
	GALA_DRAG_DROP_ACTION_DRAG_ID_PROPERTY,
	GALA_DRAG_DROP_ACTION_HANDLE_PROPERTY,
	GALA_DRAG_DROP_ACTION_DRAGGING_PROPERTY,
	GALA_DRAG_DROP_ACTION_ALLOW_BUBBLING_PROPERTY,
	GALA_DRAG_DROP_ACTION_HOVERED_PROPERTY,
	GALA_DRAG_DROP_ACTION_NUM_PROPERTIES
};
static GParamSpec* gala_drag_drop_action_properties[GALA_DRAG_DROP_ACTION_NUM_PROPERTIES];
#define _g_free0(var) (var = (g_free (var), NULL))
#define _g_object_unref0(var) ((var == NULL) ? NULL : (var = (g_object_unref (var), NULL)))
#define _clutter_grab_unref0(var) ((var == NULL) ? NULL : (var = (clutter_grab_unref (var), NULL)))
enum  {
	GALA_DRAG_DROP_ACTION_DRAG_BEGIN_SIGNAL,
	GALA_DRAG_DROP_ACTION_DRAG_CANCELED_SIGNAL,
	GALA_DRAG_DROP_ACTION_DRAG_END_SIGNAL,
	GALA_DRAG_DROP_ACTION_CROSSED_SIGNAL,
	GALA_DRAG_DROP_ACTION_DESTINATION_CROSSED_SIGNAL,
	GALA_DRAG_DROP_ACTION_ACTOR_CLICKED_SIGNAL,
	GALA_DRAG_DROP_ACTION_NUM_SIGNALS
};
static guint gala_drag_drop_action_signals[GALA_DRAG_DROP_ACTION_NUM_SIGNALS] = {0};

struct _GalaDragDropActionPrivate {
	GalaDragDropActionType _drag_type;
	gchar* _drag_id;
	ClutterActor* _handle;
	gboolean _dragging;
	gboolean _allow_bubbling;
	ClutterActor* _hovered;
	gboolean clicked;
	gfloat last_x;
	gfloat last_y;
	ClutterGrab* grab;
	ClutterInputDevice* grabbed_device;
	gulong on_event_id;
};

static gint GalaDragDropAction_private_offset;
static gpointer gala_drag_drop_action_parent_class = NULL;
static GeeHashMap* gala_drag_drop_action_sources;
static GeeHashMap* gala_drag_drop_action_sources = NULL;
static GeeHashMap* gala_drag_drop_action_destinations;
static GeeHashMap* gala_drag_drop_action_destinations = NULL;
static ClutterActor* gala_drag_drop_action_grabbed_actor;
static ClutterActor* gala_drag_drop_action_grabbed_actor = NULL;

static void gala_drag_drop_action_release_actor (GalaDragDropAction* self,
                                          ClutterActor* actor);
static void gala_drag_drop_action_real_set_actor (ClutterActorMeta* base,
                                           ClutterActor* new_actor);
static void gala_drag_drop_action_connect_actor (GalaDragDropAction* self,
                                          ClutterActor* actor);
static void gala_drag_drop_action_emit_crossed (GalaDragDropAction* self,
                                         ClutterActor* destination,
                                         gboolean is_hovered);
static GalaDragDropAction* gala_drag_drop_action_get_drag_drop_action (GalaDragDropAction* self,
                                                                ClutterActor* actor);
static gboolean gala_drag_drop_action_real_handle_event (ClutterAction* base,
                                                  ClutterEvent* event);
static void gala_drag_drop_action_grab_actor (GalaDragDropAction* self,
                                       ClutterActor* actor,
                                       ClutterInputDevice* device);
static void gala_drag_drop_action_ungrab_actor (GalaDragDropAction* self);
static void gala_drag_drop_action_set_dragging (GalaDragDropAction* self,
                                         gboolean value);
static ClutterActor* gala_drag_drop_action_get_hovered (GalaDragDropAction* self);
static void gala_drag_drop_action_finish (GalaDragDropAction* self);
static gboolean gala_drag_drop_action_on_event (GalaDragDropAction* self,
                                         ClutterEvent* event);
static gboolean _gala_drag_drop_action_on_event_clutter_actor_event (ClutterActor* _sender,
                                                              ClutterEvent* event,
                                                              gpointer self);
static void gala_drag_drop_action_set_handle (GalaDragDropAction* self,
                                       ClutterActor* value);
static void gala_drag_drop_action_cleanup (GalaDragDropAction* self);
static void g_cclosure_user_marshal_OBJECT__FLOAT_FLOAT (GClosure * closure,
                                                  GValue * return_value,
                                                  guint n_param_values,
                                                  const GValue * param_values,
                                                  gpointer invocation_hint,
                                                  gpointer marshal_data);
static void g_cclosure_user_marshal_VOID__OBJECT_BOOLEAN (GClosure * closure,
                                                   GValue * return_value,
                                                   guint n_param_values,
                                                   const GValue * param_values,
                                                   gpointer invocation_hint,
                                                   gpointer marshal_data);
static void gala_drag_drop_action_finalize (GObject * obj);
static GType gala_drag_drop_action_get_type_once (void);
static void _vala_gala_drag_drop_action_get_property (GObject * object,
                                               guint property_id,
                                               GValue * value,
                                               GParamSpec * pspec);
static void _vala_gala_drag_drop_action_set_property (GObject * object,
                                               guint property_id,
                                               const GValue * value,
                                               GParamSpec * pspec);

static GType
gala_drag_drop_action_type_get_type_once (void)
{
	static const GFlagsValue values[] = {{GALA_DRAG_DROP_ACTION_TYPE_SOURCE, "GALA_DRAG_DROP_ACTION_TYPE_SOURCE", "source"}, {GALA_DRAG_DROP_ACTION_TYPE_DESTINATION, "GALA_DRAG_DROP_ACTION_TYPE_DESTINATION", "destination"}, {0, NULL, NULL}};
	GType gala_drag_drop_action_type_type_id;
	gala_drag_drop_action_type_type_id = g_flags_register_static ("GalaDragDropActionType", values);
	return gala_drag_drop_action_type_type_id;
}

GType
gala_drag_drop_action_type_get_type (void)
{
	static volatile gsize gala_drag_drop_action_type_type_id__once = 0;
	if (g_once_init_enter (&gala_drag_drop_action_type_type_id__once)) {
		GType gala_drag_drop_action_type_type_id;
		gala_drag_drop_action_type_type_id = gala_drag_drop_action_type_get_type_once ();
		g_once_init_leave (&gala_drag_drop_action_type_type_id__once, gala_drag_drop_action_type_type_id);
	}
	return gala_drag_drop_action_type_type_id__once;
}

static inline gpointer
gala_drag_drop_action_get_instance_private (GalaDragDropAction* self)
{
	return G_STRUCT_MEMBER_P (self, GalaDragDropAction_private_offset);
}

/**
         * Create a new DragDropAction
         *
         * @param type The type of this actor
         * @param id   An ID that marks which sources can be dragged on
         *             which destinations. It has to be the same for all actors that
         *             should be compatible with each other.
         */
GalaDragDropAction*
gala_drag_drop_action_construct (GType object_type,
                                 GalaDragDropActionType type,
                                 const gchar* id)
{
	GalaDragDropAction * self = NULL;
	GeeHashMap* _tmp0_;
	GeeHashMap* _tmp2_;
	g_return_val_if_fail (id != NULL, NULL);
	self = (GalaDragDropAction*) g_object_new (object_type, "drag-type", type, "drag-id", id, NULL);
	_tmp0_ = gala_drag_drop_action_sources;
	if (_tmp0_ == NULL) {
		GeeHashMap* _tmp1_;
		_tmp1_ = gee_hash_map_new (G_TYPE_STRING, (GBoxedCopyFunc) g_strdup, (GDestroyNotify) g_free, GEE_TYPE_LINKED_LIST, (GBoxedCopyFunc) g_object_ref, (GDestroyNotify) g_object_unref, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
		_g_object_unref0 (gala_drag_drop_action_sources);
		gala_drag_drop_action_sources = _tmp1_;
	}
	_tmp2_ = gala_drag_drop_action_destinations;
	if (_tmp2_ == NULL) {
		GeeHashMap* _tmp3_;
		_tmp3_ = gee_hash_map_new (G_TYPE_STRING, (GBoxedCopyFunc) g_strdup, (GDestroyNotify) g_free, GEE_TYPE_LINKED_LIST, (GBoxedCopyFunc) g_object_ref, (GDestroyNotify) g_object_unref, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
		_g_object_unref0 (gala_drag_drop_action_destinations);
		gala_drag_drop_action_destinations = _tmp3_;
	}
	return self;
}

GalaDragDropAction*
gala_drag_drop_action_new (GalaDragDropActionType type,
                           const gchar* id)
{
	return gala_drag_drop_action_construct (GALA_TYPE_DRAG_DROP_ACTION, type, id);
}

static void
gala_drag_drop_action_real_set_actor (ClutterActorMeta* base,
                                      ClutterActor* new_actor)
{
	GalaDragDropAction * self;
	ClutterActor* _tmp0_;
	ClutterActor* _tmp1_;
	self = (GalaDragDropAction*) base;
	_tmp0_ = clutter_actor_meta_get_actor ((ClutterActorMeta*) self);
	_tmp1_ = _tmp0_;
	if (_tmp1_ != NULL) {
		ClutterActor* _tmp2_;
		ClutterActor* _tmp3_;
		_tmp2_ = clutter_actor_meta_get_actor ((ClutterActorMeta*) self);
		_tmp3_ = _tmp2_;
		gala_drag_drop_action_release_actor (self, _tmp3_);
	}
	if (new_actor != NULL) {
		gala_drag_drop_action_connect_actor (self, new_actor);
	}
	CLUTTER_ACTOR_META_CLASS (gala_drag_drop_action_parent_class)->set_actor ((ClutterActorMeta*) G_TYPE_CHECK_INSTANCE_CAST (self, clutter_action_get_type (), ClutterAction), new_actor);
}

static void
gala_drag_drop_action_release_actor (GalaDragDropAction* self,
                                     ClutterActor* actor)
{
	GalaDragDropActionType _tmp0_;
	GalaDragDropActionType _tmp5_;
	g_return_if_fail (self != NULL);
	g_return_if_fail (actor != NULL);
	_tmp0_ = self->priv->_drag_type;
	if ((_tmp0_ & GALA_DRAG_DROP_ACTION_TYPE_SOURCE) == GALA_DRAG_DROP_ACTION_TYPE_SOURCE) {
		GeeLinkedList* source_list = NULL;
		GeeHashMap* _tmp1_;
		const gchar* _tmp2_;
		gpointer _tmp3_;
		GeeLinkedList* _tmp4_;
		_tmp1_ = gala_drag_drop_action_sources;
		_tmp2_ = self->priv->_drag_id;
		_tmp3_ = gee_abstract_map_get ((GeeAbstractMap*) _tmp1_, _tmp2_);
		source_list = (GeeLinkedList*) _tmp3_;
		_tmp4_ = source_list;
		gee_abstract_collection_remove ((GeeAbstractCollection*) _tmp4_, actor);
		_g_object_unref0 (source_list);
	}
	_tmp5_ = self->priv->_drag_type;
	if ((_tmp5_ & GALA_DRAG_DROP_ACTION_TYPE_DESTINATION) == GALA_DRAG_DROP_ACTION_TYPE_DESTINATION) {
		GeeLinkedList* dest_list = NULL;
		GeeHashMap* _tmp6_;
		const gchar* _tmp7_;
		gpointer _tmp8_;
		GeeLinkedList* _tmp9_;
		_tmp6_ = gala_drag_drop_action_destinations;
		_tmp7_ = self->priv->_drag_id;
		_tmp8_ = gee_abstract_map_get ((GeeAbstractMap*) _tmp6_, _tmp7_);
		dest_list = (GeeLinkedList*) _tmp8_;
		_tmp9_ = dest_list;
		gee_abstract_collection_remove ((GeeAbstractCollection*) _tmp9_, actor);
		_g_object_unref0 (dest_list);
	}
}

static void
gala_drag_drop_action_connect_actor (GalaDragDropAction* self,
                                     ClutterActor* actor)
{
	GalaDragDropActionType _tmp0_;
	GalaDragDropActionType _tmp10_;
	g_return_if_fail (self != NULL);
	g_return_if_fail (actor != NULL);
	_tmp0_ = self->priv->_drag_type;
	if ((_tmp0_ & GALA_DRAG_DROP_ACTION_TYPE_SOURCE) == GALA_DRAG_DROP_ACTION_TYPE_SOURCE) {
		GeeLinkedList* source_list = NULL;
		GeeHashMap* _tmp1_;
		const gchar* _tmp2_;
		gpointer _tmp3_;
		GeeLinkedList* _tmp4_;
		GeeLinkedList* _tmp9_;
		_tmp1_ = gala_drag_drop_action_sources;
		_tmp2_ = self->priv->_drag_id;
		_tmp3_ = gee_abstract_map_get ((GeeAbstractMap*) _tmp1_, _tmp2_);
		source_list = (GeeLinkedList*) _tmp3_;
		_tmp4_ = source_list;
		if (_tmp4_ == NULL) {
			GeeLinkedList* _tmp5_;
			GeeHashMap* _tmp6_;
			const gchar* _tmp7_;
			GeeLinkedList* _tmp8_;
			_tmp5_ = gee_linked_list_new (clutter_actor_get_type (), (GBoxedCopyFunc) g_object_ref, (GDestroyNotify) g_object_unref, NULL, NULL, NULL);
			_g_object_unref0 (source_list);
			source_list = _tmp5_;
			_tmp6_ = gala_drag_drop_action_sources;
			_tmp7_ = self->priv->_drag_id;
			_tmp8_ = source_list;
			gee_abstract_map_set ((GeeAbstractMap*) _tmp6_, _tmp7_, _tmp8_);
		}
		_tmp9_ = source_list;
		gee_abstract_collection_add ((GeeAbstractCollection*) _tmp9_, actor);
		_g_object_unref0 (source_list);
	}
	_tmp10_ = self->priv->_drag_type;
	if ((_tmp10_ & GALA_DRAG_DROP_ACTION_TYPE_DESTINATION) == GALA_DRAG_DROP_ACTION_TYPE_DESTINATION) {
		GeeLinkedList* dest_list = NULL;
		GeeHashMap* _tmp11_;
		const gchar* _tmp12_;
		gpointer _tmp13_;
		GeeLinkedList* _tmp14_;
		GeeLinkedList* _tmp19_;
		_tmp11_ = gala_drag_drop_action_destinations;
		_tmp12_ = self->priv->_drag_id;
		_tmp13_ = gee_abstract_map_get ((GeeAbstractMap*) _tmp11_, _tmp12_);
		dest_list = (GeeLinkedList*) _tmp13_;
		_tmp14_ = dest_list;
		if (_tmp14_ == NULL) {
			GeeLinkedList* _tmp15_;
			GeeHashMap* _tmp16_;
			const gchar* _tmp17_;
			GeeLinkedList* _tmp18_;
			_tmp15_ = gee_linked_list_new (clutter_actor_get_type (), (GBoxedCopyFunc) g_object_ref, (GDestroyNotify) g_object_unref, NULL, NULL, NULL);
			_g_object_unref0 (dest_list);
			dest_list = _tmp15_;
			_tmp16_ = gala_drag_drop_action_destinations;
			_tmp17_ = self->priv->_drag_id;
			_tmp18_ = dest_list;
			gee_abstract_map_set ((GeeAbstractMap*) _tmp16_, _tmp17_, _tmp18_);
		}
		_tmp19_ = dest_list;
		gee_abstract_collection_add ((GeeAbstractCollection*) _tmp19_, actor);
		_g_object_unref0 (dest_list);
	}
}

static void
gala_drag_drop_action_emit_crossed (GalaDragDropAction* self,
                                    ClutterActor* destination,
                                    gboolean is_hovered)
{
	GalaDragDropAction* _tmp0_;
	GalaDragDropAction* _tmp1_;
	ClutterActor* _tmp2_;
	ClutterActor* _tmp3_;
	g_return_if_fail (self != NULL);
	g_return_if_fail (destination != NULL);
	_tmp0_ = gala_drag_drop_action_get_drag_drop_action (self, destination);
	_tmp1_ = _tmp0_;
	_tmp2_ = clutter_actor_meta_get_actor ((ClutterActorMeta*) self);
	_tmp3_ = _tmp2_;
	g_signal_emit (_tmp1_, gala_drag_drop_action_signals[GALA_DRAG_DROP_ACTION_CROSSED_SIGNAL], 0, _tmp3_, is_hovered);
	_g_object_unref0 (_tmp1_);
	g_signal_emit (self, gala_drag_drop_action_signals[GALA_DRAG_DROP_ACTION_DESTINATION_CROSSED_SIGNAL], 0, destination, is_hovered);
}

static gboolean
gala_drag_drop_action_real_handle_event (ClutterAction* base,
                                         ClutterEvent* event)
{
	GalaDragDropAction * self;
	GalaDragDropActionType _tmp0_;
	gboolean result;
	self = (GalaDragDropAction*) base;
	g_return_val_if_fail (event != NULL, FALSE);
	_tmp0_ = self->priv->_drag_type;
	if (!((_tmp0_ & GALA_DRAG_DROP_ACTION_TYPE_SOURCE) == GALA_DRAG_DROP_ACTION_TYPE_SOURCE)) {
		result = FALSE;
		return result;
	}
	switch (clutter_event_type (event)) {
		case CLUTTER_BUTTON_PRESS:
		{
			ClutterActor* _tmp1_;
			ClutterActor* _tmp2_;
			ClutterActor* _tmp3_;
			ClutterInputDevice* _tmp4_;
			gfloat x = 0.0F;
			gfloat y = 0.0F;
			gfloat _tmp5_ = 0.0F;
			gfloat _tmp6_ = 0.0F;
			if (clutter_event_get_button (event) != ((guint32) 1)) {
				g_signal_emit (self, gala_drag_drop_action_signals[GALA_DRAG_DROP_ACTION_ACTOR_CLICKED_SIGNAL], 0, clutter_event_get_button (event));
				result = FALSE;
				return result;
			}
			_tmp1_ = gala_drag_drop_action_grabbed_actor;
			if (_tmp1_ != NULL) {
				result = FALSE;
				return result;
			}
			_tmp2_ = clutter_actor_meta_get_actor ((ClutterActorMeta*) self);
			_tmp3_ = _tmp2_;
			_tmp4_ = clutter_event_get_device (event);
			gala_drag_drop_action_grab_actor (self, _tmp3_, _tmp4_);
			self->priv->clicked = TRUE;
			clutter_event_get_coords (event, &_tmp5_, &_tmp6_);
			x = _tmp5_;
			y = _tmp6_;
			self->priv->last_x = x;
			self->priv->last_y = y;
			result = TRUE;
			return result;
		}
		case CLUTTER_BUTTON_RELEASE:
		{
			gboolean _tmp7_;
			_tmp7_ = self->priv->_dragging;
			if (!_tmp7_) {
				gfloat x = 0.0F;
				gfloat y = 0.0F;
				gfloat ex = 0.0F;
				gfloat ey = 0.0F;
				gfloat _tmp8_ = 0.0F;
				gfloat _tmp9_ = 0.0F;
				ClutterActor* _tmp10_;
				ClutterActor* _tmp11_;
				gfloat _tmp12_ = 0.0F;
				gfloat _tmp13_ = 0.0F;
				gboolean _tmp14_ = FALSE;
				gboolean _tmp15_ = FALSE;
				gboolean _tmp16_ = FALSE;
				clutter_event_get_coords (event, &_tmp8_, &_tmp9_);
				ex = _tmp8_;
				ey = _tmp9_;
				_tmp10_ = clutter_actor_meta_get_actor ((ClutterActorMeta*) self);
				_tmp11_ = _tmp10_;
				clutter_actor_get_transformed_position (_tmp11_, &_tmp12_, &_tmp13_);
				x = _tmp12_;
				y = _tmp13_;
				if (x < ex) {
					ClutterActor* _tmp17_;
					ClutterActor* _tmp18_;
					gfloat _tmp19_;
					gfloat _tmp20_;
					_tmp17_ = clutter_actor_meta_get_actor ((ClutterActorMeta*) self);
					_tmp18_ = _tmp17_;
					_tmp19_ = clutter_actor_get_width (_tmp18_);
					_tmp20_ = _tmp19_;
					_tmp16_ = (x + _tmp20_) > ex;
				} else {
					_tmp16_ = FALSE;
				}
				if (_tmp16_) {
					_tmp15_ = y < ey;
				} else {
					_tmp15_ = FALSE;
				}
				if (_tmp15_) {
					ClutterActor* _tmp21_;
					ClutterActor* _tmp22_;
					gfloat _tmp23_;
					gfloat _tmp24_;
					_tmp21_ = clutter_actor_meta_get_actor ((ClutterActorMeta*) self);
					_tmp22_ = _tmp21_;
					_tmp23_ = clutter_actor_get_height (_tmp22_);
					_tmp24_ = _tmp23_;
					_tmp14_ = (y + _tmp24_) > ey;
				} else {
					_tmp14_ = FALSE;
				}
				if (_tmp14_) {
					g_signal_emit (self, gala_drag_drop_action_signals[GALA_DRAG_DROP_ACTION_ACTOR_CLICKED_SIGNAL], 0, clutter_event_get_button (event));
				}
				gala_drag_drop_action_ungrab_actor (self);
				self->priv->clicked = FALSE;
				gala_drag_drop_action_set_dragging (self, FALSE);
				result = TRUE;
				return result;
			} else {
				gboolean _tmp25_;
				_tmp25_ = self->priv->_dragging;
				if (_tmp25_) {
					ClutterActor* _tmp26_;
					_tmp26_ = self->priv->_hovered;
					if (_tmp26_ != NULL) {
						gala_drag_drop_action_finish (self);
					} else {
						gala_drag_drop_action_cancel (self);
					}
					result = TRUE;
					return result;
				}
			}
			break;
		}
		default:
		{
			break;
		}
	}
	result = CLUTTER_ACTION_CLASS (gala_drag_drop_action_parent_class)->handle_event (G_TYPE_CHECK_INSTANCE_CAST (self, clutter_action_get_type (), ClutterAction), event);
	return result;
}

static gpointer
_g_object_ref0 (gpointer self)
{
	return self ? g_object_ref (self) : NULL;
}

static gboolean
_gala_drag_drop_action_on_event_clutter_actor_event (ClutterActor* _sender,
                                                     ClutterEvent* event,
                                                     gpointer self)
{
	gboolean result;
	result = gala_drag_drop_action_on_event ((GalaDragDropAction*) self, event);
	return result;
}

static void
gala_drag_drop_action_grab_actor (GalaDragDropAction* self,
                                  ClutterActor* actor,
                                  ClutterInputDevice* device)
{
	ClutterActor* _tmp0_;
	ClutterStage* _tmp1_;
	ClutterGrab* _tmp2_;
	ClutterInputDevice* _tmp3_;
	gulong _tmp4_;
	g_return_if_fail (self != NULL);
	g_return_if_fail (actor != NULL);
	g_return_if_fail (device != NULL);
	_tmp0_ = gala_drag_drop_action_grabbed_actor;
	if (_tmp0_ != NULL) {
		g_critical ("DragDropAction.vala:259: Tried to grab an actor with a grab already in" \
" progress");
	}
	_tmp1_ = clutter_actor_get_stage (actor);
	_tmp2_ = clutter_stage_grab (_tmp1_, actor);
	_clutter_grab_unref0 (self->priv->grab);
	self->priv->grab = _tmp2_;
	gala_drag_drop_action_grabbed_actor = actor;
	_tmp3_ = _g_object_ref0 (device);
	_g_object_unref0 (self->priv->grabbed_device);
	self->priv->grabbed_device = _tmp3_;
	_tmp4_ = g_signal_connect_object (actor, "event", (GCallback) _gala_drag_drop_action_on_event_clutter_actor_event, self, 0);
	self->priv->on_event_id = _tmp4_;
}

static void
gala_drag_drop_action_ungrab_actor (GalaDragDropAction* self)
{
	gboolean _tmp0_ = FALSE;
	ClutterGrab* _tmp2_;
	ClutterActor* _tmp4_;
	g_return_if_fail (self != NULL);
	if (self->priv->on_event_id == ((gulong) 0)) {
		_tmp0_ = TRUE;
	} else {
		ClutterActor* _tmp1_;
		_tmp1_ = gala_drag_drop_action_grabbed_actor;
		_tmp0_ = _tmp1_ == NULL;
	}
	if (_tmp0_) {
		return;
	}
	_tmp2_ = self->priv->grab;
	if (_tmp2_ != NULL) {
		ClutterGrab* _tmp3_;
		_tmp3_ = self->priv->grab;
		clutter_grab_dismiss (_tmp3_);
		_clutter_grab_unref0 (self->priv->grab);
		self->priv->grab = NULL;
	}
	_g_object_unref0 (self->priv->grabbed_device);
	self->priv->grabbed_device = NULL;
	_tmp4_ = gala_drag_drop_action_grabbed_actor;
	g_signal_handler_disconnect ((GObject*) _tmp4_, self->priv->on_event_id);
	self->priv->on_event_id = (gulong) 0;
	gala_drag_drop_action_grabbed_actor = NULL;
}

static gboolean
gala_drag_drop_action_on_event (GalaDragDropAction* self,
                                ClutterEvent* event)
{
	ClutterInputDevice* device = NULL;
	ClutterInputDevice* _tmp0_;
	ClutterInputDevice* _tmp1_;
	gboolean _tmp2_ = FALSE;
	gboolean _tmp3_ = FALSE;
	ClutterInputDevice* _tmp4_;
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	g_return_val_if_fail (event != NULL, FALSE);
	_tmp0_ = clutter_event_get_device (event);
	_tmp1_ = _g_object_ref0 (_tmp0_);
	device = _tmp1_;
	_tmp4_ = self->priv->grabbed_device;
	if (_tmp4_ != NULL) {
		ClutterInputDevice* _tmp5_;
		ClutterInputDevice* _tmp6_;
		_tmp5_ = device;
		_tmp6_ = self->priv->grabbed_device;
		_tmp3_ = _tmp5_ != _tmp6_;
	} else {
		_tmp3_ = FALSE;
	}
	if (_tmp3_) {
		ClutterInputDevice* _tmp7_;
		_tmp7_ = device;
		_tmp2_ = clutter_input_device_get_device_type (_tmp7_) != CLUTTER_KEYBOARD_DEVICE;
	} else {
		_tmp2_ = FALSE;
	}
	if (_tmp2_) {
		result = FALSE;
		_g_object_unref0 (device);
		return result;
	}
	switch (clutter_event_type (event)) {
		case CLUTTER_KEY_PRESS:
		{
			if (clutter_event_get_key_symbol (event) == CLUTTER_KEY_Escape) {
				gala_drag_drop_action_cancel (self);
			}
			break;
		}
		case CLUTTER_MOTION:
		{
			gfloat x = 0.0F;
			gfloat y = 0.0F;
			gfloat _tmp8_ = 0.0F;
			gfloat _tmp9_ = 0.0F;
			gboolean _tmp10_ = FALSE;
			gboolean _tmp11_;
			clutter_event_get_coords (event, &_tmp8_, &_tmp9_);
			x = _tmp8_;
			y = _tmp9_;
			_tmp11_ = self->priv->_dragging;
			if (!_tmp11_) {
				_tmp10_ = self->priv->clicked;
			} else {
				_tmp10_ = FALSE;
			}
			if (_tmp10_) {
				gint drag_threshold = 0;
				ClutterSettings* _tmp12_;
				gint _tmp13_;
				gint _tmp14_;
				gboolean _tmp15_ = FALSE;
				_tmp12_ = clutter_settings_get_default ();
				g_object_get (_tmp12_, "dnd-drag-threshold", &_tmp13_, NULL);
				_tmp14_ = _tmp13_;
				drag_threshold = _tmp14_;
				if (fabsf (self->priv->last_x - x) > ((gfloat) drag_threshold)) {
					_tmp15_ = TRUE;
				} else {
					_tmp15_ = fabsf (self->priv->last_y - y) > ((gfloat) drag_threshold);
				}
				if (_tmp15_) {
					ClutterActor* _tmp16_ = NULL;
					ClutterActor* _tmp17_;
					ClutterActor* _tmp18_;
					ClutterActor* _tmp19_;
					ClutterInputDevice* _tmp20_;
					ClutterActor* _tmp21_;
					GeeLinkedList* source_list = NULL;
					GeeHashMap* _tmp22_;
					const gchar* _tmp23_;
					gpointer _tmp24_;
					GeeLinkedList* _tmp25_;
					g_signal_emit (self, gala_drag_drop_action_signals[GALA_DRAG_DROP_ACTION_DRAG_BEGIN_SIGNAL], 0, x, y, &_tmp16_);
					_tmp17_ = _tmp16_;
					gala_drag_drop_action_set_handle (self, _tmp17_);
					_g_object_unref0 (_tmp17_);
					_tmp18_ = self->priv->_handle;
					if (_tmp18_ == NULL) {
						gala_drag_drop_action_ungrab_actor (self);
						g_critical ("DragDropAction.vala:309: No handle has been returned by the started si" \
"gnal, aborting drag.");
						result = FALSE;
						_g_object_unref0 (device);
						return result;
					}
					self->priv->clicked = FALSE;
					gala_drag_drop_action_set_dragging (self, TRUE);
					gala_drag_drop_action_ungrab_actor (self);
					_tmp19_ = self->priv->_handle;
					_tmp20_ = clutter_event_get_device (event);
					gala_drag_drop_action_grab_actor (self, _tmp19_, _tmp20_);
					_tmp21_ = self->priv->_handle;
					clutter_actor_set_reactive (_tmp21_, FALSE);
					_tmp22_ = gala_drag_drop_action_sources;
					_tmp23_ = self->priv->_drag_id;
					_tmp24_ = gee_abstract_map_get ((GeeAbstractMap*) _tmp22_, _tmp23_);
					source_list = (GeeLinkedList*) _tmp24_;
					_tmp25_ = source_list;
					if (_tmp25_ != NULL) {
						GeeLinkedList* dest_list = NULL;
						GeeHashMap* _tmp26_;
						const gchar* _tmp27_;
						gpointer _tmp28_;
						_tmp26_ = gala_drag_drop_action_destinations;
						_tmp27_ = self->priv->_drag_id;
						_tmp28_ = gee_abstract_map_get ((GeeAbstractMap*) _tmp26_, _tmp27_);
						dest_list = (GeeLinkedList*) _tmp28_;
						{
							GeeLinkedList* _actor_list = NULL;
							GeeLinkedList* _tmp29_;
							gint _actor_size = 0;
							GeeLinkedList* _tmp30_;
							gint _tmp31_;
							gint _tmp32_;
							gint _actor_index = 0;
							_tmp29_ = source_list;
							_actor_list = _tmp29_;
							_tmp30_ = _actor_list;
							_tmp31_ = gee_abstract_collection_get_size ((GeeAbstractCollection*) _tmp30_);
							_tmp32_ = _tmp31_;
							_actor_size = _tmp32_;
							_actor_index = -1;
							while (TRUE) {
								gint _tmp33_;
								gint _tmp34_;
								ClutterActor* actor = NULL;
								GeeLinkedList* _tmp35_;
								gpointer _tmp36_;
								gboolean _tmp37_ = FALSE;
								GeeLinkedList* _tmp38_;
								ClutterActor* _tmp41_;
								_actor_index = _actor_index + 1;
								_tmp33_ = _actor_index;
								_tmp34_ = _actor_size;
								if (!(_tmp33_ < _tmp34_)) {
									break;
								}
								_tmp35_ = _actor_list;
								_tmp36_ = gee_abstract_list_get ((GeeAbstractList*) _tmp35_, _actor_index);
								actor = (ClutterActor*) _tmp36_;
								_tmp38_ = dest_list;
								if (_tmp38_ == NULL) {
									_tmp37_ = TRUE;
								} else {
									GeeLinkedList* _tmp39_;
									ClutterActor* _tmp40_;
									_tmp39_ = dest_list;
									_tmp40_ = actor;
									_tmp37_ = gee_abstract_collection_contains ((GeeAbstractCollection*) _tmp39_, _tmp40_);
								}
								if (_tmp37_) {
									_g_object_unref0 (actor);
									continue;
								}
								_tmp41_ = actor;
								clutter_actor_set_reactive (_tmp41_, FALSE);
								_g_object_unref0 (actor);
							}
						}
						_g_object_unref0 (dest_list);
					}
					_g_object_unref0 (source_list);
				}
				result = TRUE;
				_g_object_unref0 (device);
				return result;
			} else {
				gboolean _tmp42_;
				_tmp42_ = self->priv->_dragging;
				if (_tmp42_) {
					ClutterActor* _tmp43_;
					ClutterActor* _tmp44_;
					gfloat _tmp45_;
					gfloat _tmp46_;
					ClutterActor* _tmp47_;
					ClutterActor* _tmp48_;
					gfloat _tmp49_;
					gfloat _tmp50_;
					ClutterStage* stage = NULL;
					ClutterActor* _tmp51_;
					ClutterActor* _tmp52_;
					ClutterStage* _tmp53_;
					ClutterStage* _tmp54_;
					ClutterActor* actor = NULL;
					ClutterStage* _tmp55_;
					ClutterActor* _tmp56_;
					ClutterActor* _tmp57_;
					GalaDragDropAction* action = NULL;
					gboolean _tmp58_ = FALSE;
					gboolean _tmp59_ = FALSE;
					ClutterActor* _tmp60_;
					ClutterActor* _tmp73_;
					ClutterActor* _tmp74_;
					GalaDragDropAction* _tmp75_;
					ClutterActor* _tmp78_;
					ClutterActor* _tmp80_;
					ClutterActor* _tmp81_;
					_tmp43_ = self->priv->_handle;
					_tmp44_ = self->priv->_handle;
					_tmp45_ = clutter_actor_get_x (_tmp44_);
					_tmp46_ = _tmp45_;
					clutter_actor_set_x (_tmp44_, _tmp46_ - (self->priv->last_x - x));
					_tmp47_ = self->priv->_handle;
					_tmp48_ = self->priv->_handle;
					_tmp49_ = clutter_actor_get_y (_tmp48_);
					_tmp50_ = _tmp49_;
					clutter_actor_set_y (_tmp48_, _tmp50_ - (self->priv->last_y - y));
					self->priv->last_x = x;
					self->priv->last_y = y;
					_tmp51_ = clutter_actor_meta_get_actor ((ClutterActorMeta*) self);
					_tmp52_ = _tmp51_;
					_tmp53_ = clutter_actor_get_stage (_tmp52_);
					_tmp54_ = _g_object_ref0 (_tmp53_);
					stage = _tmp54_;
					_tmp55_ = stage;
					_tmp56_ = clutter_stage_get_actor_at_pos (_tmp55_, CLUTTER_PICK_REACTIVE, (gfloat) ((gint) x), (gfloat) ((gint) y));
					_tmp57_ = _g_object_ref0 (_tmp56_);
					actor = _tmp57_;
					action = NULL;
					_tmp60_ = actor;
					if (_tmp60_ != NULL) {
						ClutterActor* _tmp61_;
						GalaDragDropAction* _tmp62_;
						GalaDragDropAction* _tmp63_;
						_tmp61_ = actor;
						_tmp62_ = gala_drag_drop_action_get_drag_drop_action (self, _tmp61_);
						_g_object_unref0 (action);
						action = _tmp62_;
						_tmp63_ = action;
						_tmp59_ = _tmp63_ == NULL;
					} else {
						_tmp59_ = FALSE;
					}
					if (_tmp59_) {
						gboolean _tmp64_;
						_tmp64_ = self->priv->_allow_bubbling;
						_tmp58_ = _tmp64_;
					} else {
						_tmp58_ = FALSE;
					}
					if (_tmp58_) {
						while (TRUE) {
							ClutterActor* _tmp65_;
							ClutterActor* _tmp66_;
							ClutterActor* _tmp67_;
							ClutterActor* _tmp68_;
							ClutterStage* _tmp69_;
							ClutterActor* _tmp70_;
							GalaDragDropAction* _tmp71_;
							GalaDragDropAction* _tmp72_;
							_tmp65_ = actor;
							_tmp66_ = clutter_actor_get_parent (_tmp65_);
							_tmp67_ = _g_object_ref0 (_tmp66_);
							_g_object_unref0 (actor);
							actor = _tmp67_;
							_tmp68_ = actor;
							_tmp69_ = stage;
							if (!(_tmp68_ != G_TYPE_CHECK_INSTANCE_CAST (_tmp69_, clutter_actor_get_type (), ClutterActor))) {
								break;
							}
							_tmp70_ = actor;
							_tmp71_ = gala_drag_drop_action_get_drag_drop_action (self, _tmp70_);
							_g_object_unref0 (action);
							action = _tmp71_;
							_tmp72_ = action;
							if (_tmp72_ != NULL) {
								break;
							}
						}
					}
					_tmp73_ = actor;
					_tmp74_ = self->priv->_hovered;
					if (_tmp73_ == _tmp74_) {
						result = TRUE;
						_g_object_unref0 (action);
						_g_object_unref0 (actor);
						_g_object_unref0 (stage);
						_g_object_unref0 (device);
						return result;
					}
					_tmp75_ = action;
					if (_tmp75_ == NULL) {
						ClutterActor* _tmp76_;
						_tmp76_ = self->priv->_hovered;
						if (_tmp76_ != NULL) {
							ClutterActor* _tmp77_;
							_tmp77_ = self->priv->_hovered;
							gala_drag_drop_action_emit_crossed (self, _tmp77_, FALSE);
							gala_drag_drop_action_set_hovered (self, NULL);
						}
						result = TRUE;
						_g_object_unref0 (action);
						_g_object_unref0 (actor);
						_g_object_unref0 (stage);
						_g_object_unref0 (device);
						return result;
					}
					_tmp78_ = self->priv->_hovered;
					if (_tmp78_ != NULL) {
						ClutterActor* _tmp79_;
						_tmp79_ = self->priv->_hovered;
						gala_drag_drop_action_emit_crossed (self, _tmp79_, FALSE);
					}
					_tmp80_ = actor;
					gala_drag_drop_action_set_hovered (self, _tmp80_);
					_tmp81_ = self->priv->_hovered;
					gala_drag_drop_action_emit_crossed (self, _tmp81_, TRUE);
					result = TRUE;
					_g_object_unref0 (action);
					_g_object_unref0 (actor);
					_g_object_unref0 (stage);
					_g_object_unref0 (device);
					return result;
				}
			}
			break;
		}
		default:
		break;
	}
	result = FALSE;
	_g_object_unref0 (device);
	return result;
}

/**
         * Looks for a DragDropAction instance if this actor has one or NULL.
         * It also checks if it is a DESTINATION and if the id matches
         *
         * @return the DragDropAction instance on this actor or NULL
         */
static GalaDragDropAction*
gala_drag_drop_action_get_drag_drop_action (GalaDragDropAction* self,
                                            ClutterActor* actor)
{
	GalaDragDropAction* drop_action = NULL;
	GList* _tmp0_;
	GalaDragDropAction* result;
	g_return_val_if_fail (self != NULL, NULL);
	g_return_val_if_fail (actor != NULL, NULL);
	drop_action = NULL;
	_tmp0_ = clutter_actor_get_actions (actor);
	{
		GList* action_collection = NULL;
		GList* action_it = NULL;
		action_collection = _tmp0_;
		for (action_it = action_collection; action_it != NULL; action_it = action_it->next) {
			ClutterAction* action = NULL;
			action = (ClutterAction*) action_it->data;
			{
				ClutterAction* _tmp1_;
				GalaDragDropAction* _tmp2_;
				gboolean _tmp3_ = FALSE;
				gboolean _tmp4_ = FALSE;
				GalaDragDropAction* _tmp5_;
				_tmp1_ = action;
				_tmp2_ = _g_object_ref0 (GALA_IS_DRAG_DROP_ACTION (_tmp1_) ? ((GalaDragDropAction*) _tmp1_) : NULL);
				_g_object_unref0 (drop_action);
				drop_action = _tmp2_;
				_tmp5_ = drop_action;
				if (_tmp5_ == NULL) {
					_tmp4_ = TRUE;
				} else {
					GalaDragDropAction* _tmp6_;
					GalaDragDropActionType _tmp7_;
					_tmp6_ = drop_action;
					_tmp7_ = _tmp6_->priv->_drag_type;
					_tmp4_ = !((_tmp7_ & GALA_DRAG_DROP_ACTION_TYPE_DESTINATION) == GALA_DRAG_DROP_ACTION_TYPE_DESTINATION);
				}
				if (_tmp4_) {
					_tmp3_ = TRUE;
				} else {
					GalaDragDropAction* _tmp8_;
					const gchar* _tmp9_;
					const gchar* _tmp10_;
					_tmp8_ = drop_action;
					_tmp9_ = _tmp8_->priv->_drag_id;
					_tmp10_ = self->priv->_drag_id;
					_tmp3_ = g_strcmp0 (_tmp9_, _tmp10_) != 0;
				}
				if (_tmp3_) {
					continue;
				}
				result = drop_action;
				(action_collection == NULL) ? NULL : (action_collection = (g_list_free (action_collection), NULL));
				return result;
			}
		}
		(action_collection == NULL) ? NULL : (action_collection = (g_list_free (action_collection), NULL));
	}
	result = NULL;
	_g_object_unref0 (drop_action);
	return result;
}

/**
         * Abort the drag
         */
void
gala_drag_drop_action_cancel (GalaDragDropAction* self)
{
	g_return_if_fail (self != NULL);
	gala_drag_drop_action_cleanup (self);
	g_signal_emit (self, gala_drag_drop_action_signals[GALA_DRAG_DROP_ACTION_DRAG_CANCELED_SIGNAL], 0);
}

/**
         * Allows you to abort all drags currently running for a given drag-id
         */
void
gala_drag_drop_action_cancel_all_by_id (const gchar* id)
{
	GeeLinkedList* actors = NULL;
	GeeHashMap* _tmp0_;
	gpointer _tmp1_;
	GeeLinkedList* _tmp2_;
	g_return_if_fail (id != NULL);
	_tmp0_ = gala_drag_drop_action_sources;
	_tmp1_ = gee_abstract_map_get ((GeeAbstractMap*) _tmp0_, id);
	actors = (GeeLinkedList*) _tmp1_;
	_tmp2_ = actors;
	if (_tmp2_ == NULL) {
		_g_object_unref0 (actors);
		return;
	}
	{
		GeeLinkedList* _actor_list = NULL;
		GeeLinkedList* _tmp3_;
		gint _actor_size = 0;
		GeeLinkedList* _tmp4_;
		gint _tmp5_;
		gint _tmp6_;
		gint _actor_index = 0;
		_tmp3_ = actors;
		_actor_list = _tmp3_;
		_tmp4_ = _actor_list;
		_tmp5_ = gee_abstract_collection_get_size ((GeeAbstractCollection*) _tmp4_);
		_tmp6_ = _tmp5_;
		_actor_size = _tmp6_;
		_actor_index = -1;
		while (TRUE) {
			gint _tmp7_;
			gint _tmp8_;
			ClutterActor* actor = NULL;
			GeeLinkedList* _tmp9_;
			gpointer _tmp10_;
			ClutterActor* _tmp11_;
			GList* _tmp12_;
			_actor_index = _actor_index + 1;
			_tmp7_ = _actor_index;
			_tmp8_ = _actor_size;
			if (!(_tmp7_ < _tmp8_)) {
				break;
			}
			_tmp9_ = _actor_list;
			_tmp10_ = gee_abstract_list_get ((GeeAbstractList*) _tmp9_, _actor_index);
			actor = (ClutterActor*) _tmp10_;
			_tmp11_ = actor;
			_tmp12_ = clutter_actor_get_actions (_tmp11_);
			{
				GList* action_collection = NULL;
				GList* action_it = NULL;
				action_collection = _tmp12_;
				for (action_it = action_collection; action_it != NULL; action_it = action_it->next) {
					ClutterAction* action = NULL;
					action = (ClutterAction*) action_it->data;
					{
						GalaDragDropAction* drag_action = NULL;
						ClutterAction* _tmp13_;
						GalaDragDropAction* _tmp14_;
						gboolean _tmp15_ = FALSE;
						GalaDragDropAction* _tmp16_;
						_tmp13_ = action;
						_tmp14_ = _g_object_ref0 (GALA_IS_DRAG_DROP_ACTION (_tmp13_) ? ((GalaDragDropAction*) _tmp13_) : NULL);
						drag_action = _tmp14_;
						_tmp16_ = drag_action;
						if (_tmp16_ != NULL) {
							GalaDragDropAction* _tmp17_;
							gboolean _tmp18_;
							_tmp17_ = drag_action;
							_tmp18_ = _tmp17_->priv->_dragging;
							_tmp15_ = _tmp18_;
						} else {
							_tmp15_ = FALSE;
						}
						if (_tmp15_) {
							GalaDragDropAction* _tmp19_;
							_tmp19_ = drag_action;
							gala_drag_drop_action_cancel (_tmp19_);
							_g_object_unref0 (drag_action);
							break;
						}
						_g_object_unref0 (drag_action);
					}
				}
				(action_collection == NULL) ? NULL : (action_collection = (g_list_free (action_collection), NULL));
			}
			_g_object_unref0 (actor);
		}
	}
	_g_object_unref0 (actors);
}

static void
gala_drag_drop_action_finish (GalaDragDropAction* self)
{
	ClutterActor* _tmp0_;
	ClutterActor* _tmp1_;
	g_return_if_fail (self != NULL);
	_tmp0_ = self->priv->_hovered;
	gala_drag_drop_action_emit_crossed (self, _tmp0_, FALSE);
	gala_drag_drop_action_cleanup (self);
	_tmp1_ = self->priv->_hovered;
	g_signal_emit (self, gala_drag_drop_action_signals[GALA_DRAG_DROP_ACTION_DRAG_END_SIGNAL], 0, _tmp1_);
}

static void
gala_drag_drop_action_cleanup (GalaDragDropAction* self)
{
	GeeLinkedList* source_list = NULL;
	GeeHashMap* _tmp0_;
	const gchar* _tmp1_;
	gpointer _tmp2_;
	GeeLinkedList* _tmp3_;
	gboolean _tmp13_;
	g_return_if_fail (self != NULL);
	_tmp0_ = gala_drag_drop_action_sources;
	_tmp1_ = self->priv->_drag_id;
	_tmp2_ = gee_abstract_map_get ((GeeAbstractMap*) _tmp0_, _tmp1_);
	source_list = (GeeLinkedList*) _tmp2_;
	_tmp3_ = source_list;
	if (_tmp3_ != NULL) {
		{
			GeeLinkedList* _actor_list = NULL;
			GeeLinkedList* _tmp4_;
			gint _actor_size = 0;
			GeeLinkedList* _tmp5_;
			gint _tmp6_;
			gint _tmp7_;
			gint _actor_index = 0;
			_tmp4_ = source_list;
			_actor_list = _tmp4_;
			_tmp5_ = _actor_list;
			_tmp6_ = gee_abstract_collection_get_size ((GeeAbstractCollection*) _tmp5_);
			_tmp7_ = _tmp6_;
			_actor_size = _tmp7_;
			_actor_index = -1;
			while (TRUE) {
				gint _tmp8_;
				gint _tmp9_;
				ClutterActor* actor = NULL;
				GeeLinkedList* _tmp10_;
				gpointer _tmp11_;
				ClutterActor* _tmp12_;
				_actor_index = _actor_index + 1;
				_tmp8_ = _actor_index;
				_tmp9_ = _actor_size;
				if (!(_tmp8_ < _tmp9_)) {
					break;
				}
				_tmp10_ = _actor_list;
				_tmp11_ = gee_abstract_list_get ((GeeAbstractList*) _tmp10_, _actor_index);
				actor = (ClutterActor*) _tmp11_;
				_tmp12_ = actor;
				clutter_actor_set_reactive (_tmp12_, TRUE);
				_g_object_unref0 (actor);
			}
		}
	}
	_tmp13_ = self->priv->_dragging;
	if (_tmp13_) {
		gala_drag_drop_action_ungrab_actor (self);
	}
	gala_drag_drop_action_set_dragging (self, FALSE);
	_g_object_unref0 (source_list);
}

GalaDragDropActionType
gala_drag_drop_action_get_drag_type (GalaDragDropAction* self)
{
	GalaDragDropActionType result;
	g_return_val_if_fail (self != NULL, 0U);
	result = self->priv->_drag_type;
	return result;
}

static void
gala_drag_drop_action_set_drag_type (GalaDragDropAction* self,
                                     GalaDragDropActionType value)
{
	GalaDragDropActionType old_value;
	g_return_if_fail (self != NULL);
	old_value = gala_drag_drop_action_get_drag_type (self);
	if (old_value != value) {
		self->priv->_drag_type = value;
		g_object_notify_by_pspec ((GObject *) self, gala_drag_drop_action_properties[GALA_DRAG_DROP_ACTION_DRAG_TYPE_PROPERTY]);
	}
}

const gchar*
gala_drag_drop_action_get_drag_id (GalaDragDropAction* self)
{
	const gchar* result;
	const gchar* _tmp0_;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = self->priv->_drag_id;
	result = _tmp0_;
	return result;
}

static void
gala_drag_drop_action_set_drag_id (GalaDragDropAction* self,
                                   const gchar* value)
{
	gchar* old_value;
	g_return_if_fail (self != NULL);
	old_value = gala_drag_drop_action_get_drag_id (self);
	if (g_strcmp0 (value, old_value) != 0) {
		gchar* _tmp0_;
		_tmp0_ = g_strdup (value);
		_g_free0 (self->priv->_drag_id);
		self->priv->_drag_id = _tmp0_;
		g_object_notify_by_pspec ((GObject *) self, gala_drag_drop_action_properties[GALA_DRAG_DROP_ACTION_DRAG_ID_PROPERTY]);
	}
}

ClutterActor*
gala_drag_drop_action_get_handle (GalaDragDropAction* self)
{
	ClutterActor* result;
	ClutterActor* _tmp0_;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = self->priv->_handle;
	result = _tmp0_;
	return result;
}

static void
gala_drag_drop_action_set_handle (GalaDragDropAction* self,
                                  ClutterActor* value)
{
	ClutterActor* old_value;
	g_return_if_fail (self != NULL);
	old_value = gala_drag_drop_action_get_handle (self);
	if (old_value != value) {
		ClutterActor* _tmp0_;
		_tmp0_ = _g_object_ref0 (value);
		_g_object_unref0 (self->priv->_handle);
		self->priv->_handle = _tmp0_;
		g_object_notify_by_pspec ((GObject *) self, gala_drag_drop_action_properties[GALA_DRAG_DROP_ACTION_HANDLE_PROPERTY]);
	}
}

gboolean
gala_drag_drop_action_get_dragging (GalaDragDropAction* self)
{
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	result = self->priv->_dragging;
	return result;
}

static void
gala_drag_drop_action_set_dragging (GalaDragDropAction* self,
                                    gboolean value)
{
	gboolean old_value;
	g_return_if_fail (self != NULL);
	old_value = gala_drag_drop_action_get_dragging (self);
	if (old_value != value) {
		self->priv->_dragging = value;
		g_object_notify_by_pspec ((GObject *) self, gala_drag_drop_action_properties[GALA_DRAG_DROP_ACTION_DRAGGING_PROPERTY]);
	}
}

gboolean
gala_drag_drop_action_get_allow_bubbling (GalaDragDropAction* self)
{
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	result = self->priv->_allow_bubbling;
	return result;
}

void
gala_drag_drop_action_set_allow_bubbling (GalaDragDropAction* self,
                                          gboolean value)
{
	gboolean old_value;
	g_return_if_fail (self != NULL);
	old_value = gala_drag_drop_action_get_allow_bubbling (self);
	if (old_value != value) {
		self->priv->_allow_bubbling = value;
		g_object_notify_by_pspec ((GObject *) self, gala_drag_drop_action_properties[GALA_DRAG_DROP_ACTION_ALLOW_BUBBLING_PROPERTY]);
	}
}

static ClutterActor*
gala_drag_drop_action_get_hovered (GalaDragDropAction* self)
{
	ClutterActor* result;
	ClutterActor* _tmp0_;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = self->priv->_hovered;
	result = _tmp0_;
	return result;
}

void
gala_drag_drop_action_set_hovered (GalaDragDropAction* self,
                                   ClutterActor* value)
{
	ClutterActor* old_value;
	g_return_if_fail (self != NULL);
	old_value = gala_drag_drop_action_get_hovered (self);
	if (old_value != value) {
		ClutterActor* _tmp0_;
		_tmp0_ = _g_object_ref0 (value);
		_g_object_unref0 (self->priv->_hovered);
		self->priv->_hovered = _tmp0_;
		g_object_notify_by_pspec ((GObject *) self, gala_drag_drop_action_properties[GALA_DRAG_DROP_ACTION_HOVERED_PROPERTY]);
	}
}

static void
g_cclosure_user_marshal_OBJECT__FLOAT_FLOAT (GClosure * closure,
                                             GValue * return_value,
                                             guint n_param_values,
                                             const GValue * param_values,
                                             gpointer invocation_hint,
                                             gpointer marshal_data)
{
	typedef gpointer (*GMarshalFunc_OBJECT__FLOAT_FLOAT) (gpointer data1, gfloat arg_1, gfloat arg_2, gpointer data2);
	register GMarshalFunc_OBJECT__FLOAT_FLOAT callback;
	register GCClosure * cc;
	register gpointer data1;
	register gpointer data2;
	gpointer v_return;
	cc = (GCClosure *) closure;
	g_return_if_fail (return_value != NULL);
	g_return_if_fail (n_param_values == 3);
	if (G_CCLOSURE_SWAP_DATA (closure)) {
		data1 = closure->data;
		data2 = param_values->data[0].v_pointer;
	} else {
		data1 = param_values->data[0].v_pointer;
		data2 = closure->data;
	}
	callback = (GMarshalFunc_OBJECT__FLOAT_FLOAT) (marshal_data ? marshal_data : cc->callback);
	v_return = callback (data1, g_value_get_float (param_values + 1), g_value_get_float (param_values + 2), data2);
	g_value_take_object (return_value, v_return);
}

static void
g_cclosure_user_marshal_VOID__OBJECT_BOOLEAN (GClosure * closure,
                                              GValue * return_value,
                                              guint n_param_values,
                                              const GValue * param_values,
                                              gpointer invocation_hint,
                                              gpointer marshal_data)
{
	typedef void (*GMarshalFunc_VOID__OBJECT_BOOLEAN) (gpointer data1, gpointer arg_1, gboolean arg_2, gpointer data2);
	register GMarshalFunc_VOID__OBJECT_BOOLEAN callback;
	register GCClosure * cc;
	register gpointer data1;
	register gpointer data2;
	cc = (GCClosure *) closure;
	g_return_if_fail (n_param_values == 3);
	if (G_CCLOSURE_SWAP_DATA (closure)) {
		data1 = closure->data;
		data2 = param_values->data[0].v_pointer;
	} else {
		data1 = param_values->data[0].v_pointer;
		data2 = closure->data;
	}
	callback = (GMarshalFunc_VOID__OBJECT_BOOLEAN) (marshal_data ? marshal_data : cc->callback);
	callback (data1, g_value_get_object (param_values + 1), g_value_get_boolean (param_values + 2), data2);
}

static void
gala_drag_drop_action_class_init (GalaDragDropActionClass * klass,
                                  gpointer klass_data)
{
	gala_drag_drop_action_parent_class = g_type_class_peek_parent (klass);
	g_type_class_adjust_private_offset (klass, &GalaDragDropAction_private_offset);
	((ClutterActorMetaClass *) klass)->set_actor = (void (*) (ClutterActorMeta*, ClutterActor*)) gala_drag_drop_action_real_set_actor;
	((ClutterActionClass *) klass)->handle_event = (gboolean (*) (ClutterAction*, ClutterEvent*)) gala_drag_drop_action_real_handle_event;
	G_OBJECT_CLASS (klass)->get_property = _vala_gala_drag_drop_action_get_property;
	G_OBJECT_CLASS (klass)->set_property = _vala_gala_drag_drop_action_set_property;
	G_OBJECT_CLASS (klass)->finalize = gala_drag_drop_action_finalize;
	/**
	         * The type of the action
	         */
	g_object_class_install_property (G_OBJECT_CLASS (klass), GALA_DRAG_DROP_ACTION_DRAG_TYPE_PROPERTY, gala_drag_drop_action_properties[GALA_DRAG_DROP_ACTION_DRAG_TYPE_PROPERTY] = g_param_spec_flags ("drag-type", "drag-type", "drag-type", GALA_TYPE_DRAG_DROP_ACTION_TYPE, 0U, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY));
	/**
	         * The unique id given to this drag-drop-group
	         */
	g_object_class_install_property (G_OBJECT_CLASS (klass), GALA_DRAG_DROP_ACTION_DRAG_ID_PROPERTY, gala_drag_drop_action_properties[GALA_DRAG_DROP_ACTION_DRAG_ID_PROPERTY] = g_param_spec_string ("drag-id", "drag-id", "drag-id", NULL, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY));
	g_object_class_install_property (G_OBJECT_CLASS (klass), GALA_DRAG_DROP_ACTION_HANDLE_PROPERTY, gala_drag_drop_action_properties[GALA_DRAG_DROP_ACTION_HANDLE_PROPERTY] = g_param_spec_object ("handle", "handle", "handle", clutter_actor_get_type (), G_PARAM_STATIC_STRINGS | G_PARAM_READABLE));
	/**
	         * Indicates whether a drag action is currently active
	         */
	g_object_class_install_property (G_OBJECT_CLASS (klass), GALA_DRAG_DROP_ACTION_DRAGGING_PROPERTY, gala_drag_drop_action_properties[GALA_DRAG_DROP_ACTION_DRAGGING_PROPERTY] = g_param_spec_boolean ("dragging", "dragging", "dragging", FALSE, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE));
	/**
	         * Allow checking the parents of reactive children if they are valid destinations
	         * if the child is none
	         */
	g_object_class_install_property (G_OBJECT_CLASS (klass), GALA_DRAG_DROP_ACTION_ALLOW_BUBBLING_PROPERTY, gala_drag_drop_action_properties[GALA_DRAG_DROP_ACTION_ALLOW_BUBBLING_PROPERTY] = g_param_spec_boolean ("allow-bubbling", "allow-bubbling", "allow-bubbling", TRUE, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE | G_PARAM_WRITABLE));
	g_object_class_install_property (G_OBJECT_CLASS (klass), GALA_DRAG_DROP_ACTION_HOVERED_PROPERTY, gala_drag_drop_action_properties[GALA_DRAG_DROP_ACTION_HOVERED_PROPERTY] = g_param_spec_object ("hovered", "hovered", "hovered", clutter_actor_get_type (), G_PARAM_STATIC_STRINGS | G_PARAM_WRITABLE));
	/**
	         * A drag has been started. You have to connect to this signal and
	         * return an actor that is transformed during the drag operation.
	         *
	         * @param x The global x coordinate where the action was activated
	         * @param y The global y coordinate where the action was activated
	         * @return  A ClutterActor that serves as handle
	         */
	gala_drag_drop_action_signals[GALA_DRAG_DROP_ACTION_DRAG_BEGIN_SIGNAL] = g_signal_new ("drag-begin", GALA_TYPE_DRAG_DROP_ACTION, G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_user_marshal_OBJECT__FLOAT_FLOAT, clutter_actor_get_type (), 2, G_TYPE_FLOAT, G_TYPE_FLOAT);
	/**
	         * A drag has been canceled. You may want to consider cleaning up
	         * your handle.
	         */
	gala_drag_drop_action_signals[GALA_DRAG_DROP_ACTION_DRAG_CANCELED_SIGNAL] = g_signal_new ("drag-canceled", GALA_TYPE_DRAG_DROP_ACTION, G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
	/**
	         * A drag action has successfully been finished.
	         *
	         * @param actor The actor on which the drag finished
	         */
	gala_drag_drop_action_signals[GALA_DRAG_DROP_ACTION_DRAG_END_SIGNAL] = g_signal_new ("drag-end", GALA_TYPE_DRAG_DROP_ACTION, G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_marshal_VOID__OBJECT, G_TYPE_NONE, 1, clutter_actor_get_type ());
	/**
	         * The destination has been crossed
	         *
	         * @param target the target actor that is crossing the destination
	         * @param hovered indicates whether the actor is now hovered or not
	         */
	gala_drag_drop_action_signals[GALA_DRAG_DROP_ACTION_CROSSED_SIGNAL] = g_signal_new ("crossed", GALA_TYPE_DRAG_DROP_ACTION, G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_user_marshal_VOID__OBJECT_BOOLEAN, G_TYPE_NONE, 2, clutter_actor_get_type (), G_TYPE_BOOLEAN);
	/**
	         * Emitted on the source when a destination is crossed.
	         *
	         * @param destination The destination actor that has been crossed
	         * @param hovered     Whether the actor is now hovered or has just been left
	         */
	gala_drag_drop_action_signals[GALA_DRAG_DROP_ACTION_DESTINATION_CROSSED_SIGNAL] = g_signal_new ("destination-crossed", GALA_TYPE_DRAG_DROP_ACTION, G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_user_marshal_VOID__OBJECT_BOOLEAN, G_TYPE_NONE, 2, clutter_actor_get_type (), G_TYPE_BOOLEAN);
	/**
	         * The source has been clicked, but the movement was not larger than
	         * the drag threshold. Useful if the source is also activable.
	         *
	         * @param button The button which was pressed
	         */
	gala_drag_drop_action_signals[GALA_DRAG_DROP_ACTION_ACTOR_CLICKED_SIGNAL] = g_signal_new ("actor-clicked", GALA_TYPE_DRAG_DROP_ACTION, G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_marshal_VOID__UINT, G_TYPE_NONE, 1, G_TYPE_UINT);
}

static void
gala_drag_drop_action_instance_init (GalaDragDropAction * self,
                                     gpointer klass)
{
	self->priv = gala_drag_drop_action_get_instance_private (self);
	self->priv->_dragging = FALSE;
	self->priv->_allow_bubbling = TRUE;
	self->priv->_hovered = NULL;
	self->priv->clicked = FALSE;
	self->priv->grab = NULL;
	self->priv->grabbed_device = NULL;
	self->priv->on_event_id = (gulong) 0;
}

static void
gala_drag_drop_action_finalize (GObject * obj)
{
	GalaDragDropAction * self;
	ClutterActor* _tmp0_;
	ClutterActor* _tmp1_;
	self = G_TYPE_CHECK_INSTANCE_CAST (obj, GALA_TYPE_DRAG_DROP_ACTION, GalaDragDropAction);
	_tmp0_ = clutter_actor_meta_get_actor ((ClutterActorMeta*) self);
	_tmp1_ = _tmp0_;
	if (_tmp1_ != NULL) {
		ClutterActor* _tmp2_;
		ClutterActor* _tmp3_;
		_tmp2_ = clutter_actor_meta_get_actor ((ClutterActorMeta*) self);
		_tmp3_ = _tmp2_;
		gala_drag_drop_action_release_actor (self, _tmp3_);
	}
	_g_free0 (self->priv->_drag_id);
	_g_object_unref0 (self->priv->_handle);
	_g_object_unref0 (self->priv->_hovered);
	_clutter_grab_unref0 (self->priv->grab);
	_g_object_unref0 (self->priv->grabbed_device);
	G_OBJECT_CLASS (gala_drag_drop_action_parent_class)->finalize (obj);
}

static GType
gala_drag_drop_action_get_type_once (void)
{
	static const GTypeInfo g_define_type_info = { sizeof (GalaDragDropActionClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) gala_drag_drop_action_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (GalaDragDropAction), 0, (GInstanceInitFunc) gala_drag_drop_action_instance_init, NULL };
	GType gala_drag_drop_action_type_id;
	gala_drag_drop_action_type_id = g_type_register_static (clutter_action_get_type (), "GalaDragDropAction", &g_define_type_info, 0);
	GalaDragDropAction_private_offset = g_type_add_instance_private (gala_drag_drop_action_type_id, sizeof (GalaDragDropActionPrivate));
	return gala_drag_drop_action_type_id;
}

GType
gala_drag_drop_action_get_type (void)
{
	static volatile gsize gala_drag_drop_action_type_id__once = 0;
	if (g_once_init_enter (&gala_drag_drop_action_type_id__once)) {
		GType gala_drag_drop_action_type_id;
		gala_drag_drop_action_type_id = gala_drag_drop_action_get_type_once ();
		g_once_init_leave (&gala_drag_drop_action_type_id__once, gala_drag_drop_action_type_id);
	}
	return gala_drag_drop_action_type_id__once;
}

static void
_vala_gala_drag_drop_action_get_property (GObject * object,
                                          guint property_id,
                                          GValue * value,
                                          GParamSpec * pspec)
{
	GalaDragDropAction * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (object, GALA_TYPE_DRAG_DROP_ACTION, GalaDragDropAction);
	switch (property_id) {
		case GALA_DRAG_DROP_ACTION_DRAG_TYPE_PROPERTY:
		g_value_set_flags (value, gala_drag_drop_action_get_drag_type (self));
		break;
		case GALA_DRAG_DROP_ACTION_DRAG_ID_PROPERTY:
		g_value_set_string (value, gala_drag_drop_action_get_drag_id (self));
		break;
		case GALA_DRAG_DROP_ACTION_HANDLE_PROPERTY:
		g_value_set_object (value, gala_drag_drop_action_get_handle (self));
		break;
		case GALA_DRAG_DROP_ACTION_DRAGGING_PROPERTY:
		g_value_set_boolean (value, gala_drag_drop_action_get_dragging (self));
		break;
		case GALA_DRAG_DROP_ACTION_ALLOW_BUBBLING_PROPERTY:
		g_value_set_boolean (value, gala_drag_drop_action_get_allow_bubbling (self));
		break;
		case GALA_DRAG_DROP_ACTION_HOVERED_PROPERTY:
		g_value_set_object (value, gala_drag_drop_action_get_hovered (self));
		break;
		default:
		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
		break;
	}
}

static void
_vala_gala_drag_drop_action_set_property (GObject * object,
                                          guint property_id,
                                          const GValue * value,
                                          GParamSpec * pspec)
{
	GalaDragDropAction * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (object, GALA_TYPE_DRAG_DROP_ACTION, GalaDragDropAction);
	switch (property_id) {
		case GALA_DRAG_DROP_ACTION_DRAG_TYPE_PROPERTY:
		gala_drag_drop_action_set_drag_type (self, g_value_get_flags (value));
		break;
		case GALA_DRAG_DROP_ACTION_DRAG_ID_PROPERTY:
		gala_drag_drop_action_set_drag_id (self, g_value_get_string (value));
		break;
		case GALA_DRAG_DROP_ACTION_HANDLE_PROPERTY:
		gala_drag_drop_action_set_handle (self, g_value_get_object (value));
		break;
		case GALA_DRAG_DROP_ACTION_DRAGGING_PROPERTY:
		gala_drag_drop_action_set_dragging (self, g_value_get_boolean (value));
		break;
		case GALA_DRAG_DROP_ACTION_ALLOW_BUBBLING_PROPERTY:
		gala_drag_drop_action_set_allow_bubbling (self, g_value_get_boolean (value));
		break;
		case GALA_DRAG_DROP_ACTION_HOVERED_PROPERTY:
		gala_drag_drop_action_set_hovered (self, g_value_get_object (value));
		break;
		default:
		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
		break;
	}
}

