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

/*
* Copyright (c) 2009-2013 Yorba Foundation
*
* This program 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 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, write to the
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301 USA
*/

#include "io.elementary.photos.h"
#include <glib-object.h>
#include <cairo-gobject.h>
#include <glib.h>
#include <float.h>
#include <math.h>
#include <gdk/gdk.h>
#include <gtk/gtk.h>
#include <gdk-pixbuf/gdk-pixbuf.h>
#include <stdlib.h>
#include <string.h>
#include <gobject/gvaluecollector.h>
#include <glib/gi18n-lib.h>

#define EDITING_TOOLS_STRAIGHTEN_TOOL_MIN_ANGLE (-15.0)
#define EDITING_TOOLS_STRAIGHTEN_TOOL_MAX_ANGLE 15.0
#define EDITING_TOOLS_STRAIGHTEN_TOOL_INCREMENT 0.1
#define EDITING_TOOLS_STRAIGHTEN_TOOL_MIN_SLIDER_SIZE 160
#define EDITING_TOOLS_STRAIGHTEN_TOOL_MIN_LABEL_SIZE 100
#define EDITING_TOOLS_STRAIGHTEN_TOOL_MIN_BUTTON_SIZE 84
#define EDITING_TOOLS_STRAIGHTEN_TOOL_TEMP_PIXBUF_SIZE 768
#define EDITING_TOOLS_STRAIGHTEN_TOOL_REPAINT_ON_STOP_DELAY_MSEC 100
#define EDITING_TOOLS_STRAIGHTEN_TOOL_STRAIGHTEN_TOOL_WINDOW_CONTROL_SPACING 8
#if !defined(VALA_STRICT_C)
#if !defined(__clang__) && defined(__GNUC__) && (__GNUC__ >= 14)
#pragma GCC diagnostic warning "-Wincompatible-pointer-types"
#elif defined(__clang__) && (__clang_major__ >= 16)
#pragma clang diagnostic ignored "-Wincompatible-function-pointer-types"
#pragma clang diagnostic ignored "-Wincompatible-pointer-types"
#endif
#endif

#define EDITING_TOOLS_STRAIGHTEN_TOOL_TYPE_STRAIGHTEN_TOOL_WINDOW (editing_tools_straighten_tool_straighten_tool_window_get_type ())
#define EDITING_TOOLS_STRAIGHTEN_TOOL_STRAIGHTEN_TOOL_WINDOW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EDITING_TOOLS_STRAIGHTEN_TOOL_TYPE_STRAIGHTEN_TOOL_WINDOW, EditingToolsStraightenToolStraightenToolWindow))
#define EDITING_TOOLS_STRAIGHTEN_TOOL_STRAIGHTEN_TOOL_WINDOW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EDITING_TOOLS_STRAIGHTEN_TOOL_TYPE_STRAIGHTEN_TOOL_WINDOW, EditingToolsStraightenToolStraightenToolWindowClass))
#define EDITING_TOOLS_STRAIGHTEN_TOOL_IS_STRAIGHTEN_TOOL_WINDOW(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EDITING_TOOLS_STRAIGHTEN_TOOL_TYPE_STRAIGHTEN_TOOL_WINDOW))
#define EDITING_TOOLS_STRAIGHTEN_TOOL_IS_STRAIGHTEN_TOOL_WINDOW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EDITING_TOOLS_STRAIGHTEN_TOOL_TYPE_STRAIGHTEN_TOOL_WINDOW))
#define EDITING_TOOLS_STRAIGHTEN_TOOL_STRAIGHTEN_TOOL_WINDOW_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EDITING_TOOLS_STRAIGHTEN_TOOL_TYPE_STRAIGHTEN_TOOL_WINDOW, EditingToolsStraightenToolStraightenToolWindowClass))

typedef struct _EditingToolsStraightenToolStraightenToolWindow EditingToolsStraightenToolStraightenToolWindow;
typedef struct _EditingToolsStraightenToolStraightenToolWindowClass EditingToolsStraightenToolStraightenToolWindowClass;

#define EDITING_TOOLS_STRAIGHTEN_TOOL_TYPE_STRAIGHTEN_GUIDE (editing_tools_straighten_tool_straighten_guide_get_type ())
#define EDITING_TOOLS_STRAIGHTEN_TOOL_STRAIGHTEN_GUIDE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EDITING_TOOLS_STRAIGHTEN_TOOL_TYPE_STRAIGHTEN_GUIDE, EditingToolsStraightenToolStraightenGuide))
#define EDITING_TOOLS_STRAIGHTEN_TOOL_STRAIGHTEN_GUIDE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EDITING_TOOLS_STRAIGHTEN_TOOL_TYPE_STRAIGHTEN_GUIDE, EditingToolsStraightenToolStraightenGuideClass))
#define EDITING_TOOLS_STRAIGHTEN_TOOL_IS_STRAIGHTEN_GUIDE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EDITING_TOOLS_STRAIGHTEN_TOOL_TYPE_STRAIGHTEN_GUIDE))
#define EDITING_TOOLS_STRAIGHTEN_TOOL_IS_STRAIGHTEN_GUIDE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EDITING_TOOLS_STRAIGHTEN_TOOL_TYPE_STRAIGHTEN_GUIDE))
#define EDITING_TOOLS_STRAIGHTEN_TOOL_STRAIGHTEN_GUIDE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EDITING_TOOLS_STRAIGHTEN_TOOL_TYPE_STRAIGHTEN_GUIDE, EditingToolsStraightenToolStraightenGuideClass))

typedef struct _EditingToolsStraightenToolStraightenGuide EditingToolsStraightenToolStraightenGuide;
typedef struct _EditingToolsStraightenToolStraightenGuideClass EditingToolsStraightenToolStraightenGuideClass;
enum  {
	EDITING_TOOLS_STRAIGHTEN_TOOL_0_PROPERTY,
	EDITING_TOOLS_STRAIGHTEN_TOOL_NUM_PROPERTIES
};
static GParamSpec* editing_tools_straighten_tool_properties[EDITING_TOOLS_STRAIGHTEN_TOOL_NUM_PROPERTIES];
#define _g_object_unref0(var) ((var == NULL) ? NULL : (var = (g_object_unref (var), NULL)))
#define _cairo_surface_destroy0(var) ((var == NULL) ? NULL : (var = (cairo_surface_destroy (var), NULL)))
#define _cairo_destroy0(var) ((var == NULL) ? NULL : (var = (cairo_destroy (var), NULL)))
#define _one_shot_scheduler_unref0(var) ((var == NULL) ? NULL : (var = (one_shot_scheduler_unref (var), NULL)))
#define _editing_tools_straighten_tool_straighten_guide_unref0(var) ((var == NULL) ? NULL : (var = (editing_tools_straighten_tool_straighten_guide_unref (var), NULL)))
typedef struct _EditingToolsStraightenToolStraightenToolWindowPrivate EditingToolsStraightenToolStraightenToolWindowPrivate;
#define _g_free0(var) ((var == NULL) ? NULL : (var = (g_free (var), NULL)))
typedef struct _EditingToolsStraightenToolStraightenGuidePrivate EditingToolsStraightenToolStraightenGuidePrivate;
typedef struct _EditingToolsStraightenToolParamSpecStraightenGuide EditingToolsStraightenToolParamSpecStraightenGuide;
enum  {
	EDITING_TOOLS_STRAIGHTEN_TOOL_STRAIGHTEN_TOOL_WINDOW_0_PROPERTY,
	EDITING_TOOLS_STRAIGHTEN_TOOL_STRAIGHTEN_TOOL_WINDOW_NUM_PROPERTIES
};
static GParamSpec* editing_tools_straighten_tool_straighten_tool_window_properties[EDITING_TOOLS_STRAIGHTEN_TOOL_STRAIGHTEN_TOOL_WINDOW_NUM_PROPERTIES];
#define _vala_assert(expr, msg) if G_LIKELY (expr) ; else g_assertion_message_expr (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, msg);
#define _vala_return_if_fail(expr, msg) if G_LIKELY (expr) ; else { g_return_if_fail_warning (G_LOG_DOMAIN, G_STRFUNC, msg); return; }
#define _vala_return_val_if_fail(expr, msg, val) if G_LIKELY (expr) ; else { g_return_if_fail_warning (G_LOG_DOMAIN, G_STRFUNC, msg); return val; }
#define _vala_warn_if_fail(expr, msg) if G_LIKELY (expr) ; else g_warn_message (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, msg);

struct _EditingToolsStraightenToolPrivate {
	EditingToolsStraightenToolStraightenToolWindow* window;
	cairo_surface_t* photo_surf;
	Dimensions image_dims;
	cairo_surface_t* rotate_surf;
	cairo_t* rotate_ctx;
	Dimensions last_viewport;
	gint view_width;
	gint view_height;
	gdouble photo_angle;
	gboolean use_high_qual;
	OneShotScheduler* slider_sched;
	GdkPoint crop_center;
	gint crop_width;
	gint crop_height;
	EditingToolsStraightenToolStraightenGuide* guide;
	GdkPoint rotated_center;
	gdouble rotate_scale;
	gdouble preview_scale;
	gint scale_factor;
};

struct _EditingToolsStraightenToolStraightenToolWindow {
	EditingToolsEditingToolWindow parent_instance;
	EditingToolsStraightenToolStraightenToolWindowPrivate * priv;
	GtkScale* angle_slider;
	GtkLabel* angle_label;
	GtkLabel* description_label;
	GtkButton* ok_button;
	GtkButton* cancel_button;
	GtkButton* reset_button;
};

struct _EditingToolsStraightenToolStraightenToolWindowClass {
	EditingToolsEditingToolWindowClass parent_class;
};

struct _EditingToolsStraightenToolStraightenGuide {
	GTypeInstance parent_instance;
	volatile int ref_count;
	EditingToolsStraightenToolStraightenGuidePrivate * priv;
};

struct _EditingToolsStraightenToolStraightenGuideClass {
	GTypeClass parent_class;
	void (*finalize) (EditingToolsStraightenToolStraightenGuide *self);
};

struct _EditingToolsStraightenToolStraightenGuidePrivate {
	gboolean is_active;
	gint x[2];
	gint y[2];
	gdouble angle0;
};

struct _EditingToolsStraightenToolParamSpecStraightenGuide {
	GParamSpec parent_instance;
};

static gint EditingToolsStraightenTool_private_offset;
static gpointer editing_tools_straighten_tool_parent_class = NULL;
static gint EditingToolsStraightenToolStraightenGuide_private_offset;
static gpointer editing_tools_straighten_tool_straighten_guide_parent_class = NULL;
static gpointer editing_tools_straighten_tool_straighten_tool_window_parent_class = NULL;

static GType editing_tools_straighten_tool_straighten_tool_window_get_type (void) G_GNUC_CONST  G_GNUC_UNUSED ;
static gpointer editing_tools_straighten_tool_straighten_guide_ref (gpointer instance);
static void editing_tools_straighten_tool_straighten_guide_unref (gpointer instance);
static GParamSpec* editing_tools_straighten_tool_param_spec_straighten_guide (const gchar* name,
                                                                       const gchar* nick,
                                                                       const gchar* blurb,
                                                                       GType object_type,
                                                                       GParamFlags flags) G_GNUC_UNUSED ;
static void editing_tools_straighten_tool_value_set_straighten_guide (GValue* value,
                                                               gpointer v_object) G_GNUC_UNUSED ;
static void editing_tools_straighten_tool_value_take_straighten_guide (GValue* value,
                                                                gpointer v_object) G_GNUC_UNUSED ;
static gpointer editing_tools_straighten_tool_value_get_straighten_guide (const GValue* value) G_GNUC_UNUSED ;
static GType editing_tools_straighten_tool_straighten_guide_get_type (void) G_GNUC_CONST  G_GNUC_UNUSED ;
static EditingToolsStraightenToolStraightenGuide* editing_tools_straighten_tool_straighten_guide_new (void);
static EditingToolsStraightenToolStraightenGuide* editing_tools_straighten_tool_straighten_guide_construct (GType object_type);
static EditingToolsStraightenTool* editing_tools_straighten_tool_new (void);
static EditingToolsStraightenTool* editing_tools_straighten_tool_construct (GType object_type);
static void editing_tools_straighten_tool_on_ok_clicked (EditingToolsStraightenTool* self);
VALA_EXTERN void rotate_point_arb (GdkPoint* source_point,
                       gint img_w,
                       gint img_h,
                       gdouble angle,
                       gboolean invert,
                       GdkPoint* result);
static void editing_tools_straighten_tool_high_qual_repaint (EditingToolsStraightenTool* self);
static void editing_tools_straighten_tool_update_rotated_surface (EditingToolsStraightenTool* self);
static void editing_tools_straighten_tool_on_slider_stopped_delayed (EditingToolsStraightenTool* self);
static void editing_tools_straighten_tool_real_on_left_click (EditingToolsEditingTool* base,
                                                       gint x,
                                                       gint y);
static void editing_tools_straighten_tool_straighten_guide_reset (EditingToolsStraightenToolStraightenGuide* self,
                                                           gint x,
                                                           gint y,
                                                           gdouble angle);
static void editing_tools_straighten_tool_real_on_left_released (EditingToolsEditingTool* base,
                                                          gint x,
                                                          gint y);
static gboolean editing_tools_straighten_tool_straighten_guide_update (EditingToolsStraightenToolStraightenGuide* self,
                                                                gint x,
                                                                gint y);
