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

/**/
/*  Copyright (C) 2011-2012 Robert Dyer, Rico Tzschichholz*/
/**/
/*  This file is part of Plank.*/
/**/
/*  Plank 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.*/
/**/
/*  Plank 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 "plank.h"
#include <stdlib.h>
#include <string.h>
#include <glib.h>
#include <float.h>
#include <math.h>
#include <gtk/gtk.h>
#include <glib-object.h>
#include <gdk/gdk.h>
#include <gio/gio.h>
#include <gdk-pixbuf/gdk-pixbuf.h>
#include <cairo-gobject.h>

#define PLANK_DRAWING_SERVICE_DEFAULT_ICON "application-default-icon"
#define PLANK_DRAWING_SERVICE_FILE_ATTRIBUTE_CUSTOM_ICON "metadata::custom-icon"
#define PLANK_DRAWING_SERVICE_FILE_ATTRIBUTE_CUSTOM_ICON_NAME "metadata::custom-icon-name"
#define PLANK_DRAWING_SERVICE_SATURATION_WEIGHT 1.5
#define PLANK_DRAWING_SERVICE_WEIGHT_THRESHOLD 1.0
#define PLANK_DRAWING_SERVICE_ALPHA_THRESHOLD ((guint8) 24)
#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

enum  {
	PLANK_DRAWING_SERVICE_0_PROPERTY,
	PLANK_DRAWING_SERVICE_NUM_PROPERTIES
};
static GParamSpec* plank_drawing_service_properties[PLANK_DRAWING_SERVICE_NUM_PROPERTIES];
#define _g_object_unref0(var) ((var == NULL) ? NULL : (var = (g_object_unref (var), NULL)))
#define _g_free0(var) (var = (g_free (var), NULL))
#define _g_regex_unref0(var) ((var == NULL) ? NULL : (var = (g_regex_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)))

static gpointer plank_drawing_service_parent_class = NULL;
static GMutex plank_drawing_service_icon_theme_mutex;
static GMutex plank_drawing_service_icon_theme_mutex = {0};
static GtkIconTheme* plank_drawing_service_icon_theme;
static GtkIconTheme* plank_drawing_service_icon_theme = NULL;

static PlankDrawingService* plank_drawing_service_new (void);
static PlankDrawingService* plank_drawing_service_construct (GType object_type);
static void _vala_array_add3 (gchar** * array,
                       gint* length,
                       gint* size,
                       gchar* value);
static GdkPixbuf* plank_drawing_service_load_pixbuf_from_file (GFile* file,
                                                        gint width,
                                                        gint height);
static GdkPixbuf* plank_drawing_service_load_pixbuf (const gchar* icon,
                                              gint size);
static GdkPixbuf* plank_drawing_service_load_pixbuf_from_resource (const gchar* resource,
                                                            gint width,
                                                            gint height);
static GdkPixbuf* plank_drawing_service_get_empty_pixbuf (gint width,
                                                   gint height);
static void _vala_array_add4 (gchar** * array,
                       gint* length,
                       gint* size,
                       gchar* value);
static cairo_surface_t* plank_drawing_service_load_surface (const gchar* icon,
                                                     gint size,
                                                     gint scale);
static cairo_surface_t* plank_drawing_service_load_surface_from_resource_at_scale (const gchar* resource,
                                                                            gint width,
                                                                            gint height,
                                                                            gint scale);
static void plank_drawing_service_finalize (GObject * obj);
static GType plank_drawing_service_get_type_once (void);
static void _vala_array_destroy (gpointer array,
                          gssize array_length,
                          GDestroyNotify destroy_func);
static void _vala_array_free (gpointer array,
                       gssize array_length,
                       GDestroyNotify destroy_func);
static gssize _vala_array_length (gpointer array);

static PlankDrawingService*
plank_drawing_service_construct (GType object_type)
{
	PlankDrawingService * self = NULL;
	self = (PlankDrawingService*) g_object_new (object_type, NULL);
	return self;
}

static PlankDrawingService*
plank_drawing_service_new (void)
{
	return plank_drawing_service_construct (PLANK_TYPE_DRAWING_SERVICE);
}

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

GtkIconTheme*
plank_drawing_service_get_icon_theme (void)
{
	GtkIconTheme* _tmp0_;
	GtkIconTheme* _tmp4_;
	GtkIconTheme* result;
	g_mutex_lock (&plank_drawing_service_icon_theme_mutex);
	_tmp0_ = plank_drawing_service_icon_theme;
	if (_tmp0_ == NULL) {
		GdkScreen* _tmp1_;
		GtkIconTheme* _tmp2_;
		GtkIconTheme* _tmp3_;
		_tmp1_ = gdk_screen_get_default ();
		_tmp2_ = gtk_icon_theme_get_for_screen (_tmp1_);
		_tmp3_ = _g_object_ref0 (_tmp2_);
		_g_object_unref0 (plank_drawing_service_icon_theme);
		plank_drawing_service_icon_theme = _tmp3_;
	}
	g_mutex_unlock (&plank_drawing_service_icon_theme_mutex);
	_tmp4_ = plank_drawing_service_icon_theme;
	result = _tmp4_;
	return result;
}

/**
 * Gets the icon name from a {@link GLib.File}.
 *
 * @param file the file to get the icon name for
 * @return the icon name for the file, or null if none exists
 */
