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

/**/
/*  Copyright (C) 2013 Tom Beckmann, Rico Tzschichholz*/
/**/
/*  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 <glib-object.h>
#include "gala.h"
#include <glib.h>
#include <float.h>
#include <math.h>
#include <meta/display.h>
#include <meta/meta-plugin.h>
#include <gio/gio.h>
#include "config.h"
#include <meta/prefs.h>
#include <meta/window.h>
#include <clutter/clutter.h>
#include <meta/keybindings.h>
#include <gdk/gdk.h>
#include <stdlib.h>
#include <string.h>
#include <graphene-gobject.h>

#define GALA_ZOOM_MIN_ZOOM 1.0f
#define GALA_ZOOM_MAX_ZOOM 10.0f
#define GALA_ZOOM_SHORTCUT_DELTA 0.5f
#define GALA_ZOOM_ANIMATION_DURATION 300
#define GALA_ZOOM_MOUSE_POLL_TIME ((guint) 50)
#if !defined(VALA_EXTERN)
#if defined(_MSC_VER)
#define VALA_EXTERN __declspec(dllexport) extern
#elif __GNUC__ >= 4
#define VALA_EXTERN __attribute__((visibility("default"))) extern
#else
#define VALA_EXTERN extern
#endif
#endif

#define GALA_TYPE_ZOOM (gala_zoom_get_type ())
#define GALA_ZOOM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GALA_TYPE_ZOOM, GalaZoom))
#define GALA_ZOOM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GALA_TYPE_ZOOM, GalaZoomClass))
#define GALA_IS_ZOOM(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GALA_TYPE_ZOOM))
#define GALA_IS_ZOOM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GALA_TYPE_ZOOM))
#define GALA_ZOOM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GALA_TYPE_ZOOM, GalaZoomClass))

typedef struct _GalaZoom GalaZoom;
typedef struct _GalaZoomClass GalaZoomClass;
typedef struct _GalaZoomPrivate GalaZoomPrivate;

#define GALA_TYPE_GESTURE_TRACKER (gala_gesture_tracker_get_type ())
#define GALA_GESTURE_TRACKER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GALA_TYPE_GESTURE_TRACKER, GalaGestureTracker))
#define GALA_GESTURE_TRACKER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GALA_TYPE_GESTURE_TRACKER, GalaGestureTrackerClass))
#define GALA_IS_GESTURE_TRACKER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GALA_TYPE_GESTURE_TRACKER))
#define GALA_IS_GESTURE_TRACKER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GALA_TYPE_GESTURE_TRACKER))
#define GALA_GESTURE_TRACKER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GALA_TYPE_GESTURE_TRACKER, GalaGestureTrackerClass))

typedef struct _GalaGestureTracker GalaGestureTracker;
typedef struct _GalaGestureTrackerClass GalaGestureTrackerClass;
enum  {
	GALA_ZOOM_0_PROPERTY,
	GALA_ZOOM_WM_PROPERTY,
	GALA_ZOOM_NUM_PROPERTIES
};
static GParamSpec* gala_zoom_properties[GALA_ZOOM_NUM_PROPERTIES];
#define _g_object_unref0(var) ((var == NULL) ? NULL : (var = (g_object_unref (var), NULL)))

#define GALA_TYPE_GESTURE (gala_gesture_get_type ())
#define GALA_GESTURE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GALA_TYPE_GESTURE, GalaGesture))
#define GALA_GESTURE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GALA_TYPE_GESTURE, GalaGestureClass))
#define GALA_IS_GESTURE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GALA_TYPE_GESTURE))
#define GALA_IS_GESTURE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GALA_TYPE_GESTURE))
#define GALA_GESTURE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GALA_TYPE_GESTURE, GalaGestureClass))

typedef struct _GalaGesture GalaGesture;
typedef struct _GalaGestureClass GalaGestureClass;
typedef struct _GalaGesturePrivate GalaGesturePrivate;
typedef enum  {
	GALA_GESTURE_DIRECTION_UNKNOWN = 0,
	GALA_GESTURE_DIRECTION_UP = 1,
	GALA_GESTURE_DIRECTION_DOWN = 2,
	GALA_GESTURE_DIRECTION_LEFT = 3,
	GALA_GESTURE_DIRECTION_RIGHT = 4,
	GALA_GESTURE_DIRECTION_IN = 5,
	GALA_GESTURE_DIRECTION_OUT = 6
} GalaGestureDirection;

#define GALA_TYPE_GESTURE_DIRECTION (gala_gesture_direction_get_type ())
#define _g_free0(var) (var = (g_free (var), NULL))
typedef struct _Block35Data Block35Data;
typedef void (*GalaGestureTrackerOnUpdate) (gdouble percentage, gpointer user_data);
typedef void (*GalaGestureTrackerOnBegin) (gdouble percentage, gpointer user_data);
typedef void (*GalaGestureTrackerOnEnd) (gdouble percentage, gboolean cancel_action, gint calculated_duration, gpointer user_data);
typedef struct _Block36Data Block36Data;
typedef struct _Block37Data Block37Data;
#define __vala_graphene_point_t_free0(var) ((var == NULL) ? NULL : (var = (_vala_graphene_point_t_free (var), NULL)))

struct _GalaZoom {
	GObject parent_instance;
	GalaZoomPrivate * priv;
};

struct _GalaZoomClass {
	GObjectClass parent_class;
};

struct _GalaZoomPrivate {
	GalaWindowManager* _wm;
	guint mouse_poll_timer;
	gfloat current_zoom;
	gulong wins_handler_id;
	GalaGestureTracker* gesture_tracker;
};

struct _GalaGesture {
	GTypeInstance parent_instance;
	volatile int ref_count;
	GalaGesturePrivate * priv;
	GdkEventType type;
	GalaGestureDirection direction;
	gint fingers;
	GdkInputSource performed_on_device_type;
};

struct _GalaGestureClass {
	GTypeClass parent_class;
	void (*finalize) (GalaGesture *self);
};

struct _Block35Data {
	int _ref_count_;
	GalaZoom* self;
	gfloat initial_zoom;
	gfloat target_zoom;
};

struct _Block36Data {
	int _ref_count_;
	GalaZoom* self;
	ClutterActor* wins;
};

struct _Block37Data {
	int _ref_count_;
	Block36Data * _data36_;
	gfloat mx;
	gfloat my;
	GdkDevice* client_pointer;
};

static gint GalaZoom_private_offset;
static gpointer gala_zoom_parent_class = NULL;

VALA_EXTERN GType gala_zoom_get_type (void) G_GNUC_CONST ;
G_DEFINE_AUTOPTR_CLEANUP_FUNC (GalaZoom, g_object_unref)
VALA_EXTERN GType gala_gesture_tracker_get_type (void) G_GNUC_CONST ;
G_DEFINE_AUTOPTR_CLEANUP_FUNC (GalaGestureTracker, g_object_unref)
VALA_EXTERN GalaWindowManager* gala_zoom_get_wm (GalaZoom* self);
VALA_EXTERN GalaZoom* gala_zoom_new (GalaWindowManager* wm);
VALA_EXTERN GalaZoom* gala_zoom_construct (GType object_type,
                               GalaWindowManager* wm);
static void gala_zoom_zoom_in (MetaDisplay* display,
                        MetaWindow* window,
                        ClutterKeyEvent* event,
                        MetaKeyBinding* binding,
                        GalaZoom* self);
static void gala_zoom_zoom_out (MetaDisplay* display,
                         MetaWindow* window,
                         ClutterKeyEvent* event,
                         MetaKeyBinding* binding,
                         GalaZoom* self);
VALA_EXTERN GalaGestureTracker* gala_gesture_tracker_new (gint min_animation_duration,
                                              gint max_animation_duration);
VALA_EXTERN GalaGestureTracker* gala_gesture_tracker_construct (GType object_type,
                                                    gint min_animation_duration,
                                                    gint max_animation_duration);
VALA_EXTERN void gala_gesture_tracker_enable_touchpad (GalaGestureTracker* self);
VALA_EXTERN gpointer gala_gesture_ref (gpointer instance);
VALA_EXTERN void gala_gesture_unref (gpointer instance);
VALA_EXTERN GParamSpec* gala_param_spec_gesture (const gchar* name,
                                     const gchar* nick,
                                     const gchar* blurb,
                                     GType object_type,
                                     GParamFlags flags);
VALA_EXTERN void gala_value_set_gesture (GValue* value,
                             gpointer v_object);
VALA_EXTERN void gala_value_take_gesture (GValue* value,
                              gpointer v_object);
VALA_EXTERN gpointer gala_value_get_gesture (const GValue* value);
VALA_EXTERN GType gala_gesture_get_type (void) G_GNUC_CONST ;
G_DEFINE_AUTOPTR_CLEANUP_FUNC (GalaGesture, gala_gesture_unref)
static void gala_zoom_on_gesture_detected (GalaZoom* self,
                                    GalaGesture* gesture);
static void _gala_zoom_on_gesture_detected_gala_gesture_tracker_on_gesture_detected (GalaGestureTracker* _sender,
                                                                              GalaGesture* gesture,
                                                                              gpointer self);
static void gala_zoom_zoom (GalaZoom* self,
                     gfloat delta,
                     gboolean play_sound,
                     gboolean animate);
VALA_EXTERN GType gala_gesture_direction_get_type (void) G_GNUC_CONST ;
VALA_EXTERN gchar* gala_gesture_settings_get_string (const gchar* setting_id);
static void gala_zoom_zoom_with_gesture (GalaZoom* self,
                                  GalaGestureDirection direction);
static Block35Data* block35_data_ref (Block35Data* _data35_);
static void block35_data_unref (void * _userdata_);
static void __lambda41_ (Block35Data* _data35_,
                  gdouble percentage);
VALA_EXTERN gfloat gala_gesture_tracker_animation_value (gfloat initial_value,
                                             gfloat target_value,
                                             gdouble percentage,
                                             gboolean rounded);
static void ___lambda41__gala_gesture_tracker_on_update (gdouble percentage,
                                                  gpointer self);
VALA_EXTERN void gala_gesture_tracker_connect_handlers (GalaGestureTracker* self,
                                            GalaGestureTrackerOnBegin on_begin_handler,
                                            gpointer on_begin_handler_target,
                                            GDestroyNotify on_begin_handler_target_destroy_notify,
                                            GalaGestureTrackerOnUpdate on_update_handler,
                                            gpointer on_update_handler_target,
                                            GDestroyNotify on_update_handler_target_destroy_notify,
                                            GalaGestureTrackerOnEnd on_end_handler,
                                            gpointer on_end_handler_target,
                                            GDestroyNotify on_end_handler_target_destroy_notify);
static Block36Data* block36_data_ref (Block36Data* _data36_);
static void block36_data_unref (void * _userdata_);
static Block37Data* block37_data_ref (Block37Data* _data37_);
static void block37_data_unref (void * _userdata_);
static gboolean ___lambda39_ (Block37Data* _data37_);
static void _vala_graphene_point_t_free (graphene_point_t* self);
static gboolean ____lambda39__gsource_func (gpointer self);
static void ____lambda40_ (Block36Data* _data36_);
static void _____lambda40__clutter_actor_transitions_completed (ClutterActor* _sender,
                                                         gpointer self);
static void gala_zoom_set_wm (GalaZoom* self,
                       GalaWindowManager* value);
static void gala_zoom_finalize (GObject * obj);
static GType gala_zoom_get_type_once (void);
static void _vala_gala_zoom_get_property (GObject * object,
                                   guint property_id,
                                   GValue * value,
                                   GParamSpec * pspec);
static void _vala_gala_zoom_set_property (GObject * object,
                                   guint property_id,
                                   const GValue * value,
                                   GParamSpec * pspec);
static inline gpointer _vala_memdup2 (gconstpointer mem,
                        gsize byte_size);

static inline gpointer
gala_zoom_get_instance_private (GalaZoom* self)
{
	return G_STRUCT_MEMBER_P (self, GalaZoom_private_offset);
}

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

static void
_gala_zoom_on_gesture_detected_gala_gesture_tracker_on_gesture_detected (GalaGestureTracker* _sender,
                                                                         GalaGesture* gesture,
                                                                         gpointer self)
{
	gala_zoom_on_gesture_detected ((GalaZoom*) self, gesture);
}

GalaZoom*
gala_zoom_construct (GType object_type,
                     GalaWindowManager* wm)
{
	GalaZoom * self = NULL;
	MetaDisplay* display = NULL;
	MetaDisplay* _tmp0_;
	MetaDisplay* _tmp1_;
	GSettings* schema = NULL;
	GSettings* _tmp2_;
	GalaGestureTracker* _tmp3_;
	GalaGestureTracker* _tmp4_;
	GalaGestureTracker* _tmp5_;
	g_return_val_if_fail (wm != NULL, NULL);
	self = (GalaZoom*) g_object_new (object_type, "wm", wm, NULL);
	_tmp0_ = meta_plugin_get_display ((MetaPlugin*) wm);
	_tmp1_ = _g_object_ref0 (_tmp0_);
	display = _tmp1_;
	_tmp2_ = g_settings_new (SCHEMA ".keybindings");
	schema = _tmp2_;
	meta_display_add_keybinding (display, "zoom-in", schema, 0, (MetaKeyHandlerFunc) gala_zoom_zoom_in, g_object_ref (self), g_object_unref);
	meta_display_add_keybinding (display, "zoom-out", schema, 0, (MetaKeyHandlerFunc) gala_zoom_zoom_out, g_object_ref (self), g_object_unref);
	_tmp3_ = gala_gesture_tracker_new (GALA_ZOOM_ANIMATION_DURATION, GALA_ZOOM_ANIMATION_DURATION);
	_g_object_unref0 (self->priv->gesture_tracker);
	self->priv->gesture_tracker = _tmp3_;
	_tmp4_ = self->priv->gesture_tracker;
	gala_gesture_tracker_enable_touchpad (_tmp4_);
	_tmp5_ = self->priv->gesture_tracker;
	g_signal_connect_object (_tmp5_, "on-gesture-detected", (GCallback) _gala_zoom_on_gesture_detected_gala_gesture_tracker_on_gesture_detected, self, 0);
	_g_object_unref0 (schema);
	_g_object_unref0 (display);
	return self;
}

GalaZoom*
gala_zoom_new (GalaWindowManager* wm)
{
	return gala_zoom_construct (GALA_TYPE_ZOOM, wm);
}

static void
gala_zoom_zoom_in (MetaDisplay* display,
                   MetaWindow* window,
                   ClutterKeyEvent* event,
                   MetaKeyBinding* binding,
                   GalaZoom* self)
{
	GalaWindowManager* _tmp0_;
	gboolean _tmp1_;
	gboolean _tmp2_;
	g_return_if_fail (self != NULL);
	g_return_if_fail (display != NULL);
	g_return_if_fail (event != NULL);
	g_return_if_fail (binding != NULL);
	_tmp0_ = self->priv->_wm;
	_tmp1_ = gala_window_manager_get_enable_animations (_tmp0_);
	_tmp2_ = _tmp1_;
	gala_zoom_zoom (self, GALA_ZOOM_SHORTCUT_DELTA, TRUE, _tmp2_);
}

static void
gala_zoom_zoom_out (MetaDisplay* display,
                    MetaWindow* window,
                    ClutterKeyEvent* event,
                    MetaKeyBinding* binding,
                    GalaZoom* self)
{
	GalaWindowManager* _tmp0_;
	gboolean _tmp1_;
	gboolean _tmp2_;
	g_return_if_fail (self != NULL);
	g_return_if_fail (display != NULL);
	g_return_if_fail (event != NULL);
	g_return_if_fail (binding != NULL);
	_tmp0_ = self->priv->_wm;
	_tmp1_ = gala_window_manager_get_enable_animations (_tmp0_);
	_tmp2_ = _tmp1_;
	gala_zoom_zoom (self, -GALA_ZOOM_SHORTCUT_DELTA, TRUE, _tmp2_);
}

static void
gala_zoom_on_gesture_detected (GalaZoom* self,
                               GalaGesture* gesture)
{
	gboolean _tmp0_ = FALSE;
	gboolean _tmp2_ = FALSE;
	gboolean _tmp3_ = FALSE;
	g_return_if_fail (self != NULL);
	g_return_if_fail (gesture != NULL);
	if (gesture->type != GDK_TOUCHPAD_PINCH) {
		_tmp0_ = TRUE;
	} else {
		gboolean _tmp1_ = FALSE;
		if (gesture->direction != GALA_GESTURE_DIRECTION_IN) {
			_tmp1_ = gesture->direction != GALA_GESTURE_DIRECTION_OUT;
		} else {
			_tmp1_ = FALSE;
		}
		_tmp0_ = _tmp1_;
	}
	if (_tmp0_) {
		return;
	}
	if (gesture->fingers == 3) {
		gchar* _tmp4_;
		gchar* _tmp5_;
		_tmp4_ = gala_gesture_settings_get_string ("three-finger-pinch");
		_tmp5_ = _tmp4_;
		_tmp3_ = g_strcmp0 (_tmp5_, "zoom") == 0;
		_g_free0 (_tmp5_);
	} else {
		_tmp3_ = FALSE;
	}
	if (_tmp3_) {
		_tmp2_ = TRUE;
	} else {
		gboolean _tmp6_ = FALSE;
		if (gesture->fingers == 4) {
			gchar* _tmp7_;
			gchar* _tmp8_;
			_tmp7_ = gala_gesture_settings_get_string ("four-finger-pinch");
			_tmp8_ = _tmp7_;
			_tmp6_ = g_strcmp0 (_tmp8_, "zoom") == 0;
			_g_free0 (_tmp8_);
		} else {
			_tmp6_ = FALSE;
		}
		_tmp2_ = _tmp6_;
	}
	if (_tmp2_) {
		gala_zoom_zoom_with_gesture (self, gesture->direction);
	}
}

static Block35Data*
block35_data_ref (Block35Data* _data35_)
{
	g_atomic_int_inc (&_data35_->_ref_count_);
	return _data35_;
}

static void
block35_data_unref (void * _userdata_)
{
	Block35Data* _data35_;
	_data35_ = (Block35Data*) _userdata_;
	if (g_atomic_int_dec_and_test (&_data35_->_ref_count_)) {
		GalaZoom* self;
		self = _data35_->self;
		_g_object_unref0 (self);
		g_slice_free (Block35Data, _data35_);
	}
}

static void
__lambda41_ (Block35Data* _data35_,
             gdouble percentage)
{
	GalaZoom* self;
	gfloat zoom_level = 0.0F;
	gfloat delta = 0.0F;
	GalaWindowManager* _tmp0_;
	gboolean _tmp1_;
	gboolean _tmp2_;
	self = _data35_->self;
	zoom_level = gala_gesture_tracker_animation_value (_data35_->initial_zoom, _data35_->target_zoom, percentage, FALSE);
	delta = zoom_level - self->priv->current_zoom;
	_tmp0_ = self->priv->_wm;
	_tmp1_ = gala_window_manager_get_enable_animations (_tmp0_);
	_tmp2_ = _tmp1_;
	if (!_tmp2_) {
		if (fabsf (delta) >= GALA_ZOOM_SHORTCUT_DELTA) {
			gfloat _tmp3_ = 0.0F;
			if (delta > ((gfloat) 0)) {
				_tmp3_ = GALA_ZOOM_SHORTCUT_DELTA;
			} else {
				_tmp3_ = -GALA_ZOOM_SHORTCUT_DELTA;
			}
			delta = _tmp3_;
		} else {
			delta = (gfloat) 0;
		}
	}
	gala_zoom_zoom (self, delta, FALSE, FALSE);
}

static void
___lambda41__gala_gesture_tracker_on_update (gdouble percentage,
                                             gpointer self)
{
	__lambda41_ (self, percentage);
}

static void
gala_zoom_zoom_with_gesture (GalaZoom* self,
                             GalaGestureDirection direction)
{
	Block35Data* _data35_;
	gfloat _tmp0_ = 0.0F;
	GalaGestureTrackerOnUpdate on_animation_update = NULL;
	gpointer on_animation_update_target;
	GDestroyNotify on_animation_update_target_destroy_notify;
	GalaGestureTracker* _tmp1_;
	GalaGestureTrackerOnUpdate _tmp2_;
	gpointer _tmp2__target;
	GDestroyNotify _tmp2__target_destroy_notify;
	g_return_if_fail (self != NULL);
	_data35_ = g_slice_new0 (Block35Data);
	_data35_->_ref_count_ = 1;
	_data35_->self = g_object_ref (self);
	_data35_->initial_zoom = self->priv->current_zoom;
	if (direction == GALA_GESTURE_DIRECTION_IN) {
		_tmp0_ = _data35_->initial_zoom - GALA_ZOOM_MAX_ZOOM;
	} else {
		_tmp0_ = _data35_->initial_zoom + GALA_ZOOM_MAX_ZOOM;
	}
	_data35_->target_zoom = _tmp0_;
	on_animation_update = ___lambda41__gala_gesture_tracker_on_update;
	on_animation_update_target = block35_data_ref (_data35_);
	on_animation_update_target_destroy_notify = block35_data_unref;
	_tmp1_ = self->priv->gesture_tracker;
	_tmp2_ = on_animation_update;
	_tmp2__target = on_animation_update_target;
	_tmp2__target_destroy_notify = on_animation_update_target_destroy_notify;
	on_animation_update = NULL;
	on_animation_update_target = NULL;
	on_animation_update_target_destroy_notify = NULL;
	gala_gesture_tracker_connect_handlers (_tmp1_, NULL, NULL, NULL, _tmp2_, _tmp2__target, _tmp2__target_destroy_notify, NULL, NULL, NULL);
	(on_animation_update_target_destroy_notify == NULL) ? NULL : (on_animation_update_target_destroy_notify (on_animation_update_target), NULL);
	on_animation_update = NULL;
	on_animation_update_target = NULL;
	on_animation_update_target_destroy_notify = NULL;
	block35_data_unref (_data35_);
	_data35_ = NULL;
}

static Block36Data*
block36_data_ref (Block36Data* _data36_)
{
	g_atomic_int_inc (&_data36_->_ref_count_);
	return _data36_;
}

static void
block36_data_unref (void * _userdata_)
{
	Block36Data* _data36_;
	_data36_ = (Block36Data*) _userdata_;
	if (g_atomic_int_dec_and_test (&_data36_->_ref_count_)) {
		GalaZoom* self;
		self = _data36_->self;
		_g_object_unref0 (_data36_->wins);
		_g_object_unref0 (self);
		g_slice_free (Block36Data, _data36_);
	}
}

static Block37Data*
block37_data_ref (Block37Data* _data37_)
{
	g_atomic_int_inc (&_data37_->_ref_count_);
	return _data37_;
}

static void
block37_data_unref (void * _userdata_)
{
	Block37Data* _data37_;
	_data37_ = (Block37Data*) _userdata_;
	if (g_atomic_int_dec_and_test (&_data37_->_ref_count_)) {
		GalaZoom* self;
		self = _data37_->_data36_->self;
		_g_object_unref0 (_data37_->client_pointer);
		block36_data_unref (_data37_->_data36_);
		_data37_->_data36_ = NULL;
		g_slice_free (Block37Data, _data37_);
	}
}

static void
_vala_graphene_point_t_free (graphene_point_t* self)
{
	g_boxed_free (graphene_point_get_type (), self);
}

static gboolean
___lambda39_ (Block37Data* _data37_)
{
	Block36Data* _data36_;
	GalaZoom* self;
	GdkDevice* _tmp0_;
	gint _tmp1_ = 0;
	gint _tmp2_ = 0;
	graphene_point_t new_pivot = {0};
	ClutterActor* _tmp3_;
	gfloat _tmp4_;
	gfloat _tmp5_;
	ClutterActor* _tmp6_;
	gfloat _tmp7_;
	gfloat _tmp8_;
	ClutterActor* _tmp9_;
	graphene_point_t* _tmp10_;
	graphene_point_t* _tmp11_;
	graphene_point_t* _tmp12_;
	graphene_point_t _tmp13_;
	gboolean _tmp14_;
	ClutterActor* _tmp15_;
	ClutterActor* _tmp16_;
	ClutterActor* _tmp17_;
	ClutterActor* _tmp18_;
	graphene_point_t _tmp19_;
	ClutterActor* _tmp20_;
	gboolean result;
	_data36_ = _data37_->_data36_;
	self = _data36_->self;
	_tmp0_ = _data37_->client_pointer;
	gdk_device_get_position (_tmp0_, NULL, &_tmp1_, &_tmp2_);
	_data37_->mx = (gfloat) _tmp1_;
	_data37_->my = (gfloat) _tmp2_;
	memset (&new_pivot, 0, sizeof (graphene_point_t));
	_tmp3_ = _data36_->wins;
	_tmp4_ = clutter_actor_get_width (_tmp3_);
	_tmp5_ = _tmp4_;
	_tmp6_ = _data36_->wins;
	_tmp7_ = clutter_actor_get_height (_tmp6_);
	_tmp8_ = _tmp7_;
	graphene_point_init (&new_pivot, _data37_->mx / _tmp5_, _data37_->my / _tmp8_);
	_tmp9_ = _data36_->wins;
	g_object_get (_tmp9_, "pivot-point", &_tmp10_, NULL);
	_tmp11_ = _tmp10_;
	_tmp12_ = _tmp11_;
	_tmp13_ = new_pivot;
	_tmp14_ = graphene_point_equal (_tmp12_, &_tmp13_);
	__vala_graphene_point_t_free0 (_tmp12_);
	if (_tmp14_) {
		result = TRUE;
		return result;
	}
	_tmp15_ = _data36_->wins;
	clutter_actor_save_easing_state (_tmp15_);
	_tmp16_ = _data36_->wins;
	clutter_actor_set_easing_mode (_tmp16_, CLUTTER_LINEAR);
	_tmp17_ = _data36_->wins;
	clutter_actor_set_easing_duration (_tmp17_, GALA_ZOOM_MOUSE_POLL_TIME);
	_tmp18_ = _data36_->wins;
	_tmp19_ = new_pivot;
	g_object_set (_tmp18_, "pivot-point", &_tmp19_, NULL);
	_tmp20_ = _data36_->wins;
	clutter_actor_restore_easing_state (_tmp20_);
	result = TRUE;
	return result;
}

static gboolean
____lambda39__gsource_func (gpointer self)
{
	gboolean result;
	result = ___lambda39_ (self);
	return result;
}

static void
____lambda40_ (Block36Data* _data36_)
{
	GalaZoom* self;
	ClutterActor* _tmp0_;
	ClutterActor* _tmp1_;
	self = _data36_->self;
	_tmp0_ = _data36_->wins;
	g_signal_handler_disconnect ((GObject*) _tmp0_, self->priv->wins_handler_id);
	_tmp1_ = _data36_->wins;
	clutter_actor_set_pivot_point (_tmp1_, 0.0f, 0.0f);
}

static void
_____lambda40__clutter_actor_transitions_completed (ClutterActor* _sender,
                                                    gpointer self)
{
	____lambda40_ (self);
}

static void
gala_zoom_zoom (GalaZoom* self,
                gfloat delta,
                gboolean play_sound,
                gboolean animate)
{
	Block36Data* _data36_;
	gboolean _tmp0_ = FALSE;
	gboolean _tmp1_ = FALSE;
	GalaWindowManager* _tmp3_;
	ClutterActor* _tmp4_;
	ClutterActor* _tmp5_;
	ClutterActor* _tmp6_;
	gint _tmp21_ = 0;
	gint animation_duration = 0;
	ClutterActor* _tmp30_;
	ClutterActor* _tmp31_;
	ClutterActor* _tmp32_;
	ClutterActor* _tmp33_;
	ClutterActor* _tmp34_;
	g_return_if_fail (self != NULL);
	_data36_ = g_slice_new0 (Block36Data);
	_data36_->_ref_count_ = 1;
	_data36_->self = g_object_ref (self);
	if (self->priv->current_zoom <= GALA_ZOOM_MIN_ZOOM) {
		_tmp1_ = delta < ((gfloat) 0);
	} else {
		_tmp1_ = FALSE;
	}
	if (_tmp1_) {
		_tmp0_ = TRUE;
	} else {
		gboolean _tmp2_ = FALSE;
		if (self->priv->current_zoom >= GALA_ZOOM_MAX_ZOOM) {
			_tmp2_ = delta >= ((gfloat) 0);
		} else {
			_tmp2_ = FALSE;
		}
		_tmp0_ = _tmp2_;
	}
	if (_tmp0_) {
		if (play_sound) {
			gdk_beep ();
		}
		block36_data_unref (_data36_);
		_data36_ = NULL;
		return;
	}
	_tmp3_ = self->priv->_wm;
	_tmp4_ = gala_window_manager_get_ui_group (_tmp3_);
	_tmp5_ = _tmp4_;
	_tmp6_ = _g_object_ref0 (_tmp5_);
	_data36_->wins = _tmp6_;
	if (self->priv->mouse_poll_timer == ((guint) 0)) {
		Block37Data* _data37_;
		GdkDisplay* _tmp7_;
		GdkSeat* _tmp8_;
		GdkDevice* _tmp9_;
		GdkDevice* _tmp10_;
		GdkDevice* _tmp11_;
		gint _tmp12_ = 0;
		gint _tmp13_ = 0;
		ClutterActor* _tmp14_;
		ClutterActor* _tmp15_;
		gfloat _tmp16_;
		gfloat _tmp17_;
		ClutterActor* _tmp18_;
		gfloat _tmp19_;
		gfloat _tmp20_;
		_data37_ = g_slice_new0 (Block37Data);
		_data37_->_ref_count_ = 1;
		_data37_->_data36_ = block36_data_ref (_data36_);
		_tmp7_ = gdk_display_get_default ();
		_tmp8_ = gdk_display_get_default_seat (_tmp7_);
		_tmp9_ = gdk_seat_get_pointer (_tmp8_);
		_tmp10_ = _g_object_ref0 (_tmp9_);
		_data37_->client_pointer = _tmp10_;
		_tmp11_ = _data37_->client_pointer;
		gdk_device_get_position (_tmp11_, NULL, &_tmp12_, &_tmp13_);
		_data37_->mx = (gfloat) _tmp12_;
		_data37_->my = (gfloat) _tmp13_;
		_tmp14_ = _data36_->wins;
		_tmp15_ = _data36_->wins;
		_tmp16_ = clutter_actor_get_width (_tmp15_);
		_tmp17_ = _tmp16_;
		_tmp18_ = _data36_->wins;
		_tmp19_ = clutter_actor_get_height (_tmp18_);
		_tmp20_ = _tmp19_;
		clutter_actor_set_pivot_point (_tmp14_, _data37_->mx / _tmp17_, _data37_->my / _tmp20_);
		self->priv->mouse_poll_timer = g_timeout_add_full (G_PRIORITY_DEFAULT, GALA_ZOOM_MOUSE_POLL_TIME, ____lambda39__gsource_func, block37_data_ref (_data37_), block37_data_unref);
		block37_data_unref (_data37_);
		_data37_ = NULL;
	}
	self->priv->current_zoom = self->priv->current_zoom + delta;
	if (animate) {
		_tmp21_ = GALA_ZOOM_ANIMATION_DURATION;
	} else {
		_tmp21_ = 0;
	}
	animation_duration = _tmp21_;
	if (self->priv->current_zoom <= GALA_ZOOM_MIN_ZOOM) {
		ClutterActor* _tmp22_;
		ClutterActor* _tmp23_;
		ClutterActor* _tmp24_;
		ClutterActor* _tmp25_;
		ClutterActor* _tmp26_;
		self->priv->current_zoom = GALA_ZOOM_MIN_ZOOM;
		if (self->priv->mouse_poll_timer > ((guint) 0)) {
			g_source_remove (self->priv->mouse_poll_timer);
		}
		self->priv->mouse_poll_timer = (guint) 0;
		_tmp22_ = _data36_->wins;
		clutter_actor_save_easing_state (_tmp22_);
		_tmp23_ = _data36_->wins;
		clutter_actor_set_easing_mode (_tmp23_, CLUTTER_EASE_OUT_CUBIC);
		_tmp24_ = _data36_->wins;
		clutter_actor_set_easing_duration (_tmp24_, (guint) animation_duration);
		_tmp25_ = _data36_->wins;
		clutter_actor_set_scale (_tmp25_, (gdouble) GALA_ZOOM_MIN_ZOOM, (gdouble) GALA_ZOOM_MIN_ZOOM);
		_tmp26_ = _data36_->wins;
		clutter_actor_restore_easing_state (_tmp26_);
		if (animate) {
			ClutterActor* _tmp27_;
			gulong _tmp28_;
			_tmp27_ = _data36_->wins;
			_tmp28_ = g_signal_connect_data (_tmp27_, "transitions-completed", (GCallback) _____lambda40__clutter_actor_transitions_completed, block36_data_ref (_data36_), (GClosureNotify) block36_data_unref, 0);
			self->priv->wins_handler_id = _tmp28_;
		} else {
			ClutterActor* _tmp29_;
			_tmp29_ = _data36_->wins;
			clutter_actor_set_pivot_point (_tmp29_, 0.0f, 0.0f);
		}
		block36_data_unref (_data36_);
		_data36_ = NULL;
		return;
	}
	_tmp30_ = _data36_->wins;
	clutter_actor_save_easing_state (_tmp30_);
	_tmp31_ = _data36_->wins;
	clutter_actor_set_easing_mode (_tmp31_, CLUTTER_EASE_OUT_CUBIC);
	_tmp32_ = _data36_->wins;
	clutter_actor_set_easing_duration (_tmp32_, (guint) animation_duration);
	_tmp33_ = _data36_->wins;
	clutter_actor_set_scale (_tmp33_, (gdouble) self->priv->current_zoom, (gdouble) self->priv->current_zoom);
	_tmp34_ = _data36_->wins;
	clutter_actor_restore_easing_state (_tmp34_);
	block36_data_unref (_data36_);
	_data36_ = NULL;
}

GalaWindowManager*
gala_zoom_get_wm (GalaZoom* self)
{
	GalaWindowManager* result;
	GalaWindowManager* _tmp0_;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = self->priv->_wm;
	result = _tmp0_;
	return result;
}

static void
gala_zoom_set_wm (GalaZoom* self,
                  GalaWindowManager* value)
{
	GalaWindowManager* old_value;
	g_return_if_fail (self != NULL);
	old_value = gala_zoom_get_wm (self);
	if (old_value != value) {
		GalaWindowManager* _tmp0_;
		_tmp0_ = _g_object_ref0 (value);
		_g_object_unref0 (self->priv->_wm);
		self->priv->_wm = _tmp0_;
		g_object_notify_by_pspec ((GObject *) self, gala_zoom_properties[GALA_ZOOM_WM_PROPERTY]);
	}
}

static void
gala_zoom_class_init (GalaZoomClass * klass,
                      gpointer klass_data)
{
	gala_zoom_parent_class = g_type_class_peek_parent (klass);
	g_type_class_adjust_private_offset (klass, &GalaZoom_private_offset);
	G_OBJECT_CLASS (klass)->get_property = _vala_gala_zoom_get_property;
	G_OBJECT_CLASS (klass)->set_property = _vala_gala_zoom_set_property;
	G_OBJECT_CLASS (klass)->finalize = gala_zoom_finalize;
	g_object_class_install_property (G_OBJECT_CLASS (klass), GALA_ZOOM_WM_PROPERTY, gala_zoom_properties[GALA_ZOOM_WM_PROPERTY] = g_param_spec_object ("wm", "wm", "wm", GALA_TYPE_WINDOW_MANAGER, G_PARAM_STATIC_STRINGS | G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY));
}

static void
gala_zoom_instance_init (GalaZoom * self,
                         gpointer klass)
{
	self->priv = gala_zoom_get_instance_private (self);
	self->priv->mouse_poll_timer = (guint) 0;
	self->priv->current_zoom = GALA_ZOOM_MIN_ZOOM;
	self->priv->wins_handler_id = 0UL;
}

static void
gala_zoom_finalize (GObject * obj)
{
	GalaZoom * self;
	GalaWindowManager* _tmp0_;
	MetaDisplay* display = NULL;
	GalaWindowManager* _tmp1_;
	MetaDisplay* _tmp2_;
	MetaDisplay* _tmp3_;
	MetaDisplay* _tmp4_;
	MetaDisplay* _tmp5_;
	self = G_TYPE_CHECK_INSTANCE_CAST (obj, GALA_TYPE_ZOOM, GalaZoom);
	_tmp0_ = self->priv->_wm;
	if (_tmp0_ == NULL) {
		goto _return;
	}
	_tmp1_ = self->priv->_wm;
	_tmp2_ = meta_plugin_get_display ((MetaPlugin*) _tmp1_);
	_tmp3_ = _g_object_ref0 (_tmp2_);
	display = _tmp3_;
	_tmp4_ = display;
	meta_display_remove_keybinding (_tmp4_, "zoom-in");
	_tmp5_ = display;
	meta_display_remove_keybinding (_tmp5_, "zoom-out");
	if (self->priv->mouse_poll_timer > ((guint) 0)) {
		g_source_remove (self->priv->mouse_poll_timer);
	}
	self->priv->mouse_poll_timer = (guint) 0;
	_g_object_unref0 (display);
	_return:
	_g_object_unref0 (self->priv->_wm);
	_g_object_unref0 (self->priv->gesture_tracker);
	G_OBJECT_CLASS (gala_zoom_parent_class)->finalize (obj);
}

static GType
gala_zoom_get_type_once (void)
{
	static const GTypeInfo g_define_type_info = { sizeof (GalaZoomClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) gala_zoom_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (GalaZoom), 0, (GInstanceInitFunc) gala_zoom_instance_init, NULL };
	GType gala_zoom_type_id;
	gala_zoom_type_id = g_type_register_static (G_TYPE_OBJECT, "GalaZoom", &g_define_type_info, 0);
	GalaZoom_private_offset = g_type_add_instance_private (gala_zoom_type_id, sizeof (GalaZoomPrivate));
	return gala_zoom_type_id;
}

GType
gala_zoom_get_type (void)
{
	static volatile gsize gala_zoom_type_id__once = 0;
	if (g_once_init_enter (&gala_zoom_type_id__once)) {
		GType gala_zoom_type_id;
		gala_zoom_type_id = gala_zoom_get_type_once ();
		g_once_init_leave (&gala_zoom_type_id__once, gala_zoom_type_id);
	}
	return gala_zoom_type_id__once;
}

static void
_vala_gala_zoom_get_property (GObject * object,
                              guint property_id,
                              GValue * value,
                              GParamSpec * pspec)
{
	GalaZoom * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (object, GALA_TYPE_ZOOM, GalaZoom);
	switch (property_id) {
		case GALA_ZOOM_WM_PROPERTY:
		g_value_set_object (value, gala_zoom_get_wm (self));
		break;
		default:
		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
		break;
	}
}

static void
_vala_gala_zoom_set_property (GObject * object,
                              guint property_id,
                              const GValue * value,
                              GParamSpec * pspec)
{
	GalaZoom * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (object, GALA_TYPE_ZOOM, GalaZoom);
	switch (property_id) {
		case GALA_ZOOM_WM_PROPERTY:
		gala_zoom_set_wm (self, g_value_get_object (value));
		break;
		default:
		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
		break;
	}
}

static inline gpointer
_vala_memdup2 (gconstpointer mem,
               gsize byte_size)
{
	gpointer new_mem;
	if (mem && byte_size != 0) {
		new_mem = g_malloc (byte_size);
		memcpy (new_mem, mem, byte_size);
	} else {
		new_mem = NULL;
	}
	return new_mem;
}