static gdouble* editing_tools_straighten_tool_straighten_guide_get_angle (EditingToolsStraightenToolStraightenGuide* self);
static void editing_tools_straighten_tool_straighten_guide_clear (EditingToolsStraightenToolStraightenGuide* self);
static void editing_tools_straighten_tool_real_on_motion (EditingToolsEditingTool* base,
                                                   gint x,
                                                   gint y,
                                                   GdkModifierType mask);
static gboolean editing_tools_straighten_tool_real_on_keypress (EditingToolsEditingTool* base,
                                                         GdkEventKey* event);
static void editing_tools_straighten_tool_prepare_image (EditingToolsStraightenTool* self);
static gboolean _dimensions_equal (const Dimensions * s1,
                            const Dimensions * s2);
static void editing_tools_straighten_tool_adjust_for_rotation (EditingToolsStraightenTool* self);
VALA_EXTERN void compute_arb_rotated_size (gdouble src_width,
                               gdouble src_height,
                               gdouble angle,
                               gdouble* dest_width,
                               gdouble* dest_height);
static void editing_tools_straighten_tool_real_activate (EditingToolsEditingTool* base,
                                                  EditingToolsPhotoCanvas* canvas);
static void editing_tools_straighten_tool_bind_canvas_handlers (EditingToolsStraightenTool* self,
                                                         EditingToolsPhotoCanvas* canvas);
VALA_EXTERN void derotate_point_arb (GdkPoint* source_point,
                         gint img_w,
                         gint img_h,
                         gdouble angle,
                         GdkPoint* result);
static EditingToolsStraightenToolStraightenToolWindow* editing_tools_straighten_tool_straighten_tool_window_new (GtkWindow* container);
static EditingToolsStraightenToolStraightenToolWindow* editing_tools_straighten_tool_straighten_tool_window_construct (GType object_type,
                                                                                                                GtkWindow* container);
static void editing_tools_straighten_tool_bind_window_handlers (EditingToolsStraightenTool* self);
static void editing_tools_straighten_tool_real_deactivate (EditingToolsEditingTool* base);
static void editing_tools_straighten_tool_unbind_window_handlers (EditingToolsStraightenTool* self);
static void editing_tools_straighten_tool_unbind_canvas_handlers (EditingToolsStraightenTool* self,
                                                           EditingToolsPhotoCanvas* canvas);
static void editing_tools_straighten_tool_on_resized_pixbuf (EditingToolsStraightenTool* self,
                                                      Dimensions* old_dim,
                                                      GdkPixbuf* scaled,
                                                      GdkRectangle* scaled_position);
static void _editing_tools_straighten_tool_on_resized_pixbuf_editing_tools_photo_canvas_resized_scaled_pixbuf (EditingToolsPhotoCanvas* _sender,
                                                                                                        Dimensions* old_dim,
                                                                                                        GdkPixbuf* scaled,
                                                                                                        GdkRectangle* scaled_position,
                                                                                                        gpointer self);
static gboolean _editing_tools_editing_tool_on_keypress_gtk_widget_key_press_event (GtkWidget* _sender,
                                                                             GdkEventKey* event,
                                                                             gpointer self);
static void _editing_tools_straighten_tool_on_ok_clicked_gtk_button_clicked (GtkButton* _sender,
                                                                      gpointer self);
static void _editing_tools_editing_tool_notify_cancel_gtk_button_clicked (GtkButton* _sender,
                                                                   gpointer self);
static void editing_tools_straighten_tool_on_angle_changed (EditingToolsStraightenTool* self);
static void _editing_tools_straighten_tool_on_angle_changed_gtk_range_value_changed (GtkRange* _sender,
                                                                              gpointer self);
static void _editing_tools_straighten_tool_on_slider_stopped_delayed_one_shot_callback (gpointer self);
static EditingToolsEditingToolWindow* editing_tools_straighten_tool_real_get_tool_window (EditingToolsEditingTool* base);
static void editing_tools_straighten_tool_draw_rotated_source (EditingToolsStraightenTool* self,
                                                        cairo_surface_t* src_surf,
                                                        cairo_t* dest_ctx,
                                                        gint src_width,
                                                        gint src_height,
                                                        gdouble angle);
static void editing_tools_straighten_tool_draw_superimposed_grid (EditingToolsStraightenTool* self,
                                                           cairo_t* dest_ctx,
                                                           gint width,
                                                           gint height);
static void editing_tools_straighten_tool_real_paint (EditingToolsEditingTool* base,
                                               cairo_t* ctx);
static void editing_tools_straighten_tool_straighten_guide_draw (EditingToolsStraightenToolStraightenGuide* self,
                                                          cairo_t* ctx);
VALA_EXTERN gdouble degrees_to_radians (gdouble theta);
static gdouble* _double_dup (gdouble* self);
static void editing_tools_straighten_tool_straighten_guide_finalize (EditingToolsStraightenToolStraightenGuide * obj);
static GType editing_tools_straighten_tool_straighten_guide_get_type_once (void);
static void editing_tools_straighten_tool_straighten_tool_window_on_reset_clicked (EditingToolsStraightenToolStraightenToolWindow* self);
static GObject * editing_tools_straighten_tool_straighten_tool_window_constructor (GType type,
                                                                            guint n_construct_properties,
                                                                            GObjectConstructParam * construct_properties);
static void _editing_tools_straighten_tool_straighten_tool_window_on_reset_clicked_gtk_button_clicked (GtkButton* _sender,
                                                                                                gpointer self);
static void editing_tools_straighten_tool_straighten_tool_window_finalize (GObject * obj);
static GType editing_tools_straighten_tool_straighten_tool_window_get_type_once (void);
static void editing_tools_straighten_tool_finalize (GObject * obj);
static GType editing_tools_straighten_tool_get_type_once (void);

static const gdouble EDITING_TOOLS_STRAIGHTEN_TOOL_GUIDE_DASH[2] = {(gdouble) 10, (gdouble) 10};

static inline gpointer
editing_tools_straighten_tool_get_instance_private (EditingToolsStraightenTool* self)
{
	return G_STRUCT_MEMBER_P (self, EditingToolsStraightenTool_private_offset);
}

static EditingToolsStraightenTool*
editing_tools_straighten_tool_construct (GType object_type)
{
	EditingToolsStraightenTool * self = NULL;
	self = (EditingToolsStraightenTool*) g_object_new (object_type, "name", "StraightenTool", NULL);
	return self;
}

static EditingToolsStraightenTool*
editing_tools_straighten_tool_new (void)
{
	return editing_tools_straighten_tool_construct (EDITING_TOOLS_TYPE_STRAIGHTEN_TOOL);
}

EditingToolsStraightenTool*
editing_tools_straighten_tool_factory (void)
{
	EditingToolsStraightenTool* _tmp0_;
	EditingToolsStraightenTool* result;
	_tmp0_ = editing_tools_straighten_tool_new ();
	result = _tmp0_;
	return result;
}

gboolean
editing_tools_straighten_tool_is_available (Photo* photo,
                                            Scaling* scaling)
{
	gboolean result;
	g_return_val_if_fail (photo != NULL, FALSE);
	g_return_val_if_fail (scaling != NULL, FALSE);
	result = TRUE;
	return result;
}

/**
     * Signal handler for when the 'OK' button has been clicked.  Computes where a previously-
     * set crop region should have rotated to (to match the Photo's straightening angle).
     *
     * Note: After this has been called against a Photo, it will always have a crop region; in the
     * case of a previously-uncropped Photo, the crop region will be set to the original dimensions
     * of the photo and centered at the Photo's center.
     */
static void
editing_tools_straighten_tool_on_ok_clicked (EditingToolsStraightenTool* self)
{
	EditingToolsPhotoCanvas* _tmp0_;
	Photo* _tmp1_;
	Photo* _tmp2_;
	gdouble slider_val = 0.0;
	EditingToolsStraightenToolStraightenToolWindow* _tmp3_;
	GtkScale* _tmp4_;
	GdkPoint new_crop_center = {0};
	GdkPoint _tmp5_;
	Dimensions _tmp6_;
	Dimensions _tmp7_;
	GdkPoint _tmp8_ = {0};
	StraightenCommand* command = NULL;
	EditingToolsPhotoCanvas* _tmp9_;
	Photo* _tmp10_;
	Photo* _tmp11_;
	GdkPoint _tmp12_;
	Box _tmp13_ = {0};
	StraightenCommand* _tmp14_;
	EditingToolsPhotoCanvas* _tmp15_;
	GdkPixbuf* _tmp16_;
	GdkPixbuf* _tmp17_;
	Dimensions _tmp18_;
	g_return_if_fail (self != NULL);
	_tmp0_ = ((EditingToolsEditingTool*) self)->canvas;
	_tmp1_ = editing_tools_photo_canvas_get_photo (_tmp0_);
	_tmp2_ = _tmp1_;
	_vala_assert (_tmp2_ != NULL, "canvas.photo != null");
	_tmp3_ = self->priv->window;
	_tmp4_ = _tmp3_->angle_slider;
	slider_val = gtk_range_get_value ((GtkRange*) _tmp4_);
	_tmp5_ = self->priv->rotated_center;
	_tmp6_ = self->priv->image_dims;
	_tmp7_ = self->priv->image_dims;
	rotate_point_arb (&_tmp5_, _tmp6_.width, _tmp7_.height, slider_val, FALSE, &_tmp8_);
	new_crop_center = _tmp8_;
	_tmp9_ = ((EditingToolsEditingTool*) self)->canvas;
	_tmp10_ = editing_tools_photo_canvas_get_photo (_tmp9_);
	_tmp11_ = _tmp10_;
	_tmp12_ = new_crop_center;
	box_from_center (&_tmp12_, (gint) (self->priv->rotate_scale * self->priv->crop_width), (gint) (self->priv->rotate_scale * self->priv->crop_height), &_tmp13_);
	_tmp14_ = straighten_command_new (_tmp11_, slider_val, &_tmp13_, RESOURCES_STRAIGHTEN_LABEL, RESOURCES_STRAIGHTEN_TOOLTIP);
	command = _tmp14_;
	_tmp15_ = ((EditingToolsEditingTool*) self)->canvas;
	_tmp16_ = editing_tools_photo_canvas_get_scaled_pixbuf (_tmp15_);
	_tmp17_ = _tmp16_;
	_tmp18_ = self->priv->image_dims;
	g_signal_emit_by_name ((EditingToolsEditingTool*) self, "applied", (Command*) command, _tmp17_, &_tmp18_, TRUE);
	_g_object_unref0 (command);
}

static void
editing_tools_straighten_tool_high_qual_repaint (EditingToolsStraightenTool* self)
{
	EditingToolsPhotoCanvas* _tmp0_;
	g_return_if_fail (self != NULL);
	self->priv->use_high_qual = TRUE;
	editing_tools_straighten_tool_update_rotated_surface (self);
	_tmp0_ = ((EditingToolsEditingTool*) self)->canvas;
	editing_tools_photo_canvas_repaint (_tmp0_);
}

static void
editing_tools_straighten_tool_on_slider_stopped_delayed (EditingToolsStraightenTool* self)
{
	g_return_if_fail (self != NULL);
	editing_tools_straighten_tool_high_qual_repaint (self);
}

static void
editing_tools_straighten_tool_real_on_left_click (EditingToolsEditingTool* base,
                                                  gint x,
                                                  gint y)
{
	EditingToolsStraightenTool * self;
	EditingToolsStraightenToolStraightenGuide* _tmp0_;
	self = (EditingToolsStraightenTool*) base;
	x = x * self->priv->scale_factor;
	y = y * self->priv->scale_factor;
	_tmp0_ = self->priv->guide;
	editing_tools_straighten_tool_straighten_guide_reset (_tmp0_, x, y, self->priv->photo_angle);
}

static void
editing_tools_straighten_tool_real_on_left_released (EditingToolsEditingTool* base,
                                                     gint x,
                                                     gint y)
{
	EditingToolsStraightenTool * self;
	EditingToolsStraightenToolStraightenGuide* _tmp0_;
	gdouble* a = NULL;
	EditingToolsStraightenToolStraightenGuide* _tmp1_;
	gdouble* _tmp2_;
	EditingToolsStraightenToolStraightenGuide* _tmp3_;
	gdouble* _tmp4_;
	self = (EditingToolsStraightenTool*) base;
	x = x * self->priv->scale_factor;
	y = y * self->priv->scale_factor;
	_tmp0_ = self->priv->guide;
	editing_tools_straighten_tool_straighten_guide_update (_tmp0_, x, y);
	_tmp1_ = self->priv->guide;
	_tmp2_ = editing_tools_straighten_tool_straighten_guide_get_angle (_tmp1_);
	a = _tmp2_;
	_tmp3_ = self->priv->guide;
	editing_tools_straighten_tool_straighten_guide_clear (_tmp3_);
	_tmp4_ = a;
	if (_tmp4_ != NULL) {
		EditingToolsStraightenToolStraightenToolWindow* _tmp5_;
		GtkScale* _tmp6_;
		gdouble* _tmp7_;
		_tmp5_ = self->priv->window;
		_tmp6_ = _tmp5_->angle_slider;
		_tmp7_ = a;
		gtk_range_set_value ((GtkRange*) _tmp6_, *_tmp7_);
		editing_tools_straighten_tool_high_qual_repaint (self);
	}
	_g_free0 (a);
}