gchar*
plank_drawing_service_get_icon_from_file (GFile* file)
{
	GError* _inner_error0_ = NULL;
	gchar* result;
	g_return_val_if_fail (file != NULL, NULL);
	{
		GFileInfo* info = NULL;
		GFileInfo* _tmp0_;
		const gchar* custom_icon_name = NULL;
		GFileInfo* _tmp1_;
		const gchar* _tmp2_;
		gboolean _tmp3_ = FALSE;
		const gchar* _tmp4_;
		const gchar* custom_icon = NULL;
		GFileInfo* _tmp8_;
		const gchar* _tmp9_;
		gboolean _tmp10_ = FALSE;
		const gchar* _tmp11_;
		const gchar* thumb_icon = NULL;
		GFileInfo* _tmp21_;
		const gchar* _tmp22_;
		gboolean _tmp23_ = FALSE;
		const gchar* _tmp24_;
		GFileInfo* _tmp28_;
		GIcon* _tmp29_;
		gchar* _tmp30_;
		_tmp0_ = g_file_query_info (file, G_FILE_ATTRIBUTE_STANDARD_ICON "," PLANK_DRAWING_SERVICE_FILE_ATTRIBUTE_CUSTOM_ICON_NAME "," PLANK_DRAWING_SERVICE_FILE_ATTRIBUTE_CUSTOM_ICON "," G_FILE_ATTRIBUTE_THUMBNAIL_PATH, 0, NULL, &_inner_error0_);
		info = _tmp0_;
		if (G_UNLIKELY (_inner_error0_ != NULL)) {
			goto __catch0_g_error;
		}
		_tmp1_ = info;
		_tmp2_ = g_file_info_get_attribute_string (_tmp1_, PLANK_DRAWING_SERVICE_FILE_ATTRIBUTE_CUSTOM_ICON_NAME);
		custom_icon_name = _tmp2_;
		_tmp4_ = custom_icon_name;
		if (_tmp4_ != NULL) {
			const gchar* _tmp5_;
			_tmp5_ = custom_icon_name;
			_tmp3_ = g_strcmp0 (_tmp5_, "") != 0;
		} else {
			_tmp3_ = FALSE;
		}
		if (_tmp3_) {
			const gchar* _tmp6_;
			gchar* _tmp7_;
			_tmp6_ = custom_icon_name;
			_tmp7_ = g_strdup (_tmp6_);
			result = _tmp7_;
			_g_object_unref0 (info);
			return result;
		}
		_tmp8_ = info;
		_tmp9_ = g_file_info_get_attribute_string (_tmp8_, PLANK_DRAWING_SERVICE_FILE_ATTRIBUTE_CUSTOM_ICON);
		custom_icon = _tmp9_;
		_tmp11_ = custom_icon;
		if (_tmp11_ != NULL) {
			const gchar* _tmp12_;
			_tmp12_ = custom_icon;
			_tmp10_ = g_strcmp0 (_tmp12_, "") != 0;
		} else {
			_tmp10_ = FALSE;
		}
		if (_tmp10_) {
			const gchar* _tmp13_;
			const gchar* _tmp16_;
			GFile* _tmp17_;
			GFile* _tmp18_;
			gchar* _tmp19_;
			gchar* _tmp20_;
			_tmp13_ = custom_icon;
			if (g_str_has_prefix (_tmp13_, "file://")) {
				const gchar* _tmp14_;
				gchar* _tmp15_;
				_tmp14_ = custom_icon;
				_tmp15_ = g_strdup (_tmp14_);
				result = _tmp15_;
				_g_object_unref0 (info);
				return result;
			}
			_tmp16_ = custom_icon;
			_tmp17_ = g_file_get_child (file, _tmp16_);
			_tmp18_ = _tmp17_;
			_tmp19_ = g_file_get_path (_tmp18_);
			_tmp20_ = _tmp19_;
			_g_object_unref0 (_tmp18_);
			result = _tmp20_;
			_g_object_unref0 (info);
			return result;
		}
		_tmp21_ = info;
		_tmp22_ = g_file_info_get_attribute_byte_string (_tmp21_, G_FILE_ATTRIBUTE_THUMBNAIL_PATH);
		thumb_icon = _tmp22_;
		_tmp24_ = thumb_icon;
		if (_tmp24_ != NULL) {
			const gchar* _tmp25_;
			_tmp25_ = thumb_icon;
			_tmp23_ = g_strcmp0 (_tmp25_, "") != 0;
		} else {
			_tmp23_ = FALSE;
		}
		if (_tmp23_) {
			const gchar* _tmp26_;
			gchar* _tmp27_;
			_tmp26_ = thumb_icon;
			_tmp27_ = g_strdup (_tmp26_);
			result = _tmp27_;
			_g_object_unref0 (info);
			return result;
		}
		_tmp28_ = info;
		_tmp29_ = g_file_info_get_icon (_tmp28_);
		_tmp30_ = plank_drawing_service_get_icon_from_gicon (_tmp29_);
		result = _tmp30_;
		_g_object_unref0 (info);
		return result;
	}
	goto __finally0;
	__catch0_g_error:
	{
		gchar* _tmp31_ = NULL;
		gchar* _tmp32_;
		g_clear_error (&_inner_error0_);
		_tmp32_ = g_file_get_path (file);
		_tmp31_ = _tmp32_;
		if (_tmp31_ == NULL) {
			gchar* _tmp33_;
			_tmp33_ = g_strdup ("");
			_g_free0 (_tmp31_);
			_tmp31_ = _tmp33_;
		}
		g_debug ("DrawingService.vala:90: Could not get file info for '%s'", _tmp31_);
		_g_free0 (_tmp31_);
	}
	__finally0:
	if (G_UNLIKELY (_inner_error0_ != NULL)) {
		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 NULL;
	}
	result = NULL;
	return result;
}

/**
 * Gets an icon from a {@link GLib.Icon}.
 *
 * @param icon the icon to get the name for
 * @return the icon name, or null if none exists
 */
static gchar*
_vala_g_strjoinv (const gchar* separator,
                  gchar** str_array,
                  gint str_array_length1)
{
	gboolean _tmp0_ = FALSE;
	gchar* result;
	if (separator == NULL) {
		separator = "";
	}
	if (str_array != NULL) {
		gboolean _tmp1_ = FALSE;
		if (str_array_length1 > 0) {
			_tmp1_ = TRUE;
		} else {
			gboolean _tmp2_ = FALSE;
			if (str_array_length1 == -1) {
				const gchar* _tmp3_;
				_tmp3_ = str_array[0];
				_tmp2_ = _tmp3_ != NULL;
			} else {
				_tmp2_ = FALSE;
			}
			_tmp1_ = _tmp2_;
		}
		_tmp0_ = _tmp1_;
	} else {
		_tmp0_ = FALSE;
	}
	if (_tmp0_) {
		gint i = 0;
		gsize len = 0UL;
		gint _tmp16_;
		gint _tmp17_;
		const gchar* res = NULL;
		void* _tmp18_;
		const gchar* _tmp19_ = NULL;
		const gchar* _tmp20_;
		void* ptr = NULL;
		const gchar* _tmp22_;
		void* _tmp23_;
		const gchar* _tmp33_;
		len = (gsize) 1;
		{
			gboolean _tmp4_ = FALSE;
			i = 0;
			_tmp4_ = TRUE;
			while (TRUE) {
				gboolean _tmp6_ = FALSE;
				gboolean _tmp7_ = FALSE;
				gint _tmp10_ = 0;
				const gchar* _tmp11_;
				if (!_tmp4_) {
					gint _tmp5_;
					_tmp5_ = i;
					i = _tmp5_ + 1;
				}
				_tmp4_ = FALSE;
				if (str_array_length1 != -1) {
					_tmp7_ = i < str_array_length1;
				} else {
					_tmp7_ = FALSE;
				}
				if (_tmp7_) {
					_tmp6_ = TRUE;
				} else {
					gboolean _tmp8_ = FALSE;
					if (str_array_length1 == -1) {
						const gchar* _tmp9_;
						_tmp9_ = str_array[i];
						_tmp8_ = _tmp9_ != NULL;
					} else {
						_tmp8_ = FALSE;
					}
					_tmp6_ = _tmp8_;
				}
				if (!_tmp6_) {
					break;
				}
				_tmp11_ = str_array[i];
				if (_tmp11_ != NULL) {
					const gchar* _tmp12_;
					gint _tmp13_;
					gint _tmp14_;
					_tmp12_ = str_array[i];
					_tmp13_ = strlen ((const gchar*) _tmp12_);
					_tmp14_ = _tmp13_;
					_tmp10_ = _tmp14_;
				} else {
					_tmp10_ = 0;
				}
				len += (gsize) _tmp10_;
			}
		}
		if (i == 0) {
			gchar* _tmp15_;
			_tmp15_ = g_strdup ("");
			result = _tmp15_;
			return result;
		}
		str_array_length1 = i;
		_tmp16_ = strlen ((const gchar*) separator);
		_tmp17_ = _tmp16_;
		len += (gsize) (_tmp17_ * (i - 1));
		_tmp18_ = g_malloc (len);
		res = _tmp18_;
		_tmp20_ = str_array[0];
		if (_tmp20_ != NULL) {
			const gchar* _tmp21_;
			_tmp21_ = str_array[0];
			_tmp19_ = (const gchar*) _tmp21_;
		} else {
			_tmp19_ = "";
		}
		_tmp22_ = res;
		_tmp23_ = g_stpcpy ((void*) _tmp22_, _tmp19_);
		ptr = _tmp23_;
		{
			gboolean _tmp24_ = FALSE;
			i = 1;
			_tmp24_ = TRUE;
			while (TRUE) {
				void* _tmp26_;
				void* _tmp27_;
				const gchar* _tmp28_ = NULL;
				const gchar* _tmp29_;
				void* _tmp31_;
				void* _tmp32_;
				if (!_tmp24_) {
					gint _tmp25_;
					_tmp25_ = i;
					i = _tmp25_ + 1;
				}
				_tmp24_ = FALSE;
				if (!(i < str_array_length1)) {
					break;
				}
				_tmp26_ = ptr;
				_tmp27_ = g_stpcpy (_tmp26_, (const gchar*) separator);
				ptr = _tmp27_;
				_tmp29_ = str_array[i];
				if (_tmp29_ != NULL) {
					const gchar* _tmp30_;
					_tmp30_ = str_array[i];
					_tmp28_ = (const gchar*) _tmp30_;
				} else {
					_tmp28_ = "";
				}
				_tmp31_ = ptr;
				_tmp32_ = g_stpcpy (_tmp31_, _tmp28_);
				ptr = _tmp32_;
			}
		}
		_tmp33_ = res;
		res = NULL;
		result = (gchar*) _tmp33_;
		return result;
	} else {
		gchar* _tmp34_;
		_tmp34_ = g_strdup ("");
		result = _tmp34_;
		return result;
	}
}