static void
editing_tools_straighten_tool_real_on_motion (EditingToolsEditingTool* base,
                                              gint x,
                                              gint y,
                                              GdkModifierType mask)
{
	EditingToolsStraightenTool * self;
	EditingToolsStraightenToolStraightenGuide* _tmp0_;
	self = (EditingToolsStraightenTool*) base;
	x = x * self->priv->scale_factor;
	y = y * self->priv->scale_factor;
	_tmp0_ = self->priv->guide;
	if (editing_tools_straighten_tool_straighten_guide_update (_tmp0_, x, y)) {
		EditingToolsPhotoCanvas* _tmp1_;
		_tmp1_ = ((EditingToolsEditingTool*) self)->canvas;
		editing_tools_photo_canvas_repaint (_tmp1_);
	}
}

static gboolean
editing_tools_straighten_tool_real_on_keypress (EditingToolsEditingTool* base,
                                                GdkEventKey* event)
{
	EditingToolsStraightenTool * self;
	gboolean _tmp0_ = FALSE;
	gboolean _tmp1_ = FALSE;
	const gchar* _tmp2_;
	const gchar* _tmp5_;
	gboolean result;
	self = (EditingToolsStraightenTool*) base;
	g_return_val_if_fail (event != NULL, FALSE);
	_tmp2_ = gdk_keyval_name (event->keyval);
	if (g_strcmp0 (_tmp2_, "KP_Enter") == 0) {
		_tmp1_ = TRUE;
	} else {
		const gchar* _tmp3_;
		_tmp3_ = gdk_keyval_name (event->keyval);
		_tmp1_ = g_strcmp0 (_tmp3_, "Enter") == 0;
	}
	if (_tmp1_) {
		_tmp0_ = TRUE;
	} else {
		const gchar* _tmp4_;
		_tmp4_ = gdk_keyval_name (event->keyval);
		_tmp0_ = g_strcmp0 (_tmp4_, "Return") == 0;
	}
	if (_tmp0_) {
		editing_tools_straighten_tool_on_ok_clicked (self);
		result = TRUE;
		return result;
	}
	_tmp5_ = gdk_keyval_name (event->keyval);
	if (g_strcmp0 (_tmp5_, "Escape") == 0) {
		editing_tools_editing_tool_notify_cancel ((EditingToolsEditingTool*) self);
		result = TRUE;
		return result;
	}
	result = EDITING_TOOLS_EDITING_TOOL_CLASS (editing_tools_straighten_tool_parent_class)->on_keypress (G_TYPE_CHECK_INSTANCE_CAST (self, EDITING_TOOLS_TYPE_EDITING_TOOL, EditingToolsEditingTool), event);
	return result;
}

static gboolean
_dimensions_equal (const Dimensions * s1,
                   const Dimensions * s2)
{
	if (s1 == s2) {
		return TRUE;
	}
	if (s1 == NULL) {
		return FALSE;
	}
	if (s2 == NULL) {
		return FALSE;
	}
	if (s1->width != s2->width) {
		return FALSE;
	}
	if (s1->height != s2->height) {
		return FALSE;
	}
	return TRUE;
}

static void
editing_tools_straighten_tool_prepare_image (EditingToolsStraightenTool* self)
{
	Dimensions canvas_dims = {0};
	EditingToolsPhotoCanvas* _tmp0_;
	Dimensions _tmp1_ = {0};
	Dimensions _tmp2_;
	Dimensions viewport = {0};
	Dimensions _tmp3_ = {0};
	Dimensions _tmp4_;
	Dimensions _tmp5_;
	Dimensions _tmp6_;
	GdkPixbuf* low_res_tmp = NULL;
	GdkPixbuf* _tmp21_;
	gint _tmp22_;
	gint _tmp23_;
	Dimensions _tmp24_;
	GdkPixbuf* _tmp25_;
	gint _tmp26_;
	gint _tmp27_;
	GdkPixbuf* _tmp28_;
	gint _tmp29_;
	gint _tmp30_;
	cairo_surface_t* _tmp31_;
	cairo_t* ctx = NULL;
	cairo_surface_t* _tmp32_;
	cairo_t* _tmp33_;
	cairo_t* _tmp34_;
	GdkPixbuf* _tmp35_;
	cairo_t* _tmp36_;
	GdkPixbuf* _tmp37_;
	gint _tmp38_;
	gint _tmp39_;
	GdkPixbuf* _tmp40_;
	gint _tmp41_;
	gint _tmp42_;
	cairo_t* _tmp43_;
	cairo_t* _tmp44_;
	cairo_surface_t* _tmp45_;
	cairo_surface_t* _tmp46_;
	cairo_t* _tmp47_;
	GError* _inner_error0_ = NULL;
	g_return_if_fail (self != NULL);
	_tmp0_ = ((EditingToolsEditingTool*) self)->canvas;
	editing_tools_photo_canvas_get_surface_dim (_tmp0_, &_tmp1_);
	_tmp2_ = _tmp1_;
	canvas_dims = _tmp2_;
	dimensions_with_max (&canvas_dims, EDITING_TOOLS_STRAIGHTEN_TOOL_TEMP_PIXBUF_SIZE * self->priv->scale_factor, EDITING_TOOLS_STRAIGHTEN_TOOL_TEMP_PIXBUF_SIZE * self->priv->scale_factor, &_tmp3_);
	viewport = _tmp3_;
	_tmp4_ = viewport;
	_tmp5_ = self->priv->last_viewport;
	if (_dimensions_equal (&_tmp4_, &_tmp5_) == TRUE) {
		return;
	}
	_tmp6_ = viewport;
	self->priv->last_viewport = _tmp6_;
	low_res_tmp = NULL;
	{
		GdkPixbuf* _tmp7_ = NULL;
		EditingToolsPhotoCanvas* _tmp8_;
		Photo* _tmp9_;
		Photo* _tmp10_;
		Dimensions _tmp11_;
		Scaling _tmp12_ = {0};
		GdkPixbuf* _tmp13_;
		GdkPixbuf* _tmp14_;
		_tmp8_ = ((EditingToolsEditingTool*) self)->canvas;
		_tmp9_ = editing_tools_photo_canvas_get_photo (_tmp8_);
		_tmp10_ = _tmp9_;
		_tmp11_ = viewport;
		scaling_for_viewport (&_tmp11_, FALSE, &_tmp12_);
		_tmp13_ = photo_get_pixbuf_with_options (_tmp10_, &_tmp12_, PHOTO_EXCEPTION_STRAIGHTEN | PHOTO_EXCEPTION_CROP, BACKING_FETCH_MODE_BASELINE, &_inner_error0_);
		_tmp7_ = _tmp13_;
		if (G_UNLIKELY (_inner_error0_ != NULL)) {
			goto __catch0_g_error;
		}
		_tmp14_ = _tmp7_;
		_tmp7_ = NULL;
		_g_object_unref0 (low_res_tmp);
		low_res_tmp = _tmp14_;
		_g_object_unref0 (_tmp7_);
	}
	goto __finally0;
	__catch0_g_error:
	{
		EditingToolsPhotoCanvas* _tmp15_;
		Photo* _tmp16_;
		Photo* _tmp17_;
		gchar* _tmp18_;
		gchar* _tmp19_;
		GdkPixbuf* _tmp20_;
		g_clear_error (&_inner_error0_);
		_tmp15_ = ((EditingToolsEditingTool*) self)->canvas;
		_tmp16_ = editing_tools_photo_canvas_get_photo (_tmp15_);
		_tmp17_ = _tmp16_;
		_tmp18_ = data_object_to_string ((DataObject*) _tmp17_);
		_tmp19_ = _tmp18_;
		g_warning ("StraightenTool.vala:310: A pixbuf for %s couldn't be fetched.", _tmp19_);
		_g_free0 (_tmp19_);
		_tmp20_ = gdk_pixbuf_new (GDK_COLORSPACE_RGB, FALSE, 8, 1, 1);
		_g_object_unref0 (low_res_tmp);
		low_res_tmp = _tmp20_;
	}
	__finally0:
	if (G_UNLIKELY (_inner_error0_ != NULL)) {
		_g_object_unref0 (low_res_tmp);
		g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error0_->message, g_quark_to_string (_inner_error0_->domain), _inner_error0_->code);
		g_clear_error (&_inner_error0_);
		return;
	}
	_tmp21_ = low_res_tmp;
	_tmp22_ = gdk_pixbuf_get_width (_tmp21_);
	_tmp23_ = _tmp22_;
	_tmp24_ = self->priv->image_dims;
	self->priv->preview_scale = _tmp23_ / ((gdouble) _tmp24_.width);
	_tmp25_ = low_res_tmp;
	_tmp26_ = gdk_pixbuf_get_width (_tmp25_);
	_tmp27_ = _tmp26_;
	_tmp28_ = low_res_tmp;
	_tmp29_ = gdk_pixbuf_get_height (_tmp28_);
	_tmp30_ = _tmp29_;
	_tmp31_ = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, _tmp27_, _tmp30_);
	_cairo_surface_destroy0 (self->priv->photo_surf);
	self->priv->photo_surf = _tmp31_;
	_tmp32_ = self->priv->photo_surf;
	_tmp33_ = cairo_create (_tmp32_);
	ctx = _tmp33_;
	_tmp34_ = ctx;
	_tmp35_ = low_res_tmp;
	gdk_cairo_set_source_pixbuf (_tmp34_, _tmp35_, (gdouble) 0, (gdouble) 0);
	_tmp36_ = ctx;
	_tmp37_ = low_res_tmp;
	_tmp38_ = gdk_pixbuf_get_width (_tmp37_);
	_tmp39_ = _tmp38_;
	_tmp40_ = low_res_tmp;
	_tmp41_ = gdk_pixbuf_get_height (_tmp40_);
	_tmp42_ = _tmp41_;
	cairo_rectangle (_tmp36_, (gdouble) 0, (gdouble) 0, (gdouble) _tmp39_, (gdouble) _tmp42_);
	_tmp43_ = ctx;
	cairo_fill (_tmp43_);
	_tmp44_ = ctx;
	cairo_paint (_tmp44_);
	self->priv->view_width = (gint) (self->priv->crop_width * self->priv->preview_scale);
	self->priv->view_height = (gint) (self->priv->crop_height * self->priv->preview_scale);
	_tmp45_ = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, self->priv->view_width, self->priv->view_height);
	_cairo_surface_destroy0 (self->priv->rotate_surf);
	self->priv->rotate_surf = _tmp45_;
	_tmp46_ = self->priv->rotate_surf;
	_tmp47_ = cairo_create (_tmp46_);
	_cairo_destroy0 (self->priv->rotate_ctx);
	self->priv->rotate_ctx = _tmp47_;
	_cairo_destroy0 (ctx);
	_g_object_unref0 (low_res_tmp);
}

static void
editing_tools_straighten_tool_adjust_for_rotation (EditingToolsStraightenTool* self)
{
	gdouble width = 0.0;
	gdouble height = 0.0;
	gdouble _tmp0_ = 0.0;
	gdouble _tmp1_ = 0.0;
	Dimensions _tmp2_;
	Dimensions _tmp3_;
	GdkPoint _tmp4_;
	gint radius_x = 0;
	gint radius_y = 0;
	GdkPoint _tmp5_;
	Dimensions _tmp6_;
	GdkPoint _tmp7_;
	Dimensions _tmp8_;
	g_return_if_fail (self != NULL);
	compute_arb_rotated_size ((gdouble) self->priv->crop_width, (gdouble) self->priv->crop_height, self->priv->photo_angle, &_tmp0_, &_tmp1_);
	width = _tmp0_;
	height = _tmp1_;
	_tmp2_ = self->priv->image_dims;
	_tmp3_ = self->priv->image_dims;
	self->priv->rotate_scale = MIN (_tmp2_.width / width, _tmp3_.height / height);
	self->priv->rotate_scale = MIN (self->priv->rotate_scale, 1.0);
	_tmp4_ = self->priv->crop_center;
	self->priv->rotated_center = _tmp4_;
	radius_x = (gint) ((self->priv->rotate_scale * width) / 2);
	radius_y = (gint) ((self->priv->rotate_scale * height) / 2);
	_tmp5_ = self->priv->rotated_center;
	_tmp6_ = self->priv->image_dims;
	self->priv->rotated_center.x = CLAMP (_tmp5_.x, radius_x, _tmp6_.width - radius_x);
	_tmp7_ = self->priv->rotated_center;
	_tmp8_ = self->priv->image_dims;
	self->priv->rotated_center.y = CLAMP (_tmp7_.y, radius_y, _tmp8_.height - radius_y);
}

/**
     * Spawn the tool window, set up the scratch surfaces and prepare the straightening
     * tool for use.  If a valid pixbuf of the incoming Photo can't be loaded for any
     * reason, the tool will use a 1x1 temporary image instead to avoid crashing.
     *
     * @param canvas The PhotoCanvas the tool's output should be painted to.
     */
static gpointer
_g_object_ref0 (gpointer self)
{
	return self ? g_object_ref (self) : NULL;
}

static void
editing_tools_straighten_tool_real_activate (EditingToolsEditingTool* base,
                                             EditingToolsPhotoCanvas* canvas)
{
	EditingToolsStraightenTool * self;
	GtkWindow* _tmp0_;
	GtkWindow* _tmp1_;
	gint _tmp2_;
	gint _tmp3_;
	EditingToolsPhotoCanvas* _tmp4_;
	EditingToolsPhotoCanvas* _tmp5_;
	Photo* _tmp6_;
	Photo* _tmp7_;
	Dimensions _tmp8_ = {0};
	Box crop_region = {0};
	Photo* _tmp9_;
	Photo* _tmp10_;
	Box _tmp11_ = {0};
	gboolean _tmp12_;
	gdouble incoming_angle = 0.0;
	Photo* _tmp15_;
	Photo* _tmp16_;
	gdouble _tmp17_ = 0.0;
	GdkPoint _tmp18_ = {0};
	Dimensions _tmp19_;
	Dimensions _tmp20_;
	GdkPoint _tmp21_ = {0};
	GdkWindow* _tmp22_;
	GdkWindow* _tmp23_;
	GdkDisplay* _tmp24_;
	GdkCursor* _tmp25_;
	GdkCursor* _tmp26_;
	GtkWindow* _tmp27_;
	GtkWindow* _tmp28_;
	EditingToolsStraightenToolStraightenToolWindow* _tmp29_;
	EditingToolsStraightenToolStraightenToolWindow* _tmp30_;
	GtkScale* _tmp31_;
	gchar* tmp = NULL;
	gchar* _tmp32_;
	EditingToolsStraightenToolStraightenToolWindow* _tmp33_;
	GtkLabel* _tmp34_;
	EditingToolsStraightenToolStraightenToolWindow* _tmp35_;
	self = (EditingToolsStraightenTool*) base;
	g_return_if_fail (canvas != NULL);
	_tmp0_ = editing_tools_photo_canvas_get_container (canvas);
	_tmp1_ = _tmp0_;
	_tmp2_ = gtk_widget_get_scale_factor ((GtkWidget*) _tmp1_);
	_tmp3_ = _tmp2_;
	self->priv->scale_factor = _tmp3_;
	EDITING_TOOLS_EDITING_TOOL_CLASS (editing_tools_straighten_tool_parent_class)->activate (G_TYPE_CHECK_INSTANCE_CAST (self, EDITING_TOOLS_TYPE_EDITING_TOOL, EditingToolsEditingTool), canvas);
	_tmp4_ = _g_object_ref0 (canvas);
	_g_object_unref0 (((EditingToolsEditingTool*) self)->canvas);
	((EditingToolsEditingTool*) self)->canvas = _tmp4_;
	_tmp5_ = ((EditingToolsEditingTool*) self)->canvas;
	editing_tools_straighten_tool_bind_canvas_handlers (self, _tmp5_);
	_tmp6_ = editing_tools_photo_canvas_get_photo (canvas);
	_tmp7_ = _tmp6_;
	media_source_get_dimensions ((MediaSource*) _tmp7_, PHOTO_EXCEPTION_STRAIGHTEN | PHOTO_EXCEPTION_CROP, &_tmp8_);
	self->priv->image_dims = _tmp8_;
	_tmp9_ = editing_tools_photo_canvas_get_photo (canvas);
	_tmp10_ = _tmp9_;
	_tmp12_ = photo_get_crop (_tmp10_, &_tmp11_, PHOTO_EXCEPTION_NONE);
	crop_region = _tmp11_;
	if (!_tmp12_) {
		Dimensions _tmp13_;
		Dimensions _tmp14_;
		crop_region.left = 0;
		_tmp13_ = self->priv->image_dims;
		crop_region.right = _tmp13_.width;
		crop_region.top = 0;
		_tmp14_ = self->priv->image_dims;
		crop_region.bottom = _tmp14_.height;
	}
	incoming_angle = 0.0;
	_tmp15_ = editing_tools_photo_canvas_get_photo (canvas);
	_tmp16_ = _tmp15_;
	photo_get_straighten (_tmp16_, &_tmp17_);
	incoming_angle = _tmp17_;
	box_get_center (&crop_region, &_tmp18_);
	_tmp19_ = self->priv->image_dims;
	_tmp20_ = self->priv->image_dims;
	derotate_point_arb (&_tmp18_, _tmp19_.width, _tmp20_.height, incoming_angle, &_tmp21_);
	self->priv->crop_center = _tmp21_;
	self->priv->crop_width = box_get_width (&crop_region);
	self->priv->crop_height = box_get_height (&crop_region);
	editing_tools_straighten_tool_adjust_for_rotation (self);
	editing_tools_straighten_tool_prepare_image (self);
	_tmp22_ = editing_tools_photo_canvas_get_drawing_window (canvas);
	_tmp23_ = _tmp22_;
	_tmp24_ = gdk_display_get_default ();
	_tmp25_ = gdk_cursor_new_for_display (_tmp24_, GDK_CROSSHAIR);
	_tmp26_ = _tmp25_;
	gdk_window_set_cursor (_tmp23_, _tmp26_);
	_g_object_unref0 (_tmp26_);
	_tmp27_ = editing_tools_photo_canvas_get_container (canvas);
	_tmp28_ = _tmp27_;
	_tmp29_ = editing_tools_straighten_tool_straighten_tool_window_new (_tmp28_);
	g_object_ref_sink (_tmp29_);
	_g_object_unref0 (self->priv->window);
	self->priv->window = _tmp29_;
	editing_tools_straighten_tool_bind_window_handlers (self);
	_tmp30_ = self->priv->window;
	_tmp31_ = _tmp30_->angle_slider;
	gtk_range_set_value ((GtkRange*) _tmp31_, incoming_angle);
	self->priv->photo_angle = incoming_angle;
	_tmp32_ = g_strdup_printf ("%2.1f°", incoming_angle);
	tmp = _tmp32_;
	_tmp33_ = self->priv->window;
	_tmp34_ = _tmp33_->angle_label;
	gtk_label_set_text (_tmp34_, tmp);
	editing_tools_straighten_tool_high_qual_repaint (self);
	_tmp35_ = self->priv->window;
	gtk_widget_show_all ((GtkWidget*) _tmp35_);
	_g_free0 (tmp);
}

/**
     * Tears down the tool window and frees resources.
     */
static void
editing_tools_straighten_tool_real_deactivate (EditingToolsEditingTool* base)
{
	EditingToolsStraightenTool * self;
	EditingToolsStraightenToolStraightenToolWindow* _tmp0_;
	EditingToolsPhotoCanvas* _tmp2_;
	self = (EditingToolsStraightenTool*) base;
	_tmp0_ = self->priv->window;
	if (_tmp0_ != NULL) {
		EditingToolsStraightenToolStraightenToolWindow* _tmp1_;
		editing_tools_straighten_tool_unbind_window_handlers (self);
		_tmp1_ = self->priv->window;
		gtk_widget_hide ((GtkWidget*) _tmp1_);
		_g_object_unref0 (self->priv->window);
		self->priv->window = NULL;
	}
	_tmp2_ = ((EditingToolsEditingTool*) self)->canvas;
	if (_tmp2_ != NULL) {
		EditingToolsPhotoCanvas* _tmp3_;
		EditingToolsPhotoCanvas* _tmp4_;
		GdkWindow* _tmp5_;
		GdkWindow* _tmp6_;
		_tmp3_ = ((EditingToolsEditingTool*) self)->canvas;
		editing_tools_straighten_tool_unbind_canvas_handlers (self, _tmp3_);
		_tmp4_ = ((EditingToolsEditingTool*) self)->canvas;
		_tmp5_ = editing_tools_photo_canvas_get_drawing_window (_tmp4_);
		_tmp6_ = _tmp5_;
		gdk_window_set_cursor (_tmp6_, NULL);
	}
	EDITING_TOOLS_EDITING_TOOL_CLASS (editing_tools_straighten_tool_parent_class)->deactivate (G_TYPE_CHECK_INSTANCE_CAST (self, EDITING_TOOLS_TYPE_EDITING_TOOL, EditingToolsEditingTool));
}

static void
_editing_tools_straighten_tool_on_resized_pixbuf_editing_tools_photo_canvas_resized_scaled_pixbuf (EditingToolsPhotoCanvas* _sender,
                                                                                                   Dimensions* old_dim,
                                                                                                   GdkPixbuf* scaled,
                                                                                                   GdkRectangle* scaled_position,
                                                                                                   gpointer self)
{
	editing_tools_straighten_tool_on_resized_pixbuf ((EditingToolsStraightenTool*) self, old_dim, scaled, scaled_position);
}

static void
editing_tools_straighten_tool_bind_canvas_handlers (EditingToolsStraightenTool* self,
                                                    EditingToolsPhotoCanvas* canvas)
{
	g_return_if_fail (self != NULL);
	g_return_if_fail (canvas != NULL);
	g_signal_connect_object (canvas, "resized-scaled-pixbuf", (GCallback) _editing_tools_straighten_tool_on_resized_pixbuf_editing_tools_photo_canvas_resized_scaled_pixbuf, self, 0);
}

static void
editing_tools_straighten_tool_unbind_canvas_handlers (EditingToolsStraightenTool* self,
                                                      EditingToolsPhotoCanvas* canvas)
{
	guint _tmp0_;
	g_return_if_fail (self != NULL);
	g_return_if_fail (canvas != NULL);
	g_signal_parse_name ("resized-scaled-pixbuf", EDITING_TOOLS_TYPE_PHOTO_CANVAS, &_tmp0_, NULL, FALSE);
	g_signal_handlers_disconnect_matched (canvas, G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA, _tmp0_, 0, NULL, (GCallback) _editing_tools_straighten_tool_on_resized_pixbuf_editing_tools_photo_canvas_resized_scaled_pixbuf, self);
}

static gboolean
_editing_tools_editing_tool_on_keypress_gtk_widget_key_press_event (GtkWidget* _sender,
                                                                    GdkEventKey* event,
                                                                    gpointer self)
{
	gboolean result;
	result = editing_tools_editing_tool_on_keypress ((EditingToolsEditingTool*) self, event);
	return result;
}

static void
_editing_tools_straighten_tool_on_ok_clicked_gtk_button_clicked (GtkButton* _sender,
                                                                 gpointer self)
{
	editing_tools_straighten_tool_on_ok_clicked ((EditingToolsStraightenTool*) self);
}

static void
_editing_tools_editing_tool_notify_cancel_gtk_button_clicked (GtkButton* _sender,
                                                              gpointer self)
{
	editing_tools_editing_tool_notify_cancel ((EditingToolsEditingTool*) self);
}

static void
_editing_tools_straighten_tool_on_angle_changed_gtk_range_value_changed (GtkRange* _sender,
                                                                         gpointer self)
{
	editing_tools_straighten_tool_on_angle_changed ((EditingToolsStraightenTool*) self);
}

static void
editing_tools_straighten_tool_bind_window_handlers (EditingToolsStraightenTool* self)
{
	EditingToolsStraightenToolStraightenToolWindow* _tmp0_;
	EditingToolsStraightenToolStraightenToolWindow* _tmp1_;
	GtkButton* _tmp2_;
	EditingToolsStraightenToolStraightenToolWindow* _tmp3_;
	GtkButton* _tmp4_;
	EditingToolsStraightenToolStraightenToolWindow* _tmp5_;
	GtkScale* _tmp6_;
	g_return_if_fail (self != NULL);
	_tmp0_ = self->priv->window;
	g_signal_connect_object ((GtkWidget*) _tmp0_, "key-press-event", (GCallback) _editing_tools_editing_tool_on_keypress_gtk_widget_key_press_event, (EditingToolsEditingTool*) self, 0);
	_tmp1_ = self->priv->window;
	_tmp2_ = _tmp1_->ok_button;
	g_signal_connect_object (_tmp2_, "clicked", (GCallback) _editing_tools_straighten_tool_on_ok_clicked_gtk_button_clicked, self, 0);
	_tmp3_ = self->priv->window;
	_tmp4_ = _tmp3_->cancel_button;
	g_signal_connect_object (_tmp4_, "clicked", (GCallback) _editing_tools_editing_tool_notify_cancel_gtk_button_clicked, (EditingToolsEditingTool*) self, 0);
	_tmp5_ = self->priv->window;
	_tmp6_ = _tmp5_->angle_slider;
	g_signal_connect_object ((GtkRange*) _tmp6_, "value-changed", (GCallback) _editing_tools_straighten_tool_on_angle_changed_gtk_range_value_changed, self, 0);
}

static void
editing_tools_straighten_tool_unbind_window_handlers (EditingToolsStraightenTool* self)
{
	EditingToolsStraightenToolStraightenToolWindow* _tmp0_;
	guint _tmp1_;
	EditingToolsStraightenToolStraightenToolWindow* _tmp2_;
	GtkButton* _tmp3_;
	guint _tmp4_;
	EditingToolsStraightenToolStraightenToolWindow* _tmp5_;
	GtkButton* _tmp6_;
	guint _tmp7_;
	EditingToolsStraightenToolStraightenToolWindow* _tmp8_;
	GtkScale* _tmp9_;
	guint _tmp10_;
	g_return_if_fail (self != NULL);
	_tmp0_ = self->priv->window;
	g_signal_parse_name ("key-press-event", gtk_widget_get_type (), &_tmp1_, NULL, FALSE);
	g_signal_handlers_disconnect_matched ((GtkWidget*) _tmp0_, G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA, _tmp1_, 0, NULL, (GCallback) _editing_tools_editing_tool_on_keypress_gtk_widget_key_press_event, (EditingToolsEditingTool*) self);
	_tmp2_ = self->priv->window;
	_tmp3_ = _tmp2_->ok_button;
	g_signal_parse_name ("clicked", gtk_button_get_type (), &_tmp4_, NULL, FALSE);
	g_signal_handlers_disconnect_matched (_tmp3_, G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA, _tmp4_, 0, NULL, (GCallback) _editing_tools_straighten_tool_on_ok_clicked_gtk_button_clicked, self);
	_tmp5_ = self->priv->window;
	_tmp6_ = _tmp5_->cancel_button;
	g_signal_parse_name ("clicked", gtk_button_get_type (), &_tmp7_, NULL, FALSE);
	g_signal_handlers_disconnect_matched (_tmp6_, G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA, _tmp7_, 0, NULL, (GCallback) _editing_tools_editing_tool_notify_cancel_gtk_button_clicked, (EditingToolsEditingTool*) self);
	_tmp8_ = self->priv->window;
	_tmp9_ = _tmp8_->angle_slider;
	g_signal_parse_name ("value-changed", gtk_range_get_type (), &_tmp10_, NULL, FALSE);
	g_signal_handlers_disconnect_matched ((GtkRange*) _tmp9_, G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA, _tmp10_, 0, NULL, (GCallback) _editing_tools_straighten_tool_on_angle_changed_gtk_range_value_changed, self);
}