static gchar*
string_replace (const gchar* self,
                const gchar* old,
                const gchar* replacement)
{
	gboolean _tmp0_ = FALSE;
	gboolean _tmp1_ = FALSE;
	GError* _inner_error0_ = NULL;
	gchar* result;
	g_return_val_if_fail (self != NULL, NULL);
	g_return_val_if_fail (old != NULL, NULL);
	g_return_val_if_fail (replacement != NULL, NULL);
	if ((*((gchar*) self)) == '\0') {
		_tmp1_ = TRUE;
	} else {
		_tmp1_ = (*((gchar*) old)) == '\0';
	}
	if (_tmp1_) {
		_tmp0_ = TRUE;
	} else {
		_tmp0_ = g_strcmp0 (old, replacement) == 0;
	}
	if (_tmp0_) {
		gchar* _tmp2_;
		_tmp2_ = g_strdup (self);
		result = _tmp2_;
		return result;
	}
	{
		GRegex* regex = NULL;
		gchar* _tmp3_;
		gchar* _tmp4_;
		GRegex* _tmp5_;
		GRegex* _tmp6_;
		gchar* _tmp7_ = NULL;
		GRegex* _tmp8_;
		gchar* _tmp9_;
		gchar* _tmp10_;
		_tmp3_ = g_regex_escape_string (old, -1);
		_tmp4_ = _tmp3_;
		_tmp5_ = g_regex_new (_tmp4_, 0, 0, &_inner_error0_);
		_tmp6_ = _tmp5_;
		_g_free0 (_tmp4_);
		regex = _tmp6_;
		if (G_UNLIKELY (_inner_error0_ != NULL)) {
			if (_inner_error0_->domain == G_REGEX_ERROR) {
				goto __catch0_g_regex_error;
			}
			g_critical ("file %s: line %d: unexpected 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 NULL;
		}
		_tmp8_ = regex;
		_tmp9_ = g_regex_replace_literal (_tmp8_, self, (gssize) -1, 0, replacement, 0, &_inner_error0_);
		_tmp7_ = _tmp9_;
		if (G_UNLIKELY (_inner_error0_ != NULL)) {
			_g_regex_unref0 (regex);
			if (_inner_error0_->domain == G_REGEX_ERROR) {
				goto __catch0_g_regex_error;
			}
			g_critical ("file %s: line %d: unexpected 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 NULL;
		}
		_tmp10_ = _tmp7_;
		_tmp7_ = NULL;
		result = _tmp10_;
		_g_free0 (_tmp7_);
		_g_regex_unref0 (regex);
		return result;
	}
	goto __finally0;
	__catch0_g_regex_error:
	{
		g_clear_error (&_inner_error0_);
		g_assert_not_reached ();
	}
	__finally0:
	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 NULL;
}

gchar*
plank_drawing_service_get_icon_from_gicon (GIcon* icon)
{
	gchar* result;
	if (G_TYPE_CHECK_INSTANCE_TYPE (icon, g_themed_icon_get_type ())) {
		gchar* icons = NULL;
		gchar** _tmp0_;
		gchar** _tmp1_;
		gchar* _tmp2_;
		const gchar* _tmp3_;
		gchar* _tmp4_;
		_tmp1_ = _tmp0_ = g_themed_icon_get_names (G_TYPE_CHECK_INSTANCE_CAST (icon, g_themed_icon_get_type (), GThemedIcon));
		_tmp2_ = _vala_g_strjoinv (";;", _tmp1_, (gint) _vala_array_length (_tmp0_));
		icons = _tmp2_;
		_tmp3_ = icons;
		_tmp4_ = string_replace (_tmp3_, "(null);;", "");
		result = _tmp4_;
		_g_free0 (icons);
		return result;
	}
	if (G_TYPE_CHECK_INSTANCE_TYPE (icon, g_file_icon_get_type ())) {
		GFile* _tmp5_;
		gchar* _tmp6_;
		_tmp5_ = g_file_icon_get_file (G_TYPE_CHECK_INSTANCE_CAST (icon, g_file_icon_get_type (), GFileIcon));
		_tmp6_ = g_file_get_path (_tmp5_);
		result = _tmp6_;
		return result;
	}
	result = NULL;
	return result;
}

/**
 * Loads an icon based on names and the given width/height
 *
 * @param names a delimited (with ";;") list of icon names, first one found is used
 * @param width the requested width of the icon
 * @param height the requested height of the icon
 * @return the pixbuf representing the requested icon
 */
static void
_vala_array_add3 (gchar** * array,
                  gint* length,
                  gint* size,
                  gchar* value)
{
	if ((*length) == (*size)) {
		*size = (*size) ? (2 * (*size)) : 4;
		*array = g_renew (gchar*, *array, (*size) + 1);
	}
	(*array)[(*length)++] = value;
	(*array)[*length] = NULL;
}

GdkPixbuf*
plank_drawing_service_load_icon (const gchar* names,
                                 gint width,
                                 gint height)
{
	GdkPixbuf* pbuf = NULL;
	gchar** all_names = NULL;
	gchar** _tmp0_;
	gchar** _tmp1_;
	gint all_names_length1;
	gint _all_names_size_;
	gchar* _tmp2_;
	gchar** _tmp3_;
	gint _tmp3__length1;
	GdkPixbuf* _tmp15_;
	GdkPixbuf* _tmp17_;
	GdkPixbuf* _tmp29_;
	GdkPixbuf* result;
	g_return_val_if_fail (names != NULL, NULL);
	pbuf = NULL;
	_tmp1_ = _tmp0_ = g_strsplit (names, ";;", 0);
	all_names = _tmp1_;
	all_names_length1 = _vala_array_length (_tmp0_);
	_all_names_size_ = all_names_length1;
	_tmp2_ = g_strdup (PLANK_DRAWING_SERVICE_DEFAULT_ICON);
	_vala_array_add3 (&all_names, &all_names_length1, &_all_names_size_, _tmp2_);
	_tmp3_ = all_names;
	_tmp3__length1 = all_names_length1;
	{
		gchar** name_collection = NULL;
		gint name_collection_length1 = 0;
		gint _name_collection_size_ = 0;
		gint name_it = 0;
		name_collection = _tmp3_;
		name_collection_length1 = _tmp3__length1;
		for (name_it = 0; name_it < name_collection_length1; name_it = name_it + 1) {
			const gchar* name = NULL;
			name = name_collection[name_it];
			{
				GFile* file = NULL;
				const gchar* _tmp4_;
				GFile* _tmp5_;
				GFile* _tmp6_;
				const gchar* _tmp10_;
				GdkPixbuf* _tmp11_;
				GdkPixbuf* _tmp12_;
				const gchar* _tmp13_;
				_tmp4_ = name;
				_tmp5_ = plank_drawing_service_try_get_icon_file (_tmp4_);
				file = _tmp5_;
				_tmp6_ = file;
				if (_tmp6_ != NULL) {
					GFile* _tmp7_;
					GdkPixbuf* _tmp8_;
					GdkPixbuf* _tmp9_;
					_tmp7_ = file;
					_tmp8_ = plank_drawing_service_load_pixbuf_from_file (_tmp7_, width, height);
					_g_object_unref0 (pbuf);
					pbuf = _tmp8_;
					_tmp9_ = pbuf;
					if (_tmp9_ != NULL) {
						_g_object_unref0 (file);
						break;
					}
				}
				_tmp10_ = name;
				_tmp11_ = plank_drawing_service_load_pixbuf (_tmp10_, MAX (width, height));
				_g_object_unref0 (pbuf);
				pbuf = _tmp11_;
				_tmp12_ = pbuf;
				if (_tmp12_ != NULL) {
					_g_object_unref0 (file);
					break;
				}
				_tmp13_ = name;
				if (g_strcmp0 (_tmp13_, PLANK_DRAWING_SERVICE_DEFAULT_ICON) != 0) {
					const gchar* _tmp14_;
					_tmp14_ = name;
					g_message ("DrawingService.vala:144: Could not find icon '%s'", _tmp14_);
				}
				_g_object_unref0 (file);
			}
		}
	}
	_tmp15_ = pbuf;
	if (_tmp15_ == NULL) {
		GdkPixbuf* _tmp16_;
		_tmp16_ = plank_drawing_service_load_pixbuf_from_resource (PLANK_G_RESOURCE_PATH "/img/application-default-icon.svg", width, height);
		_g_object_unref0 (pbuf);
		pbuf = _tmp16_;
	}
	_tmp17_ = pbuf;
	if (_tmp17_ != NULL) {
		gboolean _tmp18_ = FALSE;
		gboolean _tmp19_ = FALSE;
		if (width != -1) {
			_tmp19_ = height != -1;
		} else {
			_tmp19_ = FALSE;
		}
		if (_tmp19_) {
			gboolean _tmp20_ = FALSE;
			GdkPixbuf* _tmp21_;
			gint _tmp22_;
			gint _tmp23_;
			_tmp21_ = pbuf;
			_tmp22_ = gdk_pixbuf_get_width (_tmp21_);
			_tmp23_ = _tmp22_;
			if (width != _tmp23_) {
				_tmp20_ = TRUE;
			} else {
				GdkPixbuf* _tmp24_;
				gint _tmp25_;
				gint _tmp26_;
				_tmp24_ = pbuf;
				_tmp25_ = gdk_pixbuf_get_height (_tmp24_);
				_tmp26_ = _tmp25_;
				_tmp20_ = height != _tmp26_;
			}
			_tmp18_ = _tmp20_;
		} else {
			_tmp18_ = FALSE;
		}
		if (_tmp18_) {
			GdkPixbuf* _tmp27_;
			GdkPixbuf* _tmp28_;
			_tmp27_ = pbuf;
			_tmp28_ = plank_drawing_service_ar_scale (_tmp27_, width, height);
			result = _tmp28_;
			all_names = (_vala_array_free (all_names, all_names_length1, (GDestroyNotify) g_free), NULL);
			_g_object_unref0 (pbuf);
			return result;
		}
		result = pbuf;
		all_names = (_vala_array_free (all_names, all_names_length1, (GDestroyNotify) g_free), NULL);
		return result;
	}
	g_warning ("DrawingService.vala:157: No icon found, return empty pixbuf");
	_tmp29_ = plank_drawing_service_get_empty_pixbuf (MAX (1, width), MAX (1, height));
	result = _tmp29_;
	all_names = (_vala_array_free (all_names, all_names_length1, (GDestroyNotify) g_free), NULL);
	_g_object_unref0 (pbuf);
	return result;
}

static GdkPixbuf*
plank_drawing_service_get_empty_pixbuf (gint width,
                                        gint height)
{
	GdkPixbuf* pbuf = NULL;
	GdkPixbuf* _tmp0_;
	GdkPixbuf* result;
	_tmp0_ = gdk_pixbuf_new (GDK_COLORSPACE_RGB, TRUE, 8, width, height);
	pbuf = _tmp0_;
	gdk_pixbuf_fill (pbuf, (guint32) 0x00000000);
	result = pbuf;
	return result;
}

/**
 * Try to get a {@link GLib.File} for the given icon name
 *
 * @param name a string which might represent an existing file
 * @return a {@link GLib.File}, or null if it failed
 */
GFile*
plank_drawing_service_try_get_icon_file (const gchar* name)
{
	GFile* file = NULL;
	gchar* name_down = NULL;
	gchar* _tmp0_;
	const gchar* _tmp1_;
	gboolean _tmp10_ = FALSE;
	GFile* _tmp11_;
	GFile* result;
	g_return_val_if_fail (name != NULL, NULL);
	file = NULL;
	_tmp0_ = g_utf8_strdown (name, (gssize) -1);
	name_down = _tmp0_;
	_tmp1_ = name_down;
	if (g_str_has_prefix (_tmp1_, "resource://")) {
		GFile* _tmp2_;
		_tmp2_ = g_file_new_for_uri (name);
		_g_object_unref0 (file);
		file = _tmp2_;
	} else {
		const gchar* _tmp3_;
		_tmp3_ = name_down;
		if (g_str_has_prefix (_tmp3_, "file://")) {
			GFile* _tmp4_;
			_tmp4_ = g_file_new_for_uri (name);
			_g_object_unref0 (file);
			file = _tmp4_;
		} else {
			if (g_str_has_prefix (name, "~/")) {
				const gchar* _tmp5_;
				gchar* _tmp6_;
				gchar* _tmp7_;
				GFile* _tmp8_;
				_tmp5_ = g_get_home_dir ();
				_tmp6_ = string_replace (name, "~", _tmp5_);
				_tmp7_ = _tmp6_;
				_tmp8_ = g_file_new_for_path (_tmp7_);
				_g_object_unref0 (file);
				file = _tmp8_;
				_g_free0 (_tmp7_);
			} else {
				if (g_str_has_prefix (name, "/")) {
					GFile* _tmp9_;
					_tmp9_ = g_file_new_for_path (name);
					_g_object_unref0 (file);
					file = _tmp9_;
				}
			}
		}
	}
	_tmp11_ = file;
	if (_tmp11_ != NULL) {
		GFile* _tmp12_;
		_tmp12_ = file;
		_tmp10_ = g_file_query_exists (_tmp12_, NULL);
	} else {
		_tmp10_ = FALSE;
	}
	if (_tmp10_) {
		result = file;
		_g_free0 (name_down);
		return result;
	}
	result = NULL;
	_g_free0 (name_down);
	_g_object_unref0 (file);
	return result;
}

static GdkPixbuf*
plank_drawing_service_load_pixbuf_from_file (GFile* file,
                                             gint width,
                                             gint height)
{
	GdkPixbuf* pbuf = NULL;
	GError* _inner_error0_ = NULL;
	GdkPixbuf* result;
	g_return_val_if_fail (file != NULL, NULL);
	pbuf = NULL;
	{
		GFileInputStream* fis = NULL;
		GFileInputStream* _tmp0_;
		GdkPixbuf* _tmp1_ = NULL;
		GFileInputStream* _tmp2_;
		GdkPixbuf* _tmp3_;
		GdkPixbuf* _tmp4_;
		_tmp0_ = g_file_read (file, NULL, &_inner_error0_);
		fis = _tmp0_;
		if (G_UNLIKELY (_inner_error0_ != NULL)) {
			goto __catch0_g_error;
		}
		_tmp2_ = fis;
		_tmp3_ = gdk_pixbuf_new_from_stream_at_scale ((GInputStream*) _tmp2_, width, height, TRUE, NULL, &_inner_error0_);
		_tmp1_ = _tmp3_;
		if (G_UNLIKELY (_inner_error0_ != NULL)) {
			_g_object_unref0 (fis);
			goto __catch0_g_error;
		}
		_tmp4_ = _tmp1_;
		_tmp1_ = NULL;
		_g_object_unref0 (pbuf);
		pbuf = _tmp4_;
		_g_object_unref0 (_tmp1_);
		_g_object_unref0 (fis);
	}
	goto __finally0;
	__catch0_g_error:
	{
		g_clear_error (&_inner_error0_);
	}
	__finally0:
	if (G_UNLIKELY (_inner_error0_ != NULL)) {
		_g_object_unref0 (pbuf);
		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 NULL;
	}
	result = pbuf;
	return result;
}

static GdkPixbuf*
plank_drawing_service_load_pixbuf_from_resource (const gchar* resource,
                                                 gint width,
                                                 gint height)
{
	GdkPixbuf* pbuf = NULL;
	GError* _inner_error0_ = NULL;
	GdkPixbuf* result;
	g_return_val_if_fail (resource != NULL, NULL);
	pbuf = NULL;
	{
		GdkPixbuf* _tmp0_ = NULL;
		GdkPixbuf* _tmp1_;
		GdkPixbuf* _tmp2_;
		_tmp1_ = gdk_pixbuf_new_from_resource_at_scale (resource, width, height, TRUE, &_inner_error0_);
		_tmp0_ = _tmp1_;
		if (G_UNLIKELY (_inner_error0_ != NULL)) {
			goto __catch0_g_error;
		}
		_tmp2_ = _tmp0_;
		_tmp0_ = NULL;
		_g_object_unref0 (pbuf);
		pbuf = _tmp2_;
		_g_object_unref0 (_tmp0_);
	}
	goto __finally0;
	__catch0_g_error:
	{
		g_clear_error (&_inner_error0_);
	}
	__finally0:
	if (G_UNLIKELY (_inner_error0_ != NULL)) {
		_g_object_unref0 (pbuf);
		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 NULL;
	}
	result = pbuf;
	return result;
}

static gboolean
string_contains (const gchar* self,
                 const gchar* needle)
{
	gchar* _tmp0_;
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	g_return_val_if_fail (needle != NULL, FALSE);
	_tmp0_ = strstr ((gchar*) self, (gchar*) needle);
	result = _tmp0_ != NULL;
	return result;
}

static GdkPixbuf*
plank_drawing_service_load_pixbuf (const gchar* icon,
                                   gint size)
{
	GdkPixbuf* pbuf = NULL;
	GtkIconTheme* icon_theme = NULL;
	GtkIconTheme* _tmp0_;
	GError* _inner_error0_ = NULL;
	GdkPixbuf* result;
	g_return_val_if_fail (icon != NULL, NULL);
	pbuf = NULL;
	_tmp0_ = plank_drawing_service_get_icon_theme ();
	icon_theme = _tmp0_;
	g_mutex_lock (&plank_drawing_service_icon_theme_mutex);
	{
		GdkPixbuf* _tmp1_ = NULL;
		GdkPixbuf* _tmp2_;
		GdkPixbuf* _tmp3_;
		_tmp2_ = gtk_icon_theme_load_icon (icon_theme, icon, size, 0, &_inner_error0_);
		_tmp1_ = _tmp2_;
		if (G_UNLIKELY (_inner_error0_ != NULL)) {
			goto __catch0_g_error;
		}
		_tmp3_ = _tmp1_;
		_tmp1_ = NULL;
		_g_object_unref0 (pbuf);
		pbuf = _tmp3_;
		_g_object_unref0 (_tmp1_);
	}
	goto __finally0;
	__catch0_g_error:
	{
		g_clear_error (&_inner_error0_);
	}
	__finally0:
	if (G_UNLIKELY (_inner_error0_ != NULL)) {
		_g_object_unref0 (pbuf);
		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 NULL;
	}
	{
		gboolean _tmp4_ = FALSE;
		GdkPixbuf* _tmp5_;
		_tmp5_ = pbuf;
		if (_tmp5_ == NULL) {
			_tmp4_ = string_contains (icon, ".");
		} else {
			_tmp4_ = FALSE;
		}
		if (_tmp4_) {
			gchar** parts = NULL;
			gchar** _tmp6_;
			gchar** _tmp7_;
			gint parts_length1;
			gint _parts_size_;
			GdkPixbuf* _tmp8_ = NULL;
			gchar** _tmp9_;
			gint _tmp9__length1;
			const gchar* _tmp10_;
			GdkPixbuf* _tmp11_;
			GdkPixbuf* _tmp12_;
			_tmp7_ = _tmp6_ = g_strsplit (icon, ".", 0);
			parts = _tmp7_;
			parts_length1 = _vala_array_length (_tmp6_);
			_parts_size_ = parts_length1;
			_tmp9_ = parts;
			_tmp9__length1 = parts_length1;
			_tmp10_ = _tmp9_[0];
			_tmp11_ = gtk_icon_theme_load_icon (icon_theme, _tmp10_, size, 0, &_inner_error0_);
			_tmp8_ = _tmp11_;
			if (G_UNLIKELY (_inner_error0_ != NULL)) {
				parts = (_vala_array_free (parts, parts_length1, (GDestroyNotify) g_free), NULL);
				goto __catch1_g_error;
			}
			_tmp12_ = _tmp8_;
			_tmp8_ = NULL;
			_g_object_unref0 (pbuf);
			pbuf = _tmp12_;
			_g_object_unref0 (_tmp8_);
			parts = (_vala_array_free (parts, parts_length1, (GDestroyNotify) g_free), NULL);
		}
	}
	goto __finally1;
	__catch1_g_error:
	{
		g_clear_error (&_inner_error0_);
	}
	__finally1:
	if (G_UNLIKELY (_inner_error0_ != NULL)) {
		_g_object_unref0 (pbuf);
		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 NULL;
	}
	g_mutex_unlock (&plank_drawing_service_icon_theme_mutex);
	result = pbuf;
	return result;
}

/**
 * Loads an icon based on names and the given width/height
 *
 * @param names a delimited (with ";;") list of icon names, first one found is used
 * @param width the requested width of the icon
 * @param height the requested height of the icon
 * @param scale the implicit requested scale of the icon
 * @return the {link Cairo.Surface} containing the requested icon, do not alter this surface
 */
static void
_vala_array_add4 (gchar** * array,
                  gint* length,
                  gint* size,
                  gchar* value)
{
	if ((*length) == (*size)) {
		*size = (*size) ? (2 * (*size)) : 4;
		*array = g_renew (gchar*, *array, (*size) + 1);
	}
	(*array)[(*length)++] = value;
	(*array)[*length] = NULL;
}

cairo_surface_t*
plank_drawing_service_load_icon_for_scale (const gchar* names,
                                           gint width,
                                           gint height,
                                           gint scale)
{
	cairo_surface_t* surface = NULL;
	gchar** all_names = NULL;
	gchar** _tmp0_;
	gchar** _tmp1_;
	gint all_names_length1;
	gint _all_names_size_;
	gchar* _tmp2_;
	gchar** _tmp3_;
	gint _tmp3__length1;
	cairo_surface_t* _tmp28_;
	cairo_surface_t* result;
	g_return_val_if_fail (names != NULL, NULL);
	surface = NULL;
	_tmp1_ = _tmp0_ = g_strsplit (names, ";;", 0);
	all_names = _tmp1_;
	all_names_length1 = _vala_array_length (_tmp0_);
	_all_names_size_ = all_names_length1;
	_tmp2_ = g_strdup (PLANK_DRAWING_SERVICE_DEFAULT_ICON);
	_vala_array_add4 (&all_names, &all_names_length1, &_all_names_size_, _tmp2_);
	_tmp3_ = all_names;
	_tmp3__length1 = all_names_length1;
	{
		gchar** name_collection = NULL;
		gint name_collection_length1 = 0;
		gint _name_collection_size_ = 0;
		gint name_it = 0;
		name_collection = _tmp3_;
		name_collection_length1 = _tmp3__length1;
		for (name_it = 0; name_it < name_collection_length1; name_it = name_it + 1) {
			const gchar* name = NULL;
			name = name_collection[name_it];
			{
				GFile* file = NULL;
				const gchar* _tmp4_;
				GFile* _tmp5_;
				GFile* _tmp6_;
				const gchar* _tmp23_;
				cairo_surface_t* _tmp24_;
				cairo_surface_t* _tmp25_;
				const gchar* _tmp26_;
				_tmp4_ = name;
				_tmp5_ = plank_drawing_service_try_get_icon_file (_tmp4_);
				file = _tmp5_;
				_tmp6_ = file;
				if (_tmp6_ != NULL) {
					GdkPixbuf* pbuf = NULL;
					GFile* _tmp7_;
					GdkPixbuf* _tmp8_;
					GdkPixbuf* _tmp9_;
					_tmp7_ = file;
					_tmp8_ = plank_drawing_service_load_pixbuf_from_file (_tmp7_, width, height);
					pbuf = _tmp8_;
					_tmp9_ = pbuf;
					if (_tmp9_ != NULL) {
						cairo_surface_t* _tmp10_;
						cairo_t* cr = NULL;
						cairo_surface_t* _tmp11_;
						cairo_t* _tmp12_;
						cairo_t* _tmp13_;
						GdkPixbuf* _tmp14_;
						GdkPixbuf* _tmp15_;
						gint _tmp16_;
						gint _tmp17_;
						GdkPixbuf* _tmp18_;
						gint _tmp19_;
						gint _tmp20_;
						cairo_t* _tmp21_;
						cairo_surface_t* _tmp22_;
						_tmp10_ = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width, height);
						_cairo_surface_destroy0 (surface);
						surface = _tmp10_;
						_tmp11_ = surface;
						_tmp12_ = cairo_create (_tmp11_);
						cr = _tmp12_;
						_tmp13_ = cr;
						_tmp14_ = pbuf;
						_tmp15_ = pbuf;
						_tmp16_ = gdk_pixbuf_get_width (_tmp15_);
						_tmp17_ = _tmp16_;
						_tmp18_ = pbuf;
						_tmp19_ = gdk_pixbuf_get_height (_tmp18_);
						_tmp20_ = _tmp19_;
						gdk_cairo_set_source_pixbuf (_tmp13_, _tmp14_, (gdouble) ((width - _tmp17_) / 2), (gdouble) ((height - _tmp20_) / 2));
						_tmp21_ = cr;
						cairo_paint (_tmp21_);
						_tmp22_ = surface;
						cairo_surface_set_device_scale (_tmp22_, (gdouble) scale, (gdouble) scale);
						_cairo_destroy0 (cr);
						_g_object_unref0 (pbuf);
						_g_object_unref0 (file);
						break;
					}
					_g_object_unref0 (pbuf);
				}
				_tmp23_ = name;
				_tmp24_ = plank_drawing_service_load_surface (_tmp23_, MAX (width, height) / scale, scale);
				_cairo_surface_destroy0 (surface);
				surface = _tmp24_;
				_tmp25_ = surface;
				if (_tmp25_ != NULL) {
					_g_object_unref0 (file);
					break;
				}
				_tmp26_ = name;
				if (g_strcmp0 (_tmp26_, PLANK_DRAWING_SERVICE_DEFAULT_ICON) != 0) {
					const gchar* _tmp27_;
					_tmp27_ = name;
					g_message ("DrawingService.vala:276: Could not find icon '%s'", _tmp27_);
				}
				_g_object_unref0 (file);
			}
		}
	}
	_tmp28_ = surface;
	if (_tmp28_ == NULL) {
		cairo_surface_t* _tmp29_;
		_tmp29_ = plank_drawing_service_load_surface_from_resource_at_scale (PLANK_G_RESOURCE_PATH "/img/application-default-icon.svg", width, height, scale);
		_cairo_surface_destroy0 (surface);
		surface = _tmp29_;
	}
	result = surface;
	all_names = (_vala_array_free (all_names, all_names_length1, (GDestroyNotify) g_free), NULL);
	return result;
}

static cairo_surface_t*
plank_drawing_service_load_surface_from_resource_at_scale (const gchar* resource,
                                                           gint width,
                                                           gint height,
                                                           gint scale)
{
	GdkPixbuf* pbuf = NULL;
	cairo_surface_t* surface = NULL;
	GdkPixbuf* _tmp3_;
	GError* _inner_error0_ = NULL;
	cairo_surface_t* result;
	g_return_val_if_fail (resource != NULL, NULL);
	pbuf = NULL;
	surface = NULL;
	{
		GdkPixbuf* _tmp0_ = NULL;
		GdkPixbuf* _tmp1_;
		GdkPixbuf* _tmp2_;
		_tmp1_ = gdk_pixbuf_new_from_resource_at_scale (resource, width, height, TRUE, &_inner_error0_);
		_tmp0_ = _tmp1_;
		if (G_UNLIKELY (_inner_error0_ != NULL)) {
			goto __catch0_g_error;
		}
		_tmp2_ = _tmp0_;
		_tmp0_ = NULL;
		_g_object_unref0 (pbuf);
		pbuf = _tmp2_;
		_g_object_unref0 (_tmp0_);
	}
	goto __finally0;
	__catch0_g_error:
	{
		g_clear_error (&_inner_error0_);
	}
	__finally0:
	if (G_UNLIKELY (_inner_error0_ != NULL)) {
		_cairo_surface_destroy0 (surface);
		_g_object_unref0 (pbuf);
		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 NULL;
	}
	_tmp3_ = pbuf;
	if (_tmp3_ != NULL) {
		cairo_surface_t* _tmp4_;
		cairo_t* cr = NULL;
		cairo_surface_t* _tmp5_;
		cairo_t* _tmp6_;
		cairo_t* _tmp7_;
		GdkPixbuf* _tmp8_;
		GdkPixbuf* _tmp9_;
		gint _tmp10_;
		gint _tmp11_;
		GdkPixbuf* _tmp12_;
		gint _tmp13_;
		gint _tmp14_;
		cairo_t* _tmp15_;
		cairo_surface_t* _tmp16_;
		_tmp4_ = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width, height);
		_cairo_surface_destroy0 (surface);
		surface = _tmp4_;
		_tmp5_ = surface;
		_tmp6_ = cairo_create (_tmp5_);
		cr = _tmp6_;
		_tmp7_ = cr;
		_tmp8_ = pbuf;
		_tmp9_ = pbuf;
		_tmp10_ = gdk_pixbuf_get_width (_tmp9_);
		_tmp11_ = _tmp10_;
		_tmp12_ = pbuf;
		_tmp13_ = gdk_pixbuf_get_height (_tmp12_);
		_tmp14_ = _tmp13_;
		gdk_cairo_set_source_pixbuf (_tmp7_, _tmp8_, (gdouble) ((width - _tmp11_) / 2), (gdouble) ((height - _tmp14_) / 2));
		_tmp15_ = cr;
		cairo_paint (_tmp15_);
		_tmp16_ = surface;
		cairo_surface_set_device_scale (_tmp16_, (gdouble) scale, (gdouble) scale);
		_cairo_destroy0 (cr);
	}
	result = surface;
	_g_object_unref0 (pbuf);
	return result;
}