static void
_editing_tools_straighten_tool_on_slider_stopped_delayed_one_shot_callback (gpointer self)
{
	editing_tools_straighten_tool_on_slider_stopped_delayed ((EditingToolsStraightenTool*) self);
}

static void
editing_tools_straighten_tool_on_angle_changed (EditingToolsStraightenTool* self)
{
	EditingToolsStraightenToolStraightenToolWindow* _tmp0_;
	GtkScale* _tmp1_;
	gchar* tmp = NULL;
	EditingToolsStraightenToolStraightenToolWindow* _tmp2_;
	GtkScale* _tmp3_;
	gchar* _tmp4_;
	EditingToolsStraightenToolStraightenToolWindow* _tmp5_;
	GtkLabel* _tmp6_;
	const gchar* _tmp7_;
	OneShotScheduler* _tmp8_;
	OneShotScheduler* _tmp10_;
	EditingToolsPhotoCanvas* _tmp11_;
	g_return_if_fail (self != NULL);
	_tmp0_ = self->priv->window;
	_tmp1_ = _tmp0_->angle_slider;
	self->priv->photo_angle = gtk_range_get_value ((GtkRange*) _tmp1_);
	_tmp2_ = self->priv->window;
	_tmp3_ = _tmp2_->angle_slider;
	_tmp4_ = g_strdup_printf ("%2.1f°", gtk_range_get_value ((GtkRange*) _tmp3_));
	tmp = _tmp4_;
	_tmp5_ = self->priv->window;
	_tmp6_ = _tmp5_->angle_label;
	_tmp7_ = tmp;
	gtk_label_set_text (_tmp6_, _tmp7_);
	_tmp8_ = self->priv->slider_sched;
	if (_tmp8_ == NULL) {
		OneShotScheduler* _tmp9_;
		_tmp9_ = one_shot_scheduler_new ("straighten", _editing_tools_straighten_tool_on_slider_stopped_delayed_one_shot_callback, self);
		_one_shot_scheduler_unref0 (self->priv->slider_sched);
		self->priv->slider_sched = _tmp9_;
	}
	_tmp10_ = self->priv->slider_sched;
	one_shot_scheduler_after_timeout (_tmp10_, (guint) EDITING_TOOLS_STRAIGHTEN_TOOL_REPAINT_ON_STOP_DELAY_MSEC, TRUE);
	self->priv->use_high_qual = FALSE;
	editing_tools_straighten_tool_adjust_for_rotation (self);
	editing_tools_straighten_tool_update_rotated_surface (self);
	_tmp11_ = ((EditingToolsEditingTool*) self)->canvas;
	editing_tools_photo_canvas_repaint (_tmp11_);
	_g_free0 (tmp);
}

/**
     * Called by the EditingHostPage when a resize event occurs.
     */
static void
editing_tools_straighten_tool_on_resized_pixbuf (EditingToolsStraightenTool* self,
                                                 Dimensions* old_dim,
                                                 GdkPixbuf* scaled,
                                                 GdkRectangle* scaled_position)
{
	g_return_if_fail (self != NULL);
	g_return_if_fail (old_dim != NULL);
	g_return_if_fail (scaled != NULL);
	g_return_if_fail (scaled_position != NULL);
	editing_tools_straighten_tool_prepare_image (self);
}

/**
     * Returns a reference to the current StraightenTool instance's tool window;
     * the PhotoPage uses this to control the tool window's positioning, etc.
     */
static EditingToolsEditingToolWindow*
editing_tools_straighten_tool_real_get_tool_window (EditingToolsEditingTool* base)
{
	EditingToolsStraightenTool * self;
	EditingToolsStraightenToolStraightenToolWindow* _tmp0_;
	EditingToolsEditingToolWindow* _tmp1_;
	EditingToolsEditingToolWindow* result;
	self = (EditingToolsStraightenTool*) base;
	_tmp0_ = self->priv->window;
	_tmp1_ = _g_object_ref0 ((EditingToolsEditingToolWindow*) _tmp0_);
	result = _tmp1_;
	return result;
}

/**
     * Draw the rotated photo and grid.
     */
static void
editing_tools_straighten_tool_update_rotated_surface (EditingToolsStraightenTool* self)
{
	cairo_surface_t* _tmp0_;
	cairo_t* _tmp1_;
	cairo_t* _tmp2_;
	cairo_t* _tmp3_;
	g_return_if_fail (self != NULL);
	_tmp0_ = self->priv->photo_surf;
	_tmp1_ = self->priv->rotate_ctx;
	editing_tools_straighten_tool_draw_rotated_source (self, _tmp0_, _tmp1_, self->priv->view_width, self->priv->view_height, self->priv->photo_angle);
	_tmp2_ = self->priv->rotate_ctx;
	cairo_set_line_width (_tmp2_, 1.0 * self->priv->scale_factor);
	_tmp3_ = self->priv->rotate_ctx;
	editing_tools_straighten_tool_draw_superimposed_grid (self, _tmp3_, self->priv->view_width, self->priv->view_height);
}

/**
     * Render a smaller, rotated version of the image, with a grid superimposed over it.
     *
     * @param ctx The rendering context of a 'scratch' Cairo surface.  The tool makes its own
     *      surfaces and contexts so it can have things set up exactly like it wants them, so
     *      it's not used.
     */
static void
editing_tools_straighten_tool_real_paint (EditingToolsEditingTool* base,
                                          cairo_t* ctx)
{
	EditingToolsStraightenTool * self;
	gint w = 0;
	EditingToolsPhotoCanvas* _tmp0_;
	GdkWindow* _tmp1_;
	GdkWindow* _tmp2_;
	gint h = 0;
	EditingToolsPhotoCanvas* _tmp3_;
	GdkWindow* _tmp4_;
	GdkWindow* _tmp5_;
	EditingToolsPhotoCanvas* _tmp6_;
	cairo_t* _tmp7_;
	cairo_t* _tmp8_;
	EditingToolsPhotoCanvas* _tmp9_;
	GtkStyleContext* _tmp10_;
	EditingToolsPhotoCanvas* _tmp11_;
	cairo_t* _tmp12_;
	cairo_t* _tmp13_;
	EditingToolsPhotoCanvas* _tmp14_;
	cairo_t* _tmp15_;
	cairo_t* _tmp16_;
	EditingToolsPhotoCanvas* _tmp17_;
	cairo_t* _tmp18_;
	cairo_t* _tmp19_;
	cairo_surface_t* _tmp20_;
	EditingToolsPhotoCanvas* _tmp21_;
	cairo_t* _tmp22_;
	cairo_t* _tmp23_;
	EditingToolsPhotoCanvas* _tmp24_;
	cairo_t* _tmp25_;
	cairo_t* _tmp26_;
	EditingToolsPhotoCanvas* _tmp27_;
	cairo_t* _tmp28_;
	cairo_t* _tmp29_;
	EditingToolsPhotoCanvas* _tmp30_;
	cairo_t* _tmp31_;
	cairo_t* _tmp32_;
	EditingToolsStraightenToolStraightenGuide* _tmp33_;
	EditingToolsPhotoCanvas* _tmp34_;
	cairo_t* _tmp35_;
	cairo_t* _tmp36_;
	self = (EditingToolsStraightenTool*) base;
	g_return_if_fail (ctx != NULL);
	_tmp0_ = ((EditingToolsEditingTool*) self)->canvas;
	_tmp1_ = editing_tools_photo_canvas_get_drawing_window (_tmp0_);
	_tmp2_ = _tmp1_;
	w = gdk_window_get_width (_tmp2_) * self->priv->scale_factor;
	_tmp3_ = ((EditingToolsEditingTool*) self)->canvas;
	_tmp4_ = editing_tools_photo_canvas_get_drawing_window (_tmp3_);
	_tmp5_ = _tmp4_;
	h = gdk_window_get_height (_tmp5_) * self->priv->scale_factor;
	_tmp6_ = ((EditingToolsEditingTool*) self)->canvas;
	_tmp7_ = editing_tools_photo_canvas_get_default_ctx (_tmp6_);
	_tmp8_ = _tmp7_;
	cairo_identity_matrix (_tmp8_);
	_tmp9_ = ((EditingToolsEditingTool*) self)->canvas;
	_tmp10_ = editing_tools_photo_canvas_get_style_context (_tmp9_);
	_tmp11_ = ((EditingToolsEditingTool*) self)->canvas;
	_tmp12_ = editing_tools_photo_canvas_get_default_ctx (_tmp11_);
	_tmp13_ = _tmp12_;
	gtk_render_background (_tmp10_, _tmp13_, (gdouble) 0, (gdouble) 0, (gdouble) w, (gdouble) h);
	_tmp14_ = ((EditingToolsEditingTool*) self)->canvas;
	_tmp15_ = editing_tools_photo_canvas_get_default_ctx (_tmp14_);
	_tmp16_ = _tmp15_;
	cairo_translate (_tmp16_, (w - self->priv->view_width) / 2.0, (h - self->priv->view_height) / 2.0);
	_tmp17_ = ((EditingToolsEditingTool*) self)->canvas;
	_tmp18_ = editing_tools_photo_canvas_get_default_ctx (_tmp17_);
	_tmp19_ = _tmp18_;
	_tmp20_ = self->priv->rotate_surf;
	cairo_set_source_surface (_tmp19_, _tmp20_, (gdouble) 0, (gdouble) 0);
	_tmp21_ = ((EditingToolsEditingTool*) self)->canvas;
	_tmp22_ = editing_tools_photo_canvas_get_default_ctx (_tmp21_);
	_tmp23_ = _tmp22_;
	cairo_rectangle (_tmp23_, (gdouble) 0, (gdouble) 0, (gdouble) self->priv->view_width, (gdouble) self->priv->view_height);
	_tmp24_ = ((EditingToolsEditingTool*) self)->canvas;
	_tmp25_ = editing_tools_photo_canvas_get_default_ctx (_tmp24_);
	_tmp26_ = _tmp25_;
	cairo_fill (_tmp26_);
	_tmp27_ = ((EditingToolsEditingTool*) self)->canvas;
	_tmp28_ = editing_tools_photo_canvas_get_default_ctx (_tmp27_);
	_tmp29_ = _tmp28_;
	cairo_paint (_tmp29_);
	_tmp30_ = ((EditingToolsEditingTool*) self)->canvas;
	_tmp31_ = editing_tools_photo_canvas_get_default_ctx (_tmp30_);
	_tmp32_ = _tmp31_;
	cairo_identity_matrix (_tmp32_);
	_tmp33_ = self->priv->guide;
	_tmp34_ = ((EditingToolsEditingTool*) self)->canvas;
	_tmp35_ = editing_tools_photo_canvas_get_default_ctx (_tmp34_);
	_tmp36_ = _tmp35_;
	editing_tools_straighten_tool_straighten_guide_draw (_tmp33_, _tmp36_);
}

/**
     * Copy a rotated version of the source image onto the destination
     * context.
     *
     * @param src_surf A Cairo surface containing the source image.
     * @param dest_ctx The rendering context of the destination image.
     * @param src_width The width of the image data in src_surf in pixels.
     * @param src_height The height of the image data in src_surf in pixels.
     * @param angle The angle the source image should be rotated by, in degrees.
     */
static void
editing_tools_straighten_tool_draw_rotated_source (EditingToolsStraightenTool* self,
                                                   cairo_surface_t* src_surf,
                                                   cairo_t* dest_ctx,
                                                   gint src_width,
                                                   gint src_height,
                                                   gdouble angle)
{
	gdouble angle_internal = 0.0;
	GdkPoint _tmp0_;
	GdkPoint _tmp1_;
	cairo_filter_t _tmp2_ = 0;
	cairo_pattern_t* _tmp3_;
	g_return_if_fail (self != NULL);
	g_return_if_fail (src_surf != NULL);
	g_return_if_fail (dest_ctx != NULL);
	angle_internal = degrees_to_radians (angle);
	cairo_identity_matrix (dest_ctx);
	cairo_set_source_rgba (dest_ctx, 0.0, 0.0, 0.0, 1.0);
	cairo_rectangle (dest_ctx, (gdouble) 0, (gdouble) 0, (gdouble) self->priv->view_width, (gdouble) self->priv->view_height);
	cairo_fill (dest_ctx);
	cairo_identity_matrix (dest_ctx);
	cairo_translate (dest_ctx, (gdouble) (self->priv->view_width / 2), (gdouble) (self->priv->view_height / 2));
	cairo_scale (dest_ctx, 1.0 / self->priv->rotate_scale, 1.0 / self->priv->rotate_scale);
	cairo_rotate (dest_ctx, angle_internal);
	_tmp0_ = self->priv->rotated_center;
	_tmp1_ = self->priv->rotated_center;
	cairo_translate (dest_ctx, (-_tmp0_.x) * self->priv->preview_scale, (-_tmp1_.y) * self->priv->preview_scale);
	cairo_set_source_surface (dest_ctx, src_surf, (gdouble) 0, (gdouble) 0);
	if (self->priv->use_high_qual) {
		_tmp2_ = CAIRO_FILTER_BEST;
	} else {
		_tmp2_ = CAIRO_FILTER_NEAREST;
	}
	_tmp3_ = cairo_get_source (dest_ctx);
	cairo_pattern_set_filter (_tmp3_, _tmp2_);
	cairo_rectangle (dest_ctx, (gdouble) 0, (gdouble) 0, (gdouble) src_width, (gdouble) src_height);
	cairo_fill (dest_ctx);
	cairo_paint (dest_ctx);
}

/**
     * Superimpose a faint grid over the supplied image.
     *
     * @param width The total width the grid should be drawn to.
     * @param height The total height the grid should be drawn to.
     * @param dest_ctx The rendering context of the destination image.
     */
static void
editing_tools_straighten_tool_draw_superimposed_grid (EditingToolsStraightenTool* self,
                                                      cairo_t* dest_ctx,
                                                      gint width,
                                                      gint height)
{
	gint half_width = 0;
	gint quarter_width = 0;
	gint half_height = 0;
	gint quarter_height = 0;
	EditingToolsPhotoCanvas* _tmp0_;
	EditingToolsPhotoCanvas* _tmp1_;
	EditingToolsPhotoCanvas* _tmp2_;
	EditingToolsPhotoCanvas* _tmp3_;
	EditingToolsPhotoCanvas* _tmp4_;
	EditingToolsPhotoCanvas* _tmp5_;
	EditingToolsPhotoCanvas* _tmp6_;
	EditingToolsPhotoCanvas* _tmp7_;
	EditingToolsPhotoCanvas* _tmp8_;
	EditingToolsPhotoCanvas* _tmp9_;
	g_return_if_fail (self != NULL);
	g_return_if_fail (dest_ctx != NULL);
	half_width = width / 2;
	quarter_width = width / 4;
	half_height = height / 2;
	quarter_height = height / 4;
	cairo_identity_matrix (dest_ctx);
	cairo_set_source_rgba (dest_ctx, 1.0, 1.0, 1.0, 1.0);
	_tmp0_ = ((EditingToolsEditingTool*) self)->canvas;
	editing_tools_photo_canvas_draw_horizontal_line (_tmp0_, dest_ctx, 0, 0, width, FALSE);
	_tmp1_ = ((EditingToolsEditingTool*) self)->canvas;
	editing_tools_photo_canvas_draw_horizontal_line (_tmp1_, dest_ctx, 0, half_height, width, FALSE);
	_tmp2_ = ((EditingToolsEditingTool*) self)->canvas;
	editing_tools_photo_canvas_draw_horizontal_line (_tmp2_, dest_ctx, 0, self->priv->view_height - 1, width, FALSE);
	_tmp3_ = ((EditingToolsEditingTool*) self)->canvas;
	editing_tools_photo_canvas_draw_vertical_line (_tmp3_, dest_ctx, 0, 0, height + 1, FALSE);
	_tmp4_ = ((EditingToolsEditingTool*) self)->canvas;
	editing_tools_photo_canvas_draw_vertical_line (_tmp4_, dest_ctx, half_width, 0, height + 1, FALSE);
	_tmp5_ = ((EditingToolsEditingTool*) self)->canvas;
	editing_tools_photo_canvas_draw_vertical_line (_tmp5_, dest_ctx, width - 1, 0, height + 1, FALSE);
	cairo_set_source_rgba (dest_ctx, 1.0, 1.0, 1.0, 0.33);
	_tmp6_ = ((EditingToolsEditingTool*) self)->canvas;
	editing_tools_photo_canvas_draw_horizontal_line (_tmp6_, dest_ctx, 0, quarter_height, width, FALSE);
	_tmp7_ = ((EditingToolsEditingTool*) self)->canvas;
	editing_tools_photo_canvas_draw_horizontal_line (_tmp7_, dest_ctx, 0, half_height + quarter_height, width, FALSE);
	_tmp8_ = ((EditingToolsEditingTool*) self)->canvas;
	editing_tools_photo_canvas_draw_vertical_line (_tmp8_, dest_ctx, quarter_width, 0, height, FALSE);
	_tmp9_ = ((EditingToolsEditingTool*) self)->canvas;
	editing_tools_photo_canvas_draw_vertical_line (_tmp9_, dest_ctx, half_width + quarter_width, 0, height, FALSE);
}

static inline gpointer
editing_tools_straighten_tool_straighten_guide_get_instance_private (EditingToolsStraightenToolStraightenGuide* self)
{
	return G_STRUCT_MEMBER_P (self, EditingToolsStraightenToolStraightenGuide_private_offset);
}

static void
editing_tools_straighten_tool_straighten_guide_reset (EditingToolsStraightenToolStraightenGuide* self,
                                                      gint x,
                                                      gint y,
                                                      gdouble angle)
{
	gint _tmp0_[2] = {0};
	gint _tmp1_[2] = {0};
	g_return_if_fail (self != NULL);
	_tmp0_[0] = x;
	_tmp0_[1] = x;
	memcpy (self->priv->x, _tmp0_, 2 * sizeof (gint));
	_tmp1_[0] = y;
	_tmp1_[1] = y;
	memcpy (self->priv->y, _tmp1_, 2 * sizeof (gint));
	self->priv->is_active = TRUE;
	self->priv->angle0 = angle;
}

static gboolean
editing_tools_straighten_tool_straighten_guide_update (EditingToolsStraightenToolStraightenGuide* self,
                                                       gint x,
                                                       gint y)
{
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	if (self->priv->is_active) {
		self->priv->x[1] = x;
		self->priv->y[1] = y;
		result = TRUE;
		return result;
	}
	result = FALSE;
	return result;
}

static void
editing_tools_straighten_tool_straighten_guide_clear (EditingToolsStraightenToolStraightenGuide* self)
{
	g_return_if_fail (self != NULL);
	self->priv->is_active = FALSE;
}

static gdouble*
_double_dup (gdouble* self)
{
	gdouble* dup;
	dup = g_new0 (gdouble, 1);
	memcpy (dup, self, sizeof (gdouble));
	return dup;
}

static gpointer
__double_dup0 (gpointer self)
{
	return self ? _double_dup (self) : NULL;
}

static gdouble*
editing_tools_straighten_tool_straighten_guide_get_angle (EditingToolsStraightenToolStraightenGuide* self)
{
	gdouble dx = 0.0;
	gint _tmp0_;
	gint _tmp1_;
	gdouble dy = 0.0;
	gint _tmp2_;
	gint _tmp3_;
	gdouble* result;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = self->priv->x[1];
	_tmp1_ = self->priv->x[0];
	dx = (gdouble) (_tmp0_ - _tmp1_);
	_tmp2_ = self->priv->y[1];
	_tmp3_ = self->priv->y[0];
	dy = (gdouble) (_tmp2_ - _tmp3_);
	if (((dy * dy) + (dx * dx)) < ((gdouble) 40)) {
		result = NULL;
		return result;
	}
	if (fabs (dy) > fabs (dx)) {
		gdouble _tmp4_;
		gdouble* _tmp5_;
		_tmp4_ = self->priv->angle0 + ((atan (dx / dy) / G_PI) * 180);
		_tmp5_ = __double_dup0 (&_tmp4_);
		result = _tmp5_;
		return result;
	} else {
		gdouble _tmp6_;
		gdouble* _tmp7_;
		_tmp6_ = self->priv->angle0 - ((atan (dy / dx) / G_PI) * 180);
		_tmp7_ = __double_dup0 (&_tmp6_);
		result = _tmp7_;
		return result;
	}
}

static void
editing_tools_straighten_tool_straighten_guide_draw (EditingToolsStraightenToolStraightenGuide* self,
                                                     cairo_t* ctx)
{
	gdouble* _tmp0_ = NULL;
	gdouble* _tmp1_;
	gdouble angle = 0.0;
	gdouble* _tmp4_;
	gdouble* _tmp5_;
	gdouble _tmp6_;
	gdouble alpha = 0.0;
	gboolean _tmp7_ = FALSE;
	gdouble _tmp8_;
	gint _tmp9_;
	gint _tmp10_;
	gint _tmp11_;
	gint _tmp12_;
	gdouble _tmp13_;
	gint _tmp14_;
	gint _tmp15_;
	gint _tmp16_;
	gint _tmp17_;
	g_return_if_fail (self != NULL);
	g_return_if_fail (ctx != NULL);
	if (!self->priv->is_active) {
		return;
	}
	_tmp1_ = editing_tools_straighten_tool_straighten_guide_get_angle (self);
	_tmp0_ = _tmp1_;
	if (_tmp0_ == NULL) {
		gdouble _tmp2_;
		gdouble* _tmp3_;
		_tmp2_ = 0.0;
		_tmp3_ = __double_dup0 (&_tmp2_);
		_g_free0 (_tmp0_);
		_tmp0_ = _tmp3_;
	}
	_tmp4_ = _tmp0_;
	_tmp0_ = NULL;
	_tmp5_ = _tmp4_;
	_tmp6_ = *_tmp5_;
	_g_free0 (_tmp5_);
	angle = _tmp6_;
	if (angle == 0.0) {
		_g_free0 (_tmp0_);
		return;
	}
	alpha = 1.0;
	if (angle < EDITING_TOOLS_STRAIGHTEN_TOOL_MIN_ANGLE) {
		_tmp7_ = TRUE;
	} else {
		_tmp7_ = angle > EDITING_TOOLS_STRAIGHTEN_TOOL_MAX_ANGLE;
	}
	if (_tmp7_) {
		alpha = 0.35;
	}
	cairo_set_source_rgba (ctx, 0.0, 0.0, 0.0, alpha);
	_tmp8_ = EDITING_TOOLS_STRAIGHTEN_TOOL_GUIDE_DASH[0];
	cairo_set_dash (ctx, EDITING_TOOLS_STRAIGHTEN_TOOL_GUIDE_DASH, (gint) G_N_ELEMENTS (EDITING_TOOLS_STRAIGHTEN_TOOL_GUIDE_DASH), _tmp8_ / 2);
	_tmp9_ = self->priv->x[0];
	_tmp10_ = self->priv->y[0];
	cairo_move_to (ctx, _tmp9_ + 0.5, _tmp10_ + 0.5);
	_tmp11_ = self->priv->x[1];
	_tmp12_ = self->priv->y[1];
	cairo_line_to (ctx, _tmp11_ + 0.5, _tmp12_ + 0.5);
	cairo_stroke (ctx);
	_tmp13_ = EDITING_TOOLS_STRAIGHTEN_TOOL_GUIDE_DASH[0];
	cairo_set_dash (ctx, EDITING_TOOLS_STRAIGHTEN_TOOL_GUIDE_DASH, (gint) G_N_ELEMENTS (EDITING_TOOLS_STRAIGHTEN_TOOL_GUIDE_DASH), (-_tmp13_) / 2);
	cairo_set_source_rgba (ctx, 1.0, 1.0, 1.0, alpha);
	_tmp14_ = self->priv->x[0];
	_tmp15_ = self->priv->y[0];
	cairo_move_to (ctx, _tmp14_ + 0.5, _tmp15_ + 0.5);
	_tmp16_ = self->priv->x[1];
	_tmp17_ = self->priv->y[1];
	cairo_line_to (ctx, _tmp16_ + 0.5, _tmp17_ + 0.5);
	cairo_stroke (ctx);
	_g_free0 (_tmp0_);
}

static EditingToolsStraightenToolStraightenGuide*
editing_tools_straighten_tool_straighten_guide_construct (GType object_type)
{
	EditingToolsStraightenToolStraightenGuide* self = NULL;
	self = (EditingToolsStraightenToolStraightenGuide*) g_type_create_instance (object_type);
	return self;
}

static EditingToolsStraightenToolStraightenGuide*
editing_tools_straighten_tool_straighten_guide_new (void)
{
	return editing_tools_straighten_tool_straighten_guide_construct (EDITING_TOOLS_STRAIGHTEN_TOOL_TYPE_STRAIGHTEN_GUIDE);
}

static void
editing_tools_straighten_tool_value_straighten_guide_init (GValue* value)
{
	value->data[0].v_pointer = NULL;
}

static void
editing_tools_straighten_tool_value_straighten_guide_free_value (GValue* value)
{
	if (value->data[0].v_pointer) {
		editing_tools_straighten_tool_straighten_guide_unref (value->data[0].v_pointer);
	}
}

static void
editing_tools_straighten_tool_value_straighten_guide_copy_value (const GValue* src_value,
                                                                 GValue* dest_value)
{
	if (src_value->data[0].v_pointer) {
		dest_value->data[0].v_pointer = editing_tools_straighten_tool_straighten_guide_ref (src_value->data[0].v_pointer);
	} else {
		dest_value->data[0].v_pointer = NULL;
	}
}

static gpointer
editing_tools_straighten_tool_value_straighten_guide_peek_pointer (const GValue* value)
{
	return value->data[0].v_pointer;
}