static cairo_surface_t*
plank_drawing_service_load_surface (const gchar* icon,
                                    gint size,
                                    gint scale)
{
	cairo_surface_t* surface = NULL;
	GtkIconInfo* info = NULL;
	GtkIconTheme* icon_theme = NULL;
	GtkIconTheme* _tmp0_;
	GError* _inner_error0_ = NULL;
	cairo_surface_t* result;
	g_return_val_if_fail (icon != NULL, NULL);
	surface = NULL;
	info = NULL;
	_tmp0_ = plank_drawing_service_get_icon_theme ();
	icon_theme = _tmp0_;
	g_mutex_lock (&plank_drawing_service_icon_theme_mutex);
	{
		GtkIconTheme* _tmp1_;
		GtkIconInfo* _tmp2_;
		GtkIconInfo* _tmp3_;
		_tmp1_ = icon_theme;
		_tmp2_ = gtk_icon_theme_lookup_icon_for_scale (_tmp1_, icon, size, scale, GTK_ICON_LOOKUP_FORCE_SIZE);
		_g_object_unref0 (info);
		info = _tmp2_;
		_tmp3_ = info;
		if (_tmp3_ != NULL) {
			cairo_surface_t* _tmp4_ = NULL;
			GtkIconInfo* _tmp5_;
			cairo_surface_t* _tmp6_;
			cairo_surface_t* _tmp7_;
			_tmp5_ = info;
			_tmp6_ = gtk_icon_info_load_surface (_tmp5_, NULL, &_inner_error0_);
			_tmp4_ = _tmp6_;
			if (G_UNLIKELY (_inner_error0_ != NULL)) {
				goto __catch0_g_error;
			}
			_tmp7_ = _tmp4_;
			_tmp4_ = NULL;
			_cairo_surface_destroy0 (surface);
			surface = _tmp7_;
			_cairo_surface_destroy0 (_tmp4_);
		}
	}
	goto __finally0;
	__catch0_g_error:
	{
		g_clear_error (&_inner_error0_);
	}
	__finally0:
	if (G_UNLIKELY (_inner_error0_ != NULL)) {
		_g_object_unref0 (info);
		_cairo_surface_destroy0 (surface);
		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 NULL;
	}
	{
		gboolean _tmp8_ = FALSE;
		cairo_surface_t* _tmp9_;
		_tmp9_ = surface;
		if (_tmp9_ == NULL) {
			_tmp8_ = string_contains (icon, ".");
		} else {
			_tmp8_ = FALSE;
		}
		if (_tmp8_) {
			gchar** parts = NULL;
			gchar** _tmp10_;
			gchar** _tmp11_;
			gint parts_length1;
			gint _parts_size_;
			GtkIconTheme* _tmp12_;
			gchar** _tmp13_;
			gint _tmp13__length1;
			const gchar* _tmp14_;
			GtkIconInfo* _tmp15_;
			GtkIconInfo* _tmp16_;
			_tmp11_ = _tmp10_ = g_strsplit (icon, ".", 0);
			parts = _tmp11_;
			parts_length1 = _vala_array_length (_tmp10_);
			_parts_size_ = parts_length1;
			_tmp12_ = icon_theme;
			_tmp13_ = parts;
			_tmp13__length1 = parts_length1;
			_tmp14_ = _tmp13_[0];
			_tmp15_ = gtk_icon_theme_lookup_icon_for_scale (_tmp12_, _tmp14_, size, scale, GTK_ICON_LOOKUP_FORCE_SIZE);
			_g_object_unref0 (info);
			info = _tmp15_;
			_tmp16_ = info;
			if (_tmp16_ != NULL) {
				cairo_surface_t* _tmp17_ = NULL;
				GtkIconInfo* _tmp18_;
				cairo_surface_t* _tmp19_;
				cairo_surface_t* _tmp20_;
				_tmp18_ = info;
				_tmp19_ = gtk_icon_info_load_surface (_tmp18_, NULL, &_inner_error0_);
				_tmp17_ = _tmp19_;
				if (G_UNLIKELY (_inner_error0_ != NULL)) {
					parts = (_vala_array_free (parts, parts_length1, (GDestroyNotify) g_free), NULL);
					goto __catch1_g_error;
				}
				_tmp20_ = _tmp17_;
				_tmp17_ = NULL;
				_cairo_surface_destroy0 (surface);
				surface = _tmp20_;
				_cairo_surface_destroy0 (_tmp17_);
			}
			parts = (_vala_array_free (parts, parts_length1, (GDestroyNotify) g_free), NULL);
		}
	}
	goto __finally1;
	__catch1_g_error:
	{
		g_clear_error (&_inner_error0_);
	}
	__finally1:
	if (G_UNLIKELY (_inner_error0_ != NULL)) {
		_g_object_unref0 (info);
		_cairo_surface_destroy0 (surface);
		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 NULL;
	}
	g_mutex_unlock (&plank_drawing_service_icon_theme_mutex);
	result = surface;
	_g_object_unref0 (info);
	return result;
}