static gchar*
editing_tools_straighten_tool_value_straighten_guide_collect_value (GValue* value,
                                                                    guint n_collect_values,
                                                                    GTypeCValue* collect_values,
                                                                    guint collect_flags)
{
	if (collect_values[0].v_pointer) {
		EditingToolsStraightenToolStraightenGuide * object;
		object = collect_values[0].v_pointer;
		if (object->parent_instance.g_class == NULL) {
			return g_strconcat ("invalid unclassed object pointer for value type `", G_VALUE_TYPE_NAME (value), "'", NULL);
		} else if (!g_value_type_compatible (G_TYPE_FROM_INSTANCE (object), G_VALUE_TYPE (value))) {
			return g_strconcat ("invalid object type `", g_type_name (G_TYPE_FROM_INSTANCE (object)), "' for value type `", G_VALUE_TYPE_NAME (value), "'", NULL);
		}
		value->data[0].v_pointer = editing_tools_straighten_tool_straighten_guide_ref (object);
	} else {
		value->data[0].v_pointer = NULL;
	}
	return NULL;
}

static gchar*
editing_tools_straighten_tool_value_straighten_guide_lcopy_value (const GValue* value,
                                                                  guint n_collect_values,
                                                                  GTypeCValue* collect_values,
                                                                  guint collect_flags)
{
	EditingToolsStraightenToolStraightenGuide ** object_p;
	object_p = collect_values[0].v_pointer;
	if (!object_p) {
		return g_strdup_printf ("value location for `%s' passed as NULL", G_VALUE_TYPE_NAME (value));
	}
	if (!value->data[0].v_pointer) {
		*object_p = NULL;
	} else if (collect_flags & G_VALUE_NOCOPY_CONTENTS) {
		*object_p = value->data[0].v_pointer;
	} else {
		*object_p = editing_tools_straighten_tool_straighten_guide_ref (value->data[0].v_pointer);
	}
	return NULL;
}

static GParamSpec*
editing_tools_straighten_tool_param_spec_straighten_guide (const gchar* name,
                                                           const gchar* nick,
                                                           const gchar* blurb,
                                                           GType object_type,
                                                           GParamFlags flags)
{
	EditingToolsStraightenToolParamSpecStraightenGuide* spec;
	g_return_val_if_fail (g_type_is_a (object_type, EDITING_TOOLS_STRAIGHTEN_TOOL_TYPE_STRAIGHTEN_GUIDE), NULL);
	spec = g_param_spec_internal (G_TYPE_PARAM_OBJECT, name, nick, blurb, flags);
	G_PARAM_SPEC (spec)->value_type = object_type;
	return G_PARAM_SPEC (spec);
}

static gpointer
editing_tools_straighten_tool_value_get_straighten_guide (const GValue* value)
{
	g_return_val_if_fail (G_TYPE_CHECK_VALUE_TYPE (value, EDITING_TOOLS_STRAIGHTEN_TOOL_TYPE_STRAIGHTEN_GUIDE), NULL);
	return value->data[0].v_pointer;
}

static void
editing_tools_straighten_tool_value_set_straighten_guide (GValue* value,
                                                          gpointer v_object)
{
	EditingToolsStraightenToolStraightenGuide * old;
	g_return_if_fail (G_TYPE_CHECK_VALUE_TYPE (value, EDITING_TOOLS_STRAIGHTEN_TOOL_TYPE_STRAIGHTEN_GUIDE));
	old = value->data[0].v_pointer;
	if (v_object) {
		g_return_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (v_object, EDITING_TOOLS_STRAIGHTEN_TOOL_TYPE_STRAIGHTEN_GUIDE));
		g_return_if_fail (g_value_type_compatible (G_TYPE_FROM_INSTANCE (v_object), G_VALUE_TYPE (value)));
		value->data[0].v_pointer = v_object;
		editing_tools_straighten_tool_straighten_guide_ref (value->data[0].v_pointer);
	} else {
		value->data[0].v_pointer = NULL;
	}
	if (old) {
		editing_tools_straighten_tool_straighten_guide_unref (old);
	}
}

static void
editing_tools_straighten_tool_value_take_straighten_guide (GValue* value,
                                                           gpointer v_object)
{
	EditingToolsStraightenToolStraightenGuide * old;
	g_return_if_fail (G_TYPE_CHECK_VALUE_TYPE (value, EDITING_TOOLS_STRAIGHTEN_TOOL_TYPE_STRAIGHTEN_GUIDE));
	old = value->data[0].v_pointer;
	if (v_object) {
		g_return_if_fail (G_TYPE_CHECK_INSTANCE_TYPE (v_object, EDITING_TOOLS_STRAIGHTEN_TOOL_TYPE_STRAIGHTEN_GUIDE));
		g_return_if_fail (g_value_type_compatible (G_TYPE_FROM_INSTANCE (v_object), G_VALUE_TYPE (value)));
		value->data[0].v_pointer = v_object;
	} else {
		value->data[0].v_pointer = NULL;
	}
	if (old) {
		editing_tools_straighten_tool_straighten_guide_unref (old);
	}
}

static void
editing_tools_straighten_tool_straighten_guide_class_init (EditingToolsStraightenToolStraightenGuideClass * klass,
                                                           gpointer klass_data)
{
	editing_tools_straighten_tool_straighten_guide_parent_class = g_type_class_peek_parent (klass);
	((EditingToolsStraightenToolStraightenGuideClass *) klass)->finalize = editing_tools_straighten_tool_straighten_guide_finalize;
	g_type_class_adjust_private_offset (klass, &EditingToolsStraightenToolStraightenGuide_private_offset);
}

static void
editing_tools_straighten_tool_straighten_guide_instance_init (EditingToolsStraightenToolStraightenGuide * self,
                                                              gpointer klass)
{
	self->priv = editing_tools_straighten_tool_straighten_guide_get_instance_private (self);
	self->priv->is_active = FALSE;
	self->ref_count = 1;
}

static void
editing_tools_straighten_tool_straighten_guide_finalize (EditingToolsStraightenToolStraightenGuide * obj)
{
	EditingToolsStraightenToolStraightenGuide * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (obj, EDITING_TOOLS_STRAIGHTEN_TOOL_TYPE_STRAIGHTEN_GUIDE, EditingToolsStraightenToolStraightenGuide);
	g_signal_handlers_destroy (self);
}

static GType
editing_tools_straighten_tool_straighten_guide_get_type_once (void)
{
	static const GTypeValueTable g_define_type_value_table = { editing_tools_straighten_tool_value_straighten_guide_init, editing_tools_straighten_tool_value_straighten_guide_free_value, editing_tools_straighten_tool_value_straighten_guide_copy_value, editing_tools_straighten_tool_value_straighten_guide_peek_pointer, "p", editing_tools_straighten_tool_value_straighten_guide_collect_value, "p", editing_tools_straighten_tool_value_straighten_guide_lcopy_value };
	static const GTypeInfo g_define_type_info = { sizeof (EditingToolsStraightenToolStraightenGuideClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) editing_tools_straighten_tool_straighten_guide_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (EditingToolsStraightenToolStraightenGuide), 0, (GInstanceInitFunc) editing_tools_straighten_tool_straighten_guide_instance_init, &g_define_type_value_table };
	static const GTypeFundamentalInfo g_define_type_fundamental_info = { (G_TYPE_FLAG_CLASSED | G_TYPE_FLAG_INSTANTIATABLE | G_TYPE_FLAG_DERIVABLE | G_TYPE_FLAG_DEEP_DERIVABLE) };
	GType editing_tools_straighten_tool_straighten_guide_type_id;
	editing_tools_straighten_tool_straighten_guide_type_id = g_type_register_fundamental (g_type_fundamental_next (), "EditingToolsStraightenToolStraightenGuide", &g_define_type_info, &g_define_type_fundamental_info, 0);
	EditingToolsStraightenToolStraightenGuide_private_offset = g_type_add_instance_private (editing_tools_straighten_tool_straighten_guide_type_id, sizeof (EditingToolsStraightenToolStraightenGuidePrivate));
	return editing_tools_straighten_tool_straighten_guide_type_id;
}

static GType
editing_tools_straighten_tool_straighten_guide_get_type (void)
{
	static volatile gsize editing_tools_straighten_tool_straighten_guide_type_id__once = 0;
	if (g_once_init_enter (&editing_tools_straighten_tool_straighten_guide_type_id__once)) {
		GType editing_tools_straighten_tool_straighten_guide_type_id;
		editing_tools_straighten_tool_straighten_guide_type_id = editing_tools_straighten_tool_straighten_guide_get_type_once ();
		g_once_init_leave (&editing_tools_straighten_tool_straighten_guide_type_id__once, editing_tools_straighten_tool_straighten_guide_type_id);
	}
	return editing_tools_straighten_tool_straighten_guide_type_id__once;
}

static gpointer
editing_tools_straighten_tool_straighten_guide_ref (gpointer instance)
{
	EditingToolsStraightenToolStraightenGuide * self;
	self = instance;
	g_atomic_int_inc (&self->ref_count);
	return instance;
}

static void
editing_tools_straighten_tool_straighten_guide_unref (gpointer instance)
{
	EditingToolsStraightenToolStraightenGuide * self;
	self = instance;
	if (g_atomic_int_dec_and_test (&self->ref_count)) {
		EDITING_TOOLS_STRAIGHTEN_TOOL_STRAIGHTEN_GUIDE_GET_CLASS (self)->finalize (self);
		g_type_free_instance ((GTypeInstance *) self);
	}
}

/**
         * Prepare straighten tool's window for use and initialize all its controls.
         *
         * @param container The application's main window.
         */
static EditingToolsStraightenToolStraightenToolWindow*
editing_tools_straighten_tool_straighten_tool_window_construct (GType object_type,
                                                                GtkWindow* container)
{
	EditingToolsStraightenToolStraightenToolWindow * self = NULL;
	g_return_val_if_fail (container != NULL, NULL);
	self = (EditingToolsStraightenToolStraightenToolWindow*) g_object_new (object_type, "transient-for", container, NULL);
	return self;
}

static EditingToolsStraightenToolStraightenToolWindow*
editing_tools_straighten_tool_straighten_tool_window_new (GtkWindow* container)
{
	return editing_tools_straighten_tool_straighten_tool_window_construct (EDITING_TOOLS_STRAIGHTEN_TOOL_TYPE_STRAIGHTEN_TOOL_WINDOW, container);
}

static void
editing_tools_straighten_tool_straighten_tool_window_on_reset_clicked (EditingToolsStraightenToolStraightenToolWindow* self)
{
	GtkScale* _tmp0_;
	g_return_if_fail (self != NULL);
	_tmp0_ = self->angle_slider;
	gtk_range_set_value ((GtkRange*) _tmp0_, 0.0);
}

static void
_editing_tools_straighten_tool_straighten_tool_window_on_reset_clicked_gtk_button_clicked (GtkButton* _sender,
                                                                                           gpointer self)
{
	editing_tools_straighten_tool_straighten_tool_window_on_reset_clicked ((EditingToolsStraightenToolStraightenToolWindow*) self);
}