/**
 * Scales a {@link Gdk.Pixbuf}, maintaining the original aspect ratio.
 *
 * @param source the pixbuf to scale
 * @param width the width of the scaled pixbuf
 * @param height the height of the scaled pixbuf
 * @return the scaled pixbuf
 */
GdkPixbuf*
plank_drawing_service_ar_scale (GdkPixbuf* source,
                                gint width,
                                gint height)
{
	gdouble source_width = 0.0;
	gint _tmp0_;
	gint _tmp1_;
	gdouble source_height = 0.0;
	gint _tmp2_;
	gint _tmp3_;
	gdouble x_scale = 0.0;
	gdouble y_scale = 0.0;
	gdouble scale = 0.0;
	gint scaled_width = 0;
	gint scaled_height = 0;
	GdkPixbuf* _tmp5_;
	GdkPixbuf* result;
	g_return_val_if_fail (source != NULL, NULL);
	_tmp0_ = gdk_pixbuf_get_width (source);
	_tmp1_ = _tmp0_;
	source_width = (gdouble) _tmp1_;
	_tmp2_ = gdk_pixbuf_get_height (source);
	_tmp3_ = _tmp2_;
	source_height = (gdouble) _tmp3_;
	x_scale = width / source_width;
	y_scale = height / source_height;
	scale = MIN (x_scale, y_scale);
	if (scale == ((gdouble) 1)) {
		GdkPixbuf* _tmp4_;
		_tmp4_ = _g_object_ref0 (source);
		result = _tmp4_;
		return result;
	}
	scaled_width = MAX (1, (gint) (source_width * scale));
	scaled_height = MAX (1, (gint) (source_height * scale));
	_tmp5_ = gdk_pixbuf_scale_simple (source, scaled_width, scaled_height, GDK_INTERP_HYPER);
	result = _tmp5_;
	return result;
}