static GObject *
editing_tools_straighten_tool_straighten_tool_window_constructor (GType type,
                                                                  guint n_construct_properties,
                                                                  GObjectConstructParam * construct_properties)
{
	GObject * obj;
	GObjectClass * parent_class;
	EditingToolsStraightenToolStraightenToolWindow * self;
	GtkScale* _tmp0_;
	GtkScale* _tmp1_;
	GtkScale* _tmp2_;
	GtkLabel* _tmp3_;
	GtkLabel* _tmp4_;
	GtkLabel* _tmp5_;
	GtkBox* slider_layout = NULL;
	GtkBox* _tmp6_;
	GtkBox* _tmp7_;
	GtkScale* _tmp8_;
	GtkBox* button_layout = NULL;
	GtkBox* _tmp9_;
	GtkButton* _tmp10_;
	GtkButton* _tmp11_;
	GtkButton* _tmp12_;
	GtkBox* _tmp13_;
	GtkButton* _tmp14_;
	GtkBox* _tmp15_;
	GtkButton* _tmp16_;
	GtkBox* _tmp17_;
	GtkButton* _tmp18_;
	GtkBox* main_layout = NULL;
	GtkBox* _tmp19_;
	GtkBox* _tmp20_;
	GtkLabel* _tmp21_;
	GtkBox* _tmp22_;
	GtkBox* _tmp23_;
	GtkBox* _tmp24_;
	GtkLabel* _tmp25_;
	GtkBox* _tmp26_;
	GtkBox* _tmp27_;
	GtkGrid* _tmp28_;
	GtkGrid* _tmp29_;
	GtkBox* _tmp30_;
	GtkButton* _tmp31_;
	parent_class = G_OBJECT_CLASS (editing_tools_straighten_tool_straighten_tool_window_parent_class);
	obj = parent_class->constructor (type, n_construct_properties, construct_properties);
	self = G_TYPE_CHECK_INSTANCE_CAST (obj, EDITING_TOOLS_STRAIGHTEN_TOOL_TYPE_STRAIGHTEN_TOOL_WINDOW, EditingToolsStraightenToolStraightenToolWindow);
	_tmp0_ = self->angle_slider;
	gtk_widget_set_size_request ((GtkWidget*) _tmp0_, EDITING_TOOLS_STRAIGHTEN_TOOL_MIN_SLIDER_SIZE, -1);
	_tmp1_ = self->angle_slider;
	gtk_range_set_value ((GtkRange*) _tmp1_, 0.0);
	_tmp2_ = self->angle_slider;
	gtk_scale_set_draw_value (_tmp2_, FALSE);
	_tmp3_ = self->description_label;
	gtk_misc_set_padding ((GtkMisc*) _tmp3_, EDITING_TOOLS_STRAIGHTEN_TOOL_STRAIGHTEN_TOOL_WINDOW_CONTROL_SPACING, 0);
	_tmp4_ = self->angle_label;
	gtk_misc_set_padding ((GtkMisc*) _tmp4_, 0, 0);
	_tmp5_ = self->angle_label;
	gtk_widget_set_size_request ((GtkWidget*) _tmp5_, EDITING_TOOLS_STRAIGHTEN_TOOL_MIN_LABEL_SIZE, -1);
	_tmp6_ = (GtkBox*) gtk_box_new (GTK_ORIENTATION_HORIZONTAL, EDITING_TOOLS_STRAIGHTEN_TOOL_STRAIGHTEN_TOOL_WINDOW_CONTROL_SPACING);
	g_object_ref_sink (_tmp6_);
	slider_layout = _tmp6_;
	_tmp7_ = slider_layout;
	_tmp8_ = self->angle_slider;
	gtk_box_pack_start (_tmp7_, (GtkWidget*) _tmp8_, TRUE, TRUE, (guint) 0);
	_tmp9_ = (GtkBox*) gtk_box_new (GTK_ORIENTATION_HORIZONTAL, EDITING_TOOLS_STRAIGHTEN_TOOL_STRAIGHTEN_TOOL_WINDOW_CONTROL_SPACING);
	g_object_ref_sink (_tmp9_);
	button_layout = _tmp9_;
	_tmp10_ = self->cancel_button;
	gtk_widget_set_size_request ((GtkWidget*) _tmp10_, EDITING_TOOLS_STRAIGHTEN_TOOL_MIN_BUTTON_SIZE, -1);
	_tmp11_ = self->reset_button;
	gtk_widget_set_size_request ((GtkWidget*) _tmp11_, EDITING_TOOLS_STRAIGHTEN_TOOL_MIN_BUTTON_SIZE, -1);
	_tmp12_ = self->ok_button;
	gtk_widget_set_size_request ((GtkWidget*) _tmp12_, EDITING_TOOLS_STRAIGHTEN_TOOL_MIN_BUTTON_SIZE, -1);
	_tmp13_ = button_layout;
	_tmp14_ = self->cancel_button;
	gtk_box_pack_start (_tmp13_, (GtkWidget*) _tmp14_, TRUE, TRUE, (guint) 0);
	_tmp15_ = button_layout;
	_tmp16_ = self->reset_button;
	gtk_box_pack_start (_tmp15_, (GtkWidget*) _tmp16_, TRUE, TRUE, (guint) 0);
	_tmp17_ = button_layout;
	_tmp18_ = self->ok_button;
	gtk_box_pack_start (_tmp17_, (GtkWidget*) _tmp18_, TRUE, TRUE, (guint) 0);
	_tmp19_ = (GtkBox*) gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
	g_object_ref_sink (_tmp19_);
	main_layout = _tmp19_;
	_tmp20_ = main_layout;
	_tmp21_ = self->description_label;
	gtk_box_pack_start (_tmp20_, (GtkWidget*) _tmp21_, TRUE, TRUE, (guint) 0);
	_tmp22_ = main_layout;
	_tmp23_ = slider_layout;
	gtk_box_pack_start (_tmp22_, (GtkWidget*) _tmp23_, TRUE, TRUE, (guint) 0);
	_tmp24_ = main_layout;
	_tmp25_ = self->angle_label;
	gtk_box_pack_start (_tmp24_, (GtkWidget*) _tmp25_, TRUE, TRUE, (guint) 0);
	_tmp26_ = main_layout;
	_tmp27_ = button_layout;
	gtk_box_pack_start (_tmp26_, (GtkWidget*) _tmp27_, TRUE, TRUE, (guint) 0);
	_tmp28_ = editing_tools_editing_tool_window_get_content_area ((EditingToolsEditingToolWindow*) self);
	_tmp29_ = _tmp28_;
	_tmp30_ = main_layout;
	gtk_container_add ((GtkContainer*) _tmp29_, (GtkWidget*) _tmp30_);
	_tmp31_ = self->reset_button;
	g_signal_connect_object (_tmp31_, "clicked", (GCallback) _editing_tools_straighten_tool_straighten_tool_window_on_reset_clicked_gtk_button_clicked, self, 0);
	gtk_window_set_position ((GtkWindow*) self, GTK_WIN_POS_CENTER_ON_PARENT);
	_g_object_unref0 (main_layout);
	_g_object_unref0 (button_layout);
	_g_object_unref0 (slider_layout);
	return obj;
}

static void
editing_tools_straighten_tool_straighten_tool_window_class_init (EditingToolsStraightenToolStraightenToolWindowClass * klass,
                                                                 gpointer klass_data)
{
	editing_tools_straighten_tool_straighten_tool_window_parent_class = g_type_class_peek_parent (klass);
	G_OBJECT_CLASS (klass)->constructor = editing_tools_straighten_tool_straighten_tool_window_constructor;
	G_OBJECT_CLASS (klass)->finalize = editing_tools_straighten_tool_straighten_tool_window_finalize;
}

static void
editing_tools_straighten_tool_straighten_tool_window_instance_init (EditingToolsStraightenToolStraightenToolWindow * self,
                                                                    gpointer klass)
{
	GtkScale* _tmp0_;
	GtkLabel* _tmp1_;
	GtkLabel* _tmp2_;
	GtkButton* _tmp3_;
	GtkButton* _tmp4_;
	GtkButton* _tmp5_;
	_tmp0_ = (GtkScale*) gtk_scale_new_with_range (GTK_ORIENTATION_HORIZONTAL, EDITING_TOOLS_STRAIGHTEN_TOOL_MIN_ANGLE, EDITING_TOOLS_STRAIGHTEN_TOOL_MAX_ANGLE, EDITING_TOOLS_STRAIGHTEN_TOOL_INCREMENT);
	g_object_ref_sink (_tmp0_);
	self->angle_slider = _tmp0_;
	_tmp1_ = (GtkLabel*) gtk_label_new ("");
	g_object_ref_sink (_tmp1_);
	self->angle_label = _tmp1_;
	_tmp2_ = (GtkLabel*) gtk_label_new (_ ("Angle:"));
	g_object_ref_sink (_tmp2_);
	self->description_label = _tmp2_;
	_tmp3_ = (GtkButton*) gtk_button_new_with_mnemonic (_ ("_Straighten"));
	g_object_ref_sink (_tmp3_);
	self->ok_button = _tmp3_;
	_tmp4_ = (GtkButton*) gtk_button_new_with_mnemonic (_ ("_Cancel"));
	g_object_ref_sink (_tmp4_);
	self->cancel_button = _tmp4_;
	_tmp5_ = (GtkButton*) gtk_button_new_with_mnemonic (_ ("_Reset"));
	g_object_ref_sink (_tmp5_);
	self->reset_button = _tmp5_;
}

static void
editing_tools_straighten_tool_straighten_tool_window_finalize (GObject * obj)
{
	EditingToolsStraightenToolStraightenToolWindow * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (obj, EDITING_TOOLS_STRAIGHTEN_TOOL_TYPE_STRAIGHTEN_TOOL_WINDOW, EditingToolsStraightenToolStraightenToolWindow);
	_g_object_unref0 (self->angle_slider);
	_g_object_unref0 (self->angle_label);
	_g_object_unref0 (self->description_label);
	_g_object_unref0 (self->ok_button);
	_g_object_unref0 (self->cancel_button);
	_g_object_unref0 (self->reset_button);
	G_OBJECT_CLASS (editing_tools_straighten_tool_straighten_tool_window_parent_class)->finalize (obj);
}

static GType
editing_tools_straighten_tool_straighten_tool_window_get_type_once (void)
{
	static const GTypeInfo g_define_type_info = { sizeof (EditingToolsStraightenToolStraightenToolWindowClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) editing_tools_straighten_tool_straighten_tool_window_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (EditingToolsStraightenToolStraightenToolWindow), 0, (GInstanceInitFunc) editing_tools_straighten_tool_straighten_tool_window_instance_init, NULL };
	GType editing_tools_straighten_tool_straighten_tool_window_type_id;
	editing_tools_straighten_tool_straighten_tool_window_type_id = g_type_register_static (EDITING_TOOLS_TYPE_EDITING_TOOL_WINDOW, "EditingToolsStraightenToolStraightenToolWindow", &g_define_type_info, 0);
	return editing_tools_straighten_tool_straighten_tool_window_type_id;
}

static GType
editing_tools_straighten_tool_straighten_tool_window_get_type (void)
{
	static volatile gsize editing_tools_straighten_tool_straighten_tool_window_type_id__once = 0;
	if (g_once_init_enter (&editing_tools_straighten_tool_straighten_tool_window_type_id__once)) {
		GType editing_tools_straighten_tool_straighten_tool_window_type_id;
		editing_tools_straighten_tool_straighten_tool_window_type_id = editing_tools_straighten_tool_straighten_tool_window_get_type_once ();
		g_once_init_leave (&editing_tools_straighten_tool_straighten_tool_window_type_id__once, editing_tools_straighten_tool_straighten_tool_window_type_id);
	}
	return editing_tools_straighten_tool_straighten_tool_window_type_id__once;
}

static void
editing_tools_straighten_tool_class_init (EditingToolsStraightenToolClass * klass,
                                          gpointer klass_data)
{
	editing_tools_straighten_tool_parent_class = g_type_class_peek_parent (klass);
	g_type_class_adjust_private_offset (klass, &EditingToolsStraightenTool_private_offset);
	((EditingToolsEditingToolClass *) klass)->on_left_click = (void (*) (EditingToolsEditingTool*, gint, gint)) editing_tools_straighten_tool_real_on_left_click;
	((EditingToolsEditingToolClass *) klass)->on_left_released = (void (*) (EditingToolsEditingTool*, gint, gint)) editing_tools_straighten_tool_real_on_left_released;
	((EditingToolsEditingToolClass *) klass)->on_motion = (void (*) (EditingToolsEditingTool*, gint, gint, GdkModifierType)) editing_tools_straighten_tool_real_on_motion;
	((EditingToolsEditingToolClass *) klass)->on_keypress = (gboolean (*) (EditingToolsEditingTool*, GdkEventKey*)) editing_tools_straighten_tool_real_on_keypress;
	((EditingToolsEditingToolClass *) klass)->activate = (void (*) (EditingToolsEditingTool*, EditingToolsPhotoCanvas*)) editing_tools_straighten_tool_real_activate;
	((EditingToolsEditingToolClass *) klass)->deactivate = (void (*) (EditingToolsEditingTool*)) editing_tools_straighten_tool_real_deactivate;
	((EditingToolsEditingToolClass *) klass)->get_tool_window = (EditingToolsEditingToolWindow* (*) (EditingToolsEditingTool*)) editing_tools_straighten_tool_real_get_tool_window;
	((EditingToolsEditingToolClass *) klass)->paint = (void (*) (EditingToolsEditingTool*, cairo_t*)) editing_tools_straighten_tool_real_paint;
	G_OBJECT_CLASS (klass)->finalize = editing_tools_straighten_tool_finalize;
}

static void
editing_tools_straighten_tool_instance_init (EditingToolsStraightenTool * self,
                                             gpointer klass)
{
	EditingToolsStraightenToolStraightenGuide* _tmp0_;
	self->priv = editing_tools_straighten_tool_get_instance_private (self);
	self->priv->photo_angle = 0.0;
	self->priv->use_high_qual = TRUE;
	self->priv->slider_sched = NULL;
	_tmp0_ = editing_tools_straighten_tool_straighten_guide_new ();
	self->priv->guide = _tmp0_;
	self->priv->scale_factor = 1;
}

static void
editing_tools_straighten_tool_finalize (GObject * obj)
{
	EditingToolsStraightenTool * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (obj, EDITING_TOOLS_TYPE_STRAIGHTEN_TOOL, EditingToolsStraightenTool);
	_g_object_unref0 (self->priv->window);
	_cairo_surface_destroy0 (self->priv->photo_surf);
	_cairo_surface_destroy0 (self->priv->rotate_surf);
	_cairo_destroy0 (self->priv->rotate_ctx);
	_one_shot_scheduler_unref0 (self->priv->slider_sched);
	_editing_tools_straighten_tool_straighten_guide_unref0 (self->priv->guide);
	G_OBJECT_CLASS (editing_tools_straighten_tool_parent_class)->finalize (obj);
}

/**
 * An editing tool that allows one to introduce or remove a Dutch angle from
 * a photograph.
 */
static GType
editing_tools_straighten_tool_get_type_once (void)
{
	static const GTypeInfo g_define_type_info = { sizeof (EditingToolsStraightenToolClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) editing_tools_straighten_tool_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (EditingToolsStraightenTool), 0, (GInstanceInitFunc) editing_tools_straighten_tool_instance_init, NULL };
	GType editing_tools_straighten_tool_type_id;
	editing_tools_straighten_tool_type_id = g_type_register_static (EDITING_TOOLS_TYPE_EDITING_TOOL, "EditingToolsStraightenTool", &g_define_type_info, 0);
	EditingToolsStraightenTool_private_offset = g_type_add_instance_private (editing_tools_straighten_tool_type_id, sizeof (EditingToolsStraightenToolPrivate));
	return editing_tools_straighten_tool_type_id;
}

GType
editing_tools_straighten_tool_get_type (void)
{
	static volatile gsize editing_tools_straighten_tool_type_id__once = 0;
	if (g_once_init_enter (&editing_tools_straighten_tool_type_id__once)) {
		GType editing_tools_straighten_tool_type_id;
		editing_tools_straighten_tool_type_id = editing_tools_straighten_tool_get_type_once ();
		g_once_init_leave (&editing_tools_straighten_tool_type_id__once, editing_tools_straighten_tool_type_id);
	}
	return editing_tools_straighten_tool_type_id__once;
}