/**
 * Computes and returns the average color of a {@link Gdk.Pixbuf}.
 * The resulting color is the average of all pixels which aren't
 * nearly transparent while saturated pixels are weighted more than
 * "grey" ones.
 *
 * @param source the pixbuf to use
 * @return the average color of the pixbuf
 */
void
plank_drawing_service_average_color (GdkPixbuf* source,
                                     PlankColor* result)
{
	guint8 r = 0U;
	guint8 g = 0U;
	guint8 b = 0U;
	guint8 a = 0U;
	guint8 min = 0U;
	guint8 max = 0U;
	gdouble delta = 0.0;
	gdouble rTotal = 0.0;
	gdouble gTotal = 0.0;
	gdouble bTotal = 0.0;
	gdouble bTotal2 = 0.0;
	gdouble gTotal2 = 0.0;
	gdouble rTotal2 = 0.0;
	gdouble aTotal2 = 0.0;
	guint8* dataPtr = NULL;
	guint8* _tmp0_;
	gint n_channels = 0;
	gint _tmp1_;
	gint _tmp2_;
	gint width = 0;
	gint _tmp3_;
	gint _tmp4_;
	gint height = 0;
	gint _tmp5_;
	gint _tmp6_;
	gint rowstride = 0;
	gint _tmp7_;
	gint _tmp8_;
	gint length = 0;
	gint pixels = 0;
	gdouble scoreTotal = 0.0;
	gdouble max_val = 0.0;
	PlankColor _tmp24_ = {0};
	g_return_if_fail (source != NULL);
	rTotal = 0.0;
	gTotal = 0.0;
	bTotal = 0.0;
	bTotal2 = 0.0;
	gTotal2 = 0.0;
	rTotal2 = 0.0;
	aTotal2 = 0.0;
	_tmp0_ = gdk_pixbuf_get_pixels (source);
	dataPtr = _tmp0_;
	_tmp1_ = gdk_pixbuf_get_n_channels (source);
	_tmp2_ = _tmp1_;
	n_channels = _tmp2_;
	_tmp3_ = gdk_pixbuf_get_width (source);
	_tmp4_ = _tmp3_;
	width = _tmp4_;
	_tmp5_ = gdk_pixbuf_get_height (source);
	_tmp6_ = _tmp5_;
	height = _tmp6_;
	_tmp7_ = gdk_pixbuf_get_rowstride (source);
	_tmp8_ = _tmp7_;
	rowstride = _tmp8_;
	length = width * height;
	pixels = (height * rowstride) / n_channels;
	scoreTotal = 0.0;
	{
		gint i = 0;
		i = 0;
		{
			gboolean _tmp9_ = FALSE;
			_tmp9_ = TRUE;
			while (TRUE) {
				guint8* _tmp11_;
				guint8 _tmp12_;
				guint8* _tmp13_;
				guint8 _tmp14_;
				guint8* _tmp15_;
				guint8 _tmp16_;
				guint8* _tmp17_;
				guint8 _tmp18_;
				gdouble _tmp21_ = 0.0;
				gdouble score = 0.0;
				guint8* _tmp22_;
				if (!_tmp9_) {
					gint _tmp10_;
					_tmp10_ = i;
					i = _tmp10_ + 1;
				}
				_tmp9_ = FALSE;
				if (!(i < pixels)) {
					break;
				}
				_tmp11_ = dataPtr;
				_tmp12_ = _tmp11_[0];
				r = _tmp12_;
				_tmp13_ = dataPtr;
				_tmp14_ = _tmp13_[1];
				g = _tmp14_;
				_tmp15_ = dataPtr;
				_tmp16_ = _tmp15_[2];
				b = _tmp16_;
				_tmp17_ = dataPtr;
				_tmp18_ = _tmp17_[3];
				a = _tmp18_;
				if (a <= PLANK_DRAWING_SERVICE_ALPHA_THRESHOLD) {
					gint _tmp19_;
					guint8* _tmp20_;
					_tmp19_ = length;
					length = _tmp19_ - 1;
					_tmp20_ = dataPtr;
					dataPtr = _tmp20_ + n_channels;
					continue;
				}
				min = MIN (r, MIN (g, b));
				max = MAX (r, MAX (g, b));
				delta = (gdouble) (max - min);
				if (delta == ((gdouble) 0)) {
					_tmp21_ = 0.0;
				} else {
					_tmp21_ = delta / max;
				}
				score = PLANK_DRAWING_SERVICE_SATURATION_WEIGHT * _tmp21_;
				bTotal += (score * b) / a;
				gTotal += (score * g) / a;
				rTotal += (score * r) / a;
				scoreTotal += score;
				bTotal2 += (gdouble) b;
				gTotal2 += (gdouble) g;
				rTotal2 += (gdouble) r;
				aTotal2 += (gdouble) a;
				_tmp22_ = dataPtr;
				dataPtr = _tmp22_ + n_channels;
			}
		}
	}
	if (length <= 0) {
		PlankColor _tmp23_ = {0};
		_tmp23_.red = 0.0;
		_tmp23_.green = 0.0;
		_tmp23_.blue = 0.0;
		_tmp23_.alpha = 0.0;
		*result = _tmp23_;
		return;
	}
	scoreTotal /= (gdouble) length;
	bTotal /= (gdouble) length;
	gTotal /= (gdouble) length;
	rTotal /= (gdouble) length;
	if (scoreTotal > 0.0) {
		bTotal /= scoreTotal;
		gTotal /= scoreTotal;
		rTotal /= scoreTotal;
	}
	bTotal2 /= (gdouble) (length * G_MAXUINT8);
	gTotal2 /= (gdouble) (length * G_MAXUINT8);
	rTotal2 /= (gdouble) (length * G_MAXUINT8);
	aTotal2 /= (gdouble) (length * G_MAXUINT8);
	if (scoreTotal <= PLANK_DRAWING_SERVICE_WEIGHT_THRESHOLD) {
		gdouble f = 0.0;
		gdouble rf = 0.0;
		f = (1.0 / PLANK_DRAWING_SERVICE_WEIGHT_THRESHOLD) * scoreTotal;
		rf = 1.0 - f;
		bTotal = (bTotal * f) + (bTotal2 * rf);
		gTotal = (gTotal * f) + (gTotal2 * rf);
		rTotal = (rTotal * f) + (rTotal2 * rf);
	}
	max_val = MAX (rTotal, MAX (gTotal, bTotal));
	if (max_val > 1.0) {
		bTotal /= max_val;
		gTotal /= max_val;
		rTotal /= max_val;
	}
	_tmp24_.red = rTotal;
	_tmp24_.green = gTotal;
	_tmp24_.blue = bTotal;
	_tmp24_.alpha = aTotal2;
	*result = _tmp24_;
	return;
}

static void
plank_drawing_service_class_init (PlankDrawingServiceClass * klass,
                                  gpointer klass_data)
{
	plank_drawing_service_parent_class = g_type_class_peek_parent (klass);
	G_OBJECT_CLASS (klass)->finalize = plank_drawing_service_finalize;
}

static void
plank_drawing_service_instance_init (PlankDrawingService * self,
                                     gpointer klass)
{
}

static void
plank_drawing_service_finalize (GObject * obj)
{
	PlankDrawingService * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (obj, PLANK_TYPE_DRAWING_SERVICE, PlankDrawingService);
	G_OBJECT_CLASS (plank_drawing_service_parent_class)->finalize (obj);
}

/**
 * Utility service for loading icons and working with pixbufs.
 */
static GType
plank_drawing_service_get_type_once (void)
{
	static const GTypeInfo g_define_type_info = { sizeof (PlankDrawingServiceClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) plank_drawing_service_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (PlankDrawingService), 0, (GInstanceInitFunc) plank_drawing_service_instance_init, NULL };
	GType plank_drawing_service_type_id;
	plank_drawing_service_type_id = g_type_register_static (G_TYPE_OBJECT, "PlankDrawingService", &g_define_type_info, 0);
	return plank_drawing_service_type_id;
}

GType
plank_drawing_service_get_type (void)
{
	static volatile gsize plank_drawing_service_type_id__once = 0;
	if (g_once_init_enter (&plank_drawing_service_type_id__once)) {
		GType plank_drawing_service_type_id;
		plank_drawing_service_type_id = plank_drawing_service_get_type_once ();
		g_once_init_leave (&plank_drawing_service_type_id__once, plank_drawing_service_type_id);
	}
	return plank_drawing_service_type_id__once;
}

static void
_vala_array_destroy (gpointer array,
                     gssize array_length,
                     GDestroyNotify destroy_func)
{
	if ((array != NULL) && (destroy_func != NULL)) {
		gssize i;
		for (i = 0; i < array_length; i = i + 1) {
			if (((gpointer*) array)[i] != NULL) {
				destroy_func (((gpointer*) array)[i]);
			}
		}
	}
}

static void
_vala_array_free (gpointer array,
                  gssize array_length,
                  GDestroyNotify destroy_func)
{
	_vala_array_destroy (array, array_length, destroy_func);
	g_free (array);
}

static gssize
_vala_array_length (gpointer array)
{
	gssize length;
	length = 0;
	if (array) {
		while (((gpointer*) array)[length]) {
			length++;
		}
	}
	return length;
}

