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

/*
 * This file is part of budgie-desktop
 *
 * Copyright © 2015-2022 Budgie Desktop Developers
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 */

#include <stdlib.h>
#include <string.h>
#include <glib.h>
#include "statusapplet.h"
#include <gtk/gtk.h>
#include <pulse/pulseaudio.h>
#include <gvc-mixer-control.h>
#include <gvc-mixer-stream.h>
#include <float.h>
#include <math.h>
#include <glib-object.h>
#include "plugin.h"
#include <gdk/gdk.h>
#include <gio/gdesktopappinfo.h>
#include <gio/gio.h>

#define MIXER_NAME "Budgie Volume Control"

enum  {
	SOUND_INDICATOR_0_PROPERTY,
	SOUND_INDICATOR_WIDGET_PROPERTY,
	SOUND_INDICATOR_MIXER_PROPERTY,
	SOUND_INDICATOR_NUM_PROPERTIES
};
static GParamSpec* sound_indicator_properties[SOUND_INDICATOR_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_error_free0(var) ((var == NULL) ? NULL : (var = (g_error_free (var), NULL)))

struct _SoundIndicatorPrivate {
	GtkImage* _widget;
	GvcMixerControl* _mixer;
	GvcMixerStream* stream;
	GtkButtonBox* buttons;
	GtkButton* settings_button;
	GtkButton* mute_button;
	GtkButton* volume_down;
	GtkButton* volume_up;
	GtkScale* volume_scale;
	gdouble step_size;
	gulong notify_id;
	gulong scale_id;
};

static gint SoundIndicator_private_offset;
static gpointer sound_indicator_parent_class = NULL;
static GType sound_indicator_type_id = 0;

static void _sound_indicator_on_state_change_gvc_mixer_control_state_changed (GvcMixerControl* _sender,
                                                                       guint new_state,
                                                                       gpointer self);
static void sound_indicator_on_sink_changed (SoundIndicator* self,
                                      guint id);
static void _sound_indicator_on_sink_changed_gvc_mixer_control_default_sink_changed (GvcMixerControl* _sender,
                                                                              guint id,
                                                                              gpointer self);
static void sound_indicator_create_sound_popover (SoundIndicator* self);
static gboolean _sound_indicator_on_scroll_event_gtk_widget_scroll_event (GtkWidget* _sender,
                                                                   GdkEventScroll* event,
                                                                   gpointer self);
static gboolean sound_indicator_on_button_release_event (SoundIndicator* self,
                                                  GdkEventButton* e);
static gboolean _sound_indicator_on_button_release_event_gtk_widget_button_release_event (GtkWidget* _sender,
                                                                                   GdkEventButton* event,
                                                                                   gpointer self);
static void sound_indicator_toggle_mute_state (SoundIndicator* self);
static void sound_indicator_on_scale_changed (SoundIndicator* self);
static void _sound_indicator_on_scale_changed_gtk_range_value_changed (GtkRange* _sender,
                                                                gpointer self);
static void _sound_indicator_toggle_mute_state_gtk_button_clicked (GtkButton* _sender,
                                                            gpointer self);
static void sound_indicator_open_sound_settings (SoundIndicator* self);
static void _sound_indicator_open_sound_settings_gtk_button_clicked (GtkButton* _sender,
                                                              gpointer self);
static void __lambda8_ (SoundIndicator* self);
static void sound_indicator_adjust_volume_increment (SoundIndicator* self,
                                              gdouble increment);
static void ___lambda8__gtk_button_clicked (GtkButton* _sender,
                                     gpointer self);
static void __lambda9_ (SoundIndicator* self);
static void ___lambda9__gtk_button_clicked (GtkButton* _sender,
                                     gpointer self);
static void sound_indicator_set_default_mixer (SoundIndicator* self);
static void sound_indicator_on_notify (SoundIndicator* self,
                                GObject* o,
                                GParamSpec* p);
static void _sound_indicator_on_notify_g_object_notify (GObject* _sender,
                                                 GParamSpec* pspec,
                                                 gpointer self);
static void sound_indicator_finalize (GObject * obj);
static void _vala_sound_indicator_get_property (GObject * object,
                                         guint property_id,
                                         GValue * value,
                                         GParamSpec * pspec);
static void _vala_sound_indicator_set_property (GObject * object,
                                         guint property_id,
                                         const GValue * value,
                                         GParamSpec * pspec);
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 inline gpointer
sound_indicator_get_instance_private (SoundIndicator* self)
{
	return G_STRUCT_MEMBER_P (self, SoundIndicator_private_offset);
}

static void
_sound_indicator_on_state_change_gvc_mixer_control_state_changed (GvcMixerControl* _sender,
                                                                  guint new_state,
                                                                  gpointer self)
{
	sound_indicator_on_state_change ((SoundIndicator*) self, new_state);
}

static void
_sound_indicator_on_sink_changed_gvc_mixer_control_default_sink_changed (GvcMixerControl* _sender,
                                                                         guint id,
                                                                         gpointer self)
{
	sound_indicator_on_sink_changed ((SoundIndicator*) self, id);
}

static gboolean
_sound_indicator_on_scroll_event_gtk_widget_scroll_event (GtkWidget* _sender,
                                                          GdkEventScroll* event,
                                                          gpointer self)
{
	gboolean result;
	result = sound_indicator_on_scroll_event ((SoundIndicator*) self, event);
	return result;
}

static gboolean
_sound_indicator_on_button_release_event_gtk_widget_button_release_event (GtkWidget* _sender,
                                                                          GdkEventButton* event,
                                                                          gpointer self)
{
	gboolean result;
	result = sound_indicator_on_button_release_event ((SoundIndicator*) self, event);
	return result;
}

SoundIndicator*
sound_indicator_construct (GType object_type)
{
	SoundIndicator * self = NULL;
	GtkImage* _tmp0_;
	GtkImage* _tmp1_;
	GtkEventBox* _tmp2_;
	GtkEventBox* _tmp3_;
	GtkImage* _tmp4_;
	GtkEventBox* _tmp5_;
	GtkEventBox* _tmp6_;
	GtkEventBox* _tmp7_;
	GvcMixerControl* _tmp8_;
	GvcMixerControl* _tmp9_;
	GvcMixerControl* _tmp10_;
	GvcMixerControl* _tmp11_;
	GvcMixerControl* _tmp12_;
	GtkStyleContext* _tmp13_;
	BudgiePopover* _tmp14_;
	GtkStyleContext* _tmp15_;
	GtkEventBox* _tmp16_;
	GtkEventBox* _tmp17_;
	GtkEventBox* _tmp18_;
	GtkEventBox* _tmp19_;
	self = (SoundIndicator*) g_object_new (object_type, NULL);
	_tmp0_ = (GtkImage*) gtk_image_new_from_icon_name ("audio-volume-muted-symbolic", (GtkIconSize) GTK_ICON_SIZE_MENU);
	g_object_ref_sink (_tmp0_);
	_tmp1_ = _tmp0_;
	sound_indicator_set_widget (self, _tmp1_);
	_g_object_unref0 (_tmp1_);
	_tmp2_ = (GtkEventBox*) gtk_event_box_new ();
	g_object_ref_sink (_tmp2_);
	_g_object_unref0 (self->ebox);
	self->ebox = _tmp2_;
	_tmp3_ = self->ebox;
	_tmp4_ = self->priv->_widget;
	gtk_container_add ((GtkContainer*) _tmp3_, (GtkWidget*) _tmp4_);
	_tmp5_ = self->ebox;
	g_object_set ((GtkWidget*) _tmp5_, "margin", 0, NULL);
	_tmp6_ = self->ebox;
	gtk_container_set_border_width ((GtkContainer*) _tmp6_, (guint) 0);
	_tmp7_ = self->ebox;
	gtk_container_add ((GtkContainer*) self, (GtkWidget*) _tmp7_);
	_tmp8_ = gvc_mixer_control_new (MIXER_NAME);
	_tmp9_ = _tmp8_;
	sound_indicator_set_mixer (self, _tmp9_);
	_g_object_unref0 (_tmp9_);
	_tmp10_ = self->priv->_mixer;
	g_signal_connect_object (_tmp10_, "state-changed", (GCallback) _sound_indicator_on_state_change_gvc_mixer_control_state_changed, self, 0);
	_tmp11_ = self->priv->_mixer;
	g_signal_connect_object (_tmp11_, "default-sink-changed", (GCallback) _sound_indicator_on_sink_changed_gvc_mixer_control_default_sink_changed, self, 0);
	_tmp12_ = self->priv->_mixer;
	gvc_mixer_control_open (_tmp12_);
	sound_indicator_create_sound_popover (self);
	_tmp13_ = gtk_widget_get_style_context ((GtkWidget*) self);
	gtk_style_context_add_class (_tmp13_, "sound-applet");
	_tmp14_ = self->popover;
	_tmp15_ = gtk_widget_get_style_context ((GtkWidget*) _tmp14_);
	gtk_style_context_add_class (_tmp15_, "sound-popover");
	_tmp16_ = self->ebox;
	gtk_widget_add_events ((GtkWidget*) _tmp16_, (gint) GDK_SCROLL_MASK);
	_tmp17_ = self->ebox;
	gtk_widget_add_events ((GtkWidget*) _tmp17_, (gint) GDK_BUTTON_RELEASE_MASK);
	_tmp18_ = self->ebox;
	g_signal_connect_object ((GtkWidget*) _tmp18_, "scroll-event", (GCallback) _sound_indicator_on_scroll_event_gtk_widget_scroll_event, self, 0);
	_tmp19_ = self->ebox;
	g_signal_connect_object ((GtkWidget*) _tmp19_, "button-release-event", (GCallback) _sound_indicator_on_button_release_event_gtk_widget_button_release_event, self, 0);
	gtk_widget_show_all ((GtkWidget*) self);
	return self;
}

SoundIndicator*
sound_indicator_new (void)
{
	return sound_indicator_construct (TYPE_SOUND_INDICATOR);
}

static gboolean
sound_indicator_on_button_release_event (SoundIndicator* self,
                                         GdkEventButton* e)
{
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	g_return_val_if_fail (e != NULL, FALSE);
	if (e->button == ((guint) GDK_BUTTON_MIDDLE)) {
		sound_indicator_toggle_mute_state (self);
	} else {
		result = GDK_EVENT_PROPAGATE;
		return result;
	}
	result = GDK_EVENT_STOP;
	return result;
}

/**
 * Create the GtkPopover to display on primary click action, with an adjustable
 * scale
 */
static gpointer
_g_object_ref0 (gpointer self)
{
	return self ? g_object_ref (self) : NULL;
}

static void
_sound_indicator_on_scale_changed_gtk_range_value_changed (GtkRange* _sender,
                                                           gpointer self)
{
	sound_indicator_on_scale_changed ((SoundIndicator*) self);
}

static void
_sound_indicator_toggle_mute_state_gtk_button_clicked (GtkButton* _sender,
                                                       gpointer self)
{
	sound_indicator_toggle_mute_state ((SoundIndicator*) self);
}

static void
_sound_indicator_open_sound_settings_gtk_button_clicked (GtkButton* _sender,
                                                         gpointer self)
{
	sound_indicator_open_sound_settings ((SoundIndicator*) self);
}

static void
__lambda8_ (SoundIndicator* self)
{
	sound_indicator_adjust_volume_increment (self, -self->priv->step_size);
}

static void
___lambda8__gtk_button_clicked (GtkButton* _sender,
                                gpointer self)
{
	__lambda8_ ((SoundIndicator*) self);
}

static void
__lambda9_ (SoundIndicator* self)
{
	sound_indicator_adjust_volume_increment (self, +self->priv->step_size);
}

static void
___lambda9__gtk_button_clicked (GtkButton* _sender,
                                gpointer self)
{
	__lambda9_ ((SoundIndicator*) self);
}

static void
sound_indicator_create_sound_popover (SoundIndicator* self)
{
	GtkEventBox* _tmp0_;
	BudgiePopover* _tmp1_;
	GtkBox* main_box = NULL;
	GtkBox* _tmp2_;
	GtkBox* _tmp3_;
	GtkBox* direct_volume_controls = NULL;
	GtkBox* _tmp4_;
	GtkScale* _tmp5_;
	GtkScale* _tmp6_;
	GtkScale* _tmp7_;
	GtkScale* _tmp8_;
	GtkScale* _tmp9_;
	GtkButton* _tmp10_;
	GtkButton* _tmp11_;
	GtkButton* _tmp12_;
	GtkButton* _tmp13_;
	GtkButton** b_list = NULL;
	GtkButton* _tmp14_;
	GtkButton* _tmp15_;
	GtkButton* _tmp16_;
	GtkButton* _tmp17_;
	GtkButton* _tmp18_;
	GtkButton* _tmp19_;
	GtkButton* _tmp20_;
	GtkButton* _tmp21_;
	GtkButton** _tmp22_;
	gint b_list_length1;
	gint _b_list_size_;
	GtkButtonBox* _tmp34_;
	GtkButtonBox* _tmp35_;
	GtkButtonBox* _tmp36_;
	GtkButton* _tmp37_;
	GtkButtonBox* _tmp38_;
	GtkButton* _tmp39_;
	GtkBox* _tmp40_;
	GtkButton* _tmp41_;
	GtkBox* _tmp42_;
	GtkScale* _tmp43_;
	GtkBox* _tmp44_;
	GtkButton* _tmp45_;
	GtkBox* _tmp46_;
	GtkBox* _tmp47_;
	GtkBox* _tmp48_;
	GtkButtonBox* _tmp49_;
	BudgiePopover* _tmp50_;
	GtkBox* _tmp51_;
	GtkScale* _tmp52_;
	gulong _tmp53_;
	GtkButton* _tmp54_;
	GtkButton* _tmp55_;
	GtkButton* _tmp56_;
	GtkButton* _tmp57_;
	BudgiePopover* _tmp58_;
	GtkWidget* _tmp59_;
	g_return_if_fail (self != NULL);
	_tmp0_ = self->ebox;
	_tmp1_ = (BudgiePopover*) budgie_popover_new ((GtkWidget*) _tmp0_);
	g_object_ref_sink (_tmp1_);
	_g_object_unref0 (self->popover);
	self->popover = _tmp1_;
	_tmp2_ = (GtkBox*) gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
	g_object_ref_sink (_tmp2_);
	main_box = _tmp2_;
	_tmp3_ = main_box;
	gtk_container_set_border_width ((GtkContainer*) _tmp3_, (guint) 6);
	_tmp4_ = (GtkBox*) gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
	g_object_ref_sink (_tmp4_);
	direct_volume_controls = _tmp4_;
	_tmp5_ = (GtkScale*) gtk_scale_new_with_range (GTK_ORIENTATION_HORIZONTAL, (gdouble) 0, (gdouble) 100, (gdouble) 1);
	g_object_ref_sink (_tmp5_);
	_g_object_unref0 (self->priv->volume_scale);
	self->priv->volume_scale = _tmp5_;
	_tmp6_ = self->priv->volume_scale;
	gtk_scale_set_draw_value (_tmp6_, FALSE);
	_tmp7_ = self->priv->volume_scale;
	gtk_widget_set_can_focus ((GtkWidget*) _tmp7_, FALSE);
	_tmp8_ = self->priv->volume_scale;
	gtk_range_set_inverted ((GtkRange*) _tmp8_, FALSE);
	_tmp9_ = self->priv->volume_scale;
	gtk_widget_set_size_request ((GtkWidget*) _tmp9_, 140, -1);
	_tmp10_ = (GtkButton*) gtk_button_new_from_icon_name ("preferences-system-symbolic", (GtkIconSize) GTK_ICON_SIZE_BUTTON);
	g_object_ref_sink (_tmp10_);
	_g_object_unref0 (self->priv->settings_button);
	self->priv->settings_button = _tmp10_;
	_tmp11_ = (GtkButton*) gtk_button_new_from_icon_name ("audio-volume-high-symbolic", (GtkIconSize) GTK_ICON_SIZE_BUTTON);
	g_object_ref_sink (_tmp11_);
	_g_object_unref0 (self->priv->mute_button);
	self->priv->mute_button = _tmp11_;
	_tmp12_ = (GtkButton*) gtk_button_new_from_icon_name ("list-remove-symbolic", (GtkIconSize) GTK_ICON_SIZE_BUTTON);
	g_object_ref_sink (_tmp12_);
	_g_object_unref0 (self->priv->volume_down);
	self->priv->volume_down = _tmp12_;
	_tmp13_ = (GtkButton*) gtk_button_new_from_icon_name ("list-add-symbolic", (GtkIconSize) GTK_ICON_SIZE_BUTTON);
	g_object_ref_sink (_tmp13_);
	_g_object_unref0 (self->priv->volume_up);
	self->priv->volume_up = _tmp13_;
	_tmp14_ = self->priv->settings_button;
	_tmp15_ = _g_object_ref0 (_tmp14_);
	_tmp16_ = self->priv->mute_button;
	_tmp17_ = _g_object_ref0 (_tmp16_);
	_tmp18_ = self->priv->volume_down;
	_tmp19_ = _g_object_ref0 (_tmp18_);
	_tmp20_ = self->priv->volume_up;
	_tmp21_ = _g_object_ref0 (_tmp20_);
	_tmp22_ = g_new0 (GtkButton*, 4 + 1);
	_tmp22_[0] = _tmp15_;
	_tmp22_[1] = _tmp17_;
	_tmp22_[2] = _tmp19_;
	_tmp22_[3] = _tmp21_;
	b_list = _tmp22_;
	b_list_length1 = 4;
	_b_list_size_ = b_list_length1;
	{
		gint i = 0;
		i = 0;
		{
			gboolean _tmp23_ = FALSE;
			_tmp23_ = TRUE;
			while (TRUE) {
				GtkButton** _tmp25_;
				gint _tmp25__length1;
				GtkButton* button = NULL;
				GtkButton** _tmp26_;
				gint _tmp26__length1;
				GtkButton* _tmp27_;
				GtkButton* _tmp28_;
				GtkButton* _tmp29_;
				GtkButton* _tmp30_;
				GtkStyleContext* _tmp31_;
				GtkButton* _tmp32_;
				GtkStyleContext* _tmp33_;
				if (!_tmp23_) {
					gint _tmp24_;
					_tmp24_ = i;
					i = _tmp24_ + 1;
				}
				_tmp23_ = FALSE;
				_tmp25_ = b_list;
				_tmp25__length1 = b_list_length1;
				if (!(i < _tmp25__length1)) {
					break;
				}
				_tmp26_ = b_list;
				_tmp26__length1 = b_list_length1;
				_tmp27_ = _tmp26_[i];
				_tmp28_ = _g_object_ref0 (_tmp27_);
				button = _tmp28_;
				_tmp29_ = button;
				gtk_widget_set_can_focus ((GtkWidget*) _tmp29_, FALSE);
				_tmp30_ = button;
				_tmp31_ = gtk_widget_get_style_context ((GtkWidget*) _tmp30_);
				gtk_style_context_add_class (_tmp31_, GTK_STYLE_CLASS_FLAT);
				_tmp32_ = button;
				_tmp33_ = gtk_widget_get_style_context ((GtkWidget*) _tmp32_);
				gtk_style_context_add_class (_tmp33_, "image-button");
				_g_object_unref0 (button);
			}
		}
	}
	_tmp34_ = (GtkButtonBox*) gtk_button_box_new (GTK_ORIENTATION_HORIZONTAL);
	g_object_ref_sink (_tmp34_);
	_g_object_unref0 (self->priv->buttons);
	self->priv->buttons = _tmp34_;
	_tmp35_ = self->priv->buttons;
	gtk_button_box_set_layout (_tmp35_, GTK_BUTTONBOX_EXPAND);
	_tmp36_ = self->priv->buttons;
	_tmp37_ = self->priv->mute_button;
	gtk_container_add ((GtkContainer*) _tmp36_, (GtkWidget*) _tmp37_);
	_tmp38_ = self->priv->buttons;
	_tmp39_ = self->priv->settings_button;
	gtk_container_add ((GtkContainer*) _tmp38_, (GtkWidget*) _tmp39_);
	_tmp40_ = direct_volume_controls;
	_tmp41_ = self->priv->volume_down;
	gtk_box_pack_start (_tmp40_, (GtkWidget*) _tmp41_, FALSE, FALSE, (guint) 1);
	_tmp42_ = direct_volume_controls;
	_tmp43_ = self->priv->volume_scale;
	gtk_box_pack_start (_tmp42_, (GtkWidget*) _tmp43_, FALSE, FALSE, (guint) 0);
	_tmp44_ = direct_volume_controls;
	_tmp45_ = self->priv->volume_up;
	gtk_box_pack_start (_tmp44_, (GtkWidget*) _tmp45_, FALSE, FALSE, (guint) 1);
	_tmp46_ = main_box;
	_tmp47_ = direct_volume_controls;
	gtk_box_pack_start (_tmp46_, (GtkWidget*) _tmp47_, FALSE, FALSE, (guint) 0);
	_tmp48_ = main_box;
	_tmp49_ = self->priv->buttons;
	gtk_box_pack_start (_tmp48_, (GtkWidget*) _tmp49_, FALSE, FALSE, (guint) 0);
	_tmp50_ = self->popover;
	_tmp51_ = main_box;
	gtk_container_add ((GtkContainer*) _tmp50_, (GtkWidget*) _tmp51_);
	_tmp52_ = self->priv->volume_scale;
	_tmp53_ = g_signal_connect_object ((GtkRange*) _tmp52_, "value-changed", (GCallback) _sound_indicator_on_scale_changed_gtk_range_value_changed, self, 0);
	self->priv->scale_id = _tmp53_;
	_tmp54_ = self->priv->mute_button;
	g_signal_connect_object (_tmp54_, "clicked", (GCallback) _sound_indicator_toggle_mute_state_gtk_button_clicked, self, 0);
	_tmp55_ = self->priv->settings_button;
	g_signal_connect_object (_tmp55_, "clicked", (GCallback) _sound_indicator_open_sound_settings_gtk_button_clicked, self, 0);
	_tmp56_ = self->priv->volume_down;
	g_signal_connect_object (_tmp56_, "clicked", (GCallback) ___lambda8__gtk_button_clicked, self, 0);
	_tmp57_ = self->priv->volume_up;
	g_signal_connect_object (_tmp57_, "clicked", (GCallback) ___lambda9__gtk_button_clicked, self, 0);
	_tmp58_ = self->popover;
	_tmp59_ = gtk_bin_get_child ((GtkBin*) _tmp58_);
	gtk_widget_show_all (_tmp59_);
	b_list = (_vala_array_free (b_list, b_list_length1, (GDestroyNotify) g_object_unref), NULL);
	_g_object_unref0 (direct_volume_controls);
	_g_object_unref0 (main_box);
}

static void
sound_indicator_on_sink_changed (SoundIndicator* self,
                                 guint id)
{
	g_return_if_fail (self != NULL);
	sound_indicator_set_default_mixer (self);
}

static void
_sound_indicator_on_notify_g_object_notify (GObject* _sender,
                                            GParamSpec* pspec,
                                            gpointer self)
{
	sound_indicator_on_notify ((SoundIndicator*) self, _sender, pspec);
}

static void
sound_indicator_set_default_mixer (SoundIndicator* self)
{
	GvcMixerStream* _tmp0_;
	GvcMixerControl* _tmp2_;
	GvcMixerStream* _tmp3_;
	GvcMixerStream* _tmp4_;
	GvcMixerStream* _tmp5_;
	gulong _tmp6_;
	g_return_if_fail (self != NULL);
	_tmp0_ = self->priv->stream;
	if (_tmp0_ != NULL) {
		GvcMixerStream* _tmp1_;
		_tmp1_ = self->priv->stream;
		g_signal_handler_disconnect (_tmp1_, self->priv->notify_id);
	}
	_tmp2_ = self->priv->_mixer;
	_tmp3_ = gvc_mixer_control_get_default_sink (_tmp2_);
	_tmp4_ = _g_object_ref0 (_tmp3_);
	_g_object_unref0 (self->priv->stream);
	self->priv->stream = _tmp4_;
	_tmp5_ = self->priv->stream;
	_tmp6_ = g_signal_connect_object ((GObject*) _tmp5_, "notify", (GCallback) _sound_indicator_on_notify_g_object_notify, self, 0);
	self->priv->notify_id = _tmp6_;
	sound_indicator_update_volume (self);
}

static void
sound_indicator_on_notify (SoundIndicator* self,
                           GObject* o,
                           GParamSpec* p)
{
	gboolean _tmp0_ = FALSE;
	const gchar* _tmp1_;
	g_return_if_fail (self != NULL);
	_tmp1_ = p->name;
	if (g_strcmp0 (_tmp1_, "volume") == 0) {
		_tmp0_ = TRUE;
	} else {
		const gchar* _tmp2_;
		_tmp2_ = p->name;
		_tmp0_ = g_strcmp0 (_tmp2_, "is-muted") == 0;
	}
	if (_tmp0_) {
		sound_indicator_update_volume (self);
	}
}

/**
 * Called when something changes on the mixer, i.e. we connected
 * This is where we hook into the stream for changes
 */
void
sound_indicator_on_state_change (SoundIndicator* self,
                                 guint new_state)
{
	g_return_if_fail (self != NULL);
	if (new_state == ((guint) GVC_STATE_READY)) {
		sound_indicator_set_default_mixer (self);
	}
}

/**
 * Update from scroll events. turn volume up + down.
 */
gboolean
sound_indicator_on_scroll_event (SoundIndicator* self,
                                 GdkEventScroll* event)
{
	GvcMixerStream* _tmp0_;
	guint32 vol = 0U;
	GvcMixerStream* _tmp1_;
	guint32 orig_vol = 0U;
	gdouble max_amp = 0.0;
	GvcMixerControl* _tmp2_;
	gdouble norm = 0.0;
	GvcMixerControl* _tmp3_;
	GtkScale* _tmp4_;
	GvcMixerStream* _tmp5_;
	GtkScale* _tmp7_;
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	g_return_val_if_fail (event != NULL, FALSE);
	_tmp0_ = self->priv->stream;
	g_return_val_if_fail (_tmp0_ != NULL, FALSE);
	_tmp1_ = self->priv->stream;
	vol = gvc_mixer_stream_get_volume (_tmp1_);
	orig_vol = vol;
	switch (event->direction) {
		case GDK_SCROLL_UP:
		{
			vol += (guint32) self->priv->step_size;
			break;
		}
		case GDK_SCROLL_DOWN:
		{
			vol -= (guint32) self->priv->step_size;
			if (vol > orig_vol) {
				vol = (guint32) 0;
			}
			break;
		}
		default:
		{
			result = FALSE;
			return result;
		}
	}
	_tmp2_ = self->priv->_mixer;
	max_amp = gvc_mixer_control_get_vol_max_amplified (_tmp2_);
	_tmp3_ = self->priv->_mixer;
	norm = gvc_mixer_control_get_vol_max_norm (_tmp3_);
	if (max_amp < norm) {
		max_amp = norm;
	}
	if (((gdouble) vol) > max_amp) {
		vol = (guint32) max_amp;
	}
	if (((gdouble) vol) >= norm) {
		vol = (guint32) norm;
	}
	_tmp4_ = self->priv->volume_scale;
	g_signal_handler_block (_tmp4_, self->priv->scale_id);
	_tmp5_ = self->priv->stream;
	if (gvc_mixer_stream_set_volume (_tmp5_, vol)) {
		GvcMixerStream* _tmp6_;
		_tmp6_ = self->priv->stream;
		gvc_mixer_stream_push_volume (_tmp6_);
	}
	_tmp7_ = self->priv->volume_scale;
	g_signal_handler_unblock (_tmp7_, self->priv->scale_id);
	result = TRUE;
	return result;
}

static void
sound_indicator_toggle_mute_state (SoundIndicator* self)
{
	GvcMixerStream* _tmp0_;
	GvcMixerStream* _tmp1_;
	g_return_if_fail (self != NULL);
	_tmp0_ = self->priv->stream;
	_tmp1_ = self->priv->stream;
	gvc_mixer_stream_change_is_muted (_tmp0_, !gvc_mixer_stream_get_is_muted (_tmp1_));
}

/**
 * Update our icon when something changed (volume/mute)
 */
void
sound_indicator_update_volume (SoundIndicator* self)
{
	gdouble vol_norm = 0.0;
	GvcMixerControl* _tmp0_;
	guint32 vol = 0U;
	GvcMixerStream* _tmp1_;
	gint n = 0;
	gchar* image_name = NULL;
	gboolean _tmp2_ = FALSE;
	GvcMixerStream* _tmp3_;
	GtkImage* _tmp8_;
	const gchar* _tmp9_;
	GtkImage* mute_button_image = NULL;
	GtkButton* _tmp10_;
	GtkWidget* _tmp11_;
	GtkImage* _tmp12_;
	GtkImage* _tmp13_;
	gfloat pct = 0.0F;
	guint ipct = 0U;
	GtkImage* _tmp16_;
	gchar* _tmp17_;
	gchar* _tmp18_;
	gchar* _tmp19_;
	gchar* _tmp20_;
	GtkScale* _tmp21_;
	GtkScale* _tmp22_;
	GtkScale* _tmp25_;
	GtkAdjustment* _tmp26_;
	GtkScale* _tmp27_;
	g_return_if_fail (self != NULL);
	_tmp0_ = self->priv->_mixer;
	vol_norm = gvc_mixer_control_get_vol_max_norm (_tmp0_);
	_tmp1_ = self->priv->stream;
	vol = gvc_mixer_stream_get_volume (_tmp1_);
	n = ((gint) floor ((3 * vol) / vol_norm)) + 1;
	_tmp3_ = self->priv->stream;
	if (gvc_mixer_stream_get_is_muted (_tmp3_)) {
		_tmp2_ = TRUE;
	} else {
		_tmp2_ = vol <= ((guint32) 0);
	}
	if (_tmp2_) {
		gchar* _tmp4_;
		_tmp4_ = g_strdup ("audio-volume-muted-symbolic");
		_g_free0 (image_name);
		image_name = _tmp4_;
	} else {
		switch (n) {
			case 1:
			{
				gchar* _tmp5_;
				_tmp5_ = g_strdup ("audio-volume-low-symbolic");
				_g_free0 (image_name);
				image_name = _tmp5_;
				break;
			}
			case 2:
			{
				gchar* _tmp6_;
				_tmp6_ = g_strdup ("audio-volume-medium-symbolic");
				_g_free0 (image_name);
				image_name = _tmp6_;
				break;
			}
			default:
			{
				gchar* _tmp7_;
				_tmp7_ = g_strdup ("audio-volume-high-symbolic");
				_g_free0 (image_name);
				image_name = _tmp7_;
				break;
			}
		}
	}
	_tmp8_ = self->priv->_widget;
	_tmp9_ = image_name;
	gtk_image_set_from_icon_name (_tmp8_, _tmp9_, (GtkIconSize) GTK_ICON_SIZE_MENU);
	_tmp10_ = self->priv->mute_button;
	_tmp11_ = gtk_button_get_image (_tmp10_);
	_tmp12_ = _g_object_ref0 (G_TYPE_CHECK_INSTANCE_CAST (_tmp11_, gtk_image_get_type (), GtkImage));
	mute_button_image = _tmp12_;
	_tmp13_ = mute_button_image;
	if (_tmp13_ != NULL) {
		GtkImage* _tmp14_;
		const gchar* _tmp15_;
		_tmp14_ = mute_button_image;
		_tmp15_ = image_name;
		gtk_image_set_from_icon_name (_tmp14_, _tmp15_, (GtkIconSize) GTK_ICON_SIZE_BUTTON);
	}
	self->priv->step_size = vol_norm / 20;
	pct = (((gfloat) vol) / ((gfloat) vol_norm)) * 100;
	ipct = (guint) round ((gdouble) pct);
	_tmp16_ = self->priv->_widget;
	_tmp17_ = g_strdup_printf ("%u", ipct);
	_tmp18_ = _tmp17_;
	_tmp19_ = g_strconcat (_tmp18_, "%", NULL);
	_tmp20_ = _tmp19_;
	gtk_widget_set_tooltip_text ((GtkWidget*) _tmp16_, _tmp20_);
	_g_free0 (_tmp20_);
	_g_free0 (_tmp18_);
	_tmp21_ = self->priv->volume_scale;
	g_signal_handler_block (_tmp21_, self->priv->scale_id);
	_tmp22_ = self->priv->volume_scale;
	gtk_range_set_range ((GtkRange*) _tmp22_, (gdouble) 0, vol_norm);
	if (((gdouble) vol) > vol_norm) {
		GtkScale* _tmp23_;
		_tmp23_ = self->priv->volume_scale;
		gtk_range_set_value ((GtkRange*) _tmp23_, (gdouble) vol);
	} else {
		GtkScale* _tmp24_;
		_tmp24_ = self->priv->volume_scale;
		gtk_range_set_value ((GtkRange*) _tmp24_, (gdouble) vol);
	}
	_tmp25_ = self->priv->volume_scale;
	_tmp26_ = gtk_range_get_adjustment ((GtkRange*) _tmp25_);
	gtk_adjustment_set_page_increment (_tmp26_, self->priv->step_size);
	_tmp27_ = self->priv->volume_scale;
	g_signal_handler_unblock (_tmp27_, self->priv->scale_id);
	gtk_widget_show_all ((GtkWidget*) self);
	gtk_widget_queue_draw ((GtkWidget*) self);
	_g_object_unref0 (mute_button_image);
	_g_free0 (image_name);
}

/**
 * The scale changed value - update the stream volume to match
 */
static void
sound_indicator_on_scale_changed (SoundIndicator* self)
{
	gboolean _tmp0_ = FALSE;
	GvcMixerStream* _tmp1_;
	gdouble scale_value = 0.0;
	GtkScale* _tmp3_;
	GtkScale* _tmp4_;
	GvcMixerStream* _tmp5_;
	GtkScale* _tmp7_;
	g_return_if_fail (self != NULL);
	_tmp1_ = self->priv->stream;
	if (_tmp1_ == NULL) {
		_tmp0_ = TRUE;
	} else {
		GvcMixerControl* _tmp2_;
		_tmp2_ = self->priv->_mixer;
		_tmp0_ = _tmp2_ == NULL;
	}
	if (_tmp0_) {
		return;
	}
	_tmp3_ = self->priv->volume_scale;
	scale_value = gtk_range_get_value ((GtkRange*) _tmp3_);
	_tmp4_ = self->priv->volume_scale;
	g_signal_handler_block (_tmp4_, self->priv->scale_id);
	_tmp5_ = self->priv->stream;
	if (gvc_mixer_stream_set_volume (_tmp5_, (guint32) scale_value)) {
		GvcMixerStream* _tmp6_;
		_tmp6_ = self->priv->stream;
		gvc_mixer_stream_push_volume (_tmp6_);
	}
	_tmp7_ = self->priv->volume_scale;
	g_signal_handler_unblock (_tmp7_, self->priv->scale_id);
}

/**
 * Adjust the volume by a given +/- increment and bounds limit it
 */
static void
sound_indicator_adjust_volume_increment (SoundIndicator* self,
                                         gdouble increment)
{
	gboolean _tmp0_ = FALSE;
	GvcMixerStream* _tmp1_;
	gint32 vol = 0;
	GvcMixerStream* _tmp3_;
	gdouble max_norm = 0.0;
	GvcMixerControl* _tmp4_;
	GtkScale* _tmp5_;
	GvcMixerStream* _tmp6_;
	GtkScale* _tmp8_;
	g_return_if_fail (self != NULL);
	_tmp1_ = self->priv->stream;
	if (_tmp1_ == NULL) {
		_tmp0_ = TRUE;
	} else {
		GvcMixerControl* _tmp2_;
		_tmp2_ = self->priv->_mixer;
		_tmp0_ = _tmp2_ == NULL;
	}
	if (_tmp0_) {
		return;
	}
	_tmp3_ = self->priv->stream;
	vol = (gint32) gvc_mixer_stream_get_volume (_tmp3_);
	_tmp4_ = self->priv->_mixer;
	max_norm = gvc_mixer_control_get_vol_max_norm (_tmp4_);
	vol += (gint32) increment;
	if (vol < ((gint32) 0)) {
		vol = (gint32) 0;
	} else {
		if (((gdouble) vol) > max_norm) {
			vol = (gint32) max_norm;
		}
	}
	_tmp5_ = self->priv->volume_scale;
	g_signal_handler_block (_tmp5_, self->priv->scale_id);
	_tmp6_ = self->priv->stream;
	if (gvc_mixer_stream_set_volume (_tmp6_, (guint32) vol)) {
		GvcMixerStream* _tmp7_;
		_tmp7_ = self->priv->stream;
		gvc_mixer_stream_push_volume (_tmp7_);
	}
	_tmp8_ = self->priv->volume_scale;
	g_signal_handler_unblock (_tmp8_, self->priv->scale_id);
}

static void
sound_indicator_open_sound_settings (SoundIndicator* self)
{
	BudgiePopover* _tmp0_;
	GDesktopAppInfo* app_info = NULL;
	GDesktopAppInfo* _tmp1_;
	GDesktopAppInfo* _tmp2_;
	GError* _inner_error0_ = NULL;
	g_return_if_fail (self != NULL);
	_tmp0_ = self->popover;
	gtk_widget_hide ((GtkWidget*) _tmp0_);
	_tmp1_ = g_desktop_app_info_new ("budgie-sound-panel.desktop");
	app_info = _tmp1_;
	_tmp2_ = app_info;
	if (_tmp2_ == NULL) {
		_g_object_unref0 (app_info);
		return;
	}
	{
		GDesktopAppInfo* _tmp3_;
		_tmp3_ = app_info;
		g_app_info_launch ((GAppInfo*) _tmp3_, NULL, NULL, &_inner_error0_);
		if (G_UNLIKELY (_inner_error0_ != NULL)) {
			goto __catch0_g_error;
		}
	}
	goto __finally0;
	__catch0_g_error:
	{
		GError* e = NULL;
		GError* _tmp4_;
		const gchar* _tmp5_;
		e = _inner_error0_;
		_inner_error0_ = NULL;
		_tmp4_ = e;
		_tmp5_ = _tmp4_->message;
		g_message ("SoundIndicator.vala:351: Unable to launch budgie-sound-panel.desktop: " \
"%s", _tmp5_);
		_g_error_free0 (e);
	}
	__finally0:
	if (G_UNLIKELY (_inner_error0_ != NULL)) {
		_g_object_unref0 (app_info);
		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;
	}
	_g_object_unref0 (app_info);
}

GtkImage*
sound_indicator_get_widget (SoundIndicator* self)
{
	GtkImage* result;
	GtkImage* _tmp0_;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = self->priv->_widget;
	result = _tmp0_;
	return result;
}

void
sound_indicator_set_widget (SoundIndicator* self,
                            GtkImage* value)
{
	GtkImage* old_value;
	g_return_if_fail (self != NULL);
	old_value = sound_indicator_get_widget (self);
	if (old_value != value) {
		GtkImage* _tmp0_;
		_tmp0_ = _g_object_ref0 (value);
		_g_object_unref0 (self->priv->_widget);
		self->priv->_widget = _tmp0_;
		g_object_notify_by_pspec ((GObject *) self, sound_indicator_properties[SOUND_INDICATOR_WIDGET_PROPERTY]);
	}
}

GvcMixerControl*
sound_indicator_get_mixer (SoundIndicator* self)
{
	GvcMixerControl* result;
	GvcMixerControl* _tmp0_;
	g_return_val_if_fail (self != NULL, NULL);
	_tmp0_ = self->priv->_mixer;
	result = _tmp0_;
	return result;
}

void
sound_indicator_set_mixer (SoundIndicator* self,
                           GvcMixerControl* value)
{
	GvcMixerControl* old_value;
	g_return_if_fail (self != NULL);
	old_value = sound_indicator_get_mixer (self);
	if (old_value != value) {
		GvcMixerControl* _tmp0_;
		_tmp0_ = _g_object_ref0 (value);
		_g_object_unref0 (self->priv->_mixer);
		self->priv->_mixer = _tmp0_;
		g_object_notify_by_pspec ((GObject *) self, sound_indicator_properties[SOUND_INDICATOR_MIXER_PROPERTY]);
	}
}

static void
sound_indicator_class_init (SoundIndicatorClass * klass,
                            gpointer klass_data)
{
	sound_indicator_parent_class = g_type_class_peek_parent (klass);
	g_type_class_adjust_private_offset (klass, &SoundIndicator_private_offset);
	G_OBJECT_CLASS (klass)->get_property = _vala_sound_indicator_get_property;
	G_OBJECT_CLASS (klass)->set_property = _vala_sound_indicator_set_property;
	G_OBJECT_CLASS (klass)->finalize = sound_indicator_finalize;
	/** Current image to display */
	g_object_class_install_property (G_OBJECT_CLASS (klass), SOUND_INDICATOR_WIDGET_PROPERTY, sound_indicator_properties[SOUND_INDICATOR_WIDGET_PROPERTY] = g_param_spec_object ("widget", "widget", "widget", gtk_image_get_type (), G_PARAM_STATIC_STRINGS | G_PARAM_READABLE | G_PARAM_WRITABLE));
	/** Our mixer */
	g_object_class_install_property (G_OBJECT_CLASS (klass), SOUND_INDICATOR_MIXER_PROPERTY, sound_indicator_properties[SOUND_INDICATOR_MIXER_PROPERTY] = g_param_spec_object ("mixer", "mixer", "mixer", gvc_mixer_control_get_type (), G_PARAM_STATIC_STRINGS | G_PARAM_READABLE | G_PARAM_WRITABLE));
}

static void
sound_indicator_instance_init (SoundIndicator * self,
                               gpointer klass)
{
	self->priv = sound_indicator_get_instance_private (self);
}

static void
sound_indicator_finalize (GObject * obj)
{
	SoundIndicator * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (obj, TYPE_SOUND_INDICATOR, SoundIndicator);
	_g_object_unref0 (self->priv->_widget);
	_g_object_unref0 (self->priv->_mixer);
	_g_object_unref0 (self->priv->stream);
	_g_object_unref0 (self->ebox);
	_g_object_unref0 (self->popover);
	_g_object_unref0 (self->priv->buttons);
	_g_object_unref0 (self->priv->settings_button);
	_g_object_unref0 (self->priv->mute_button);
	_g_object_unref0 (self->priv->volume_down);
	_g_object_unref0 (self->priv->volume_up);
	_g_object_unref0 (self->priv->volume_scale);
	G_OBJECT_CLASS (sound_indicator_parent_class)->finalize (obj);
}

GType
sound_indicator_get_type (void)
{
	return sound_indicator_type_id;
}

GType
sound_indicator_register_type (GTypeModule * module)
{
	static const GTypeInfo g_define_type_info = { sizeof (SoundIndicatorClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) sound_indicator_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (SoundIndicator), 0, (GInstanceInitFunc) sound_indicator_instance_init, NULL };
	sound_indicator_type_id = g_type_module_register_type (module, gtk_bin_get_type (), "SoundIndicator", &g_define_type_info, 0);
	SoundIndicator_private_offset = sizeof (SoundIndicatorPrivate);
	return sound_indicator_type_id;
}

static void
_vala_sound_indicator_get_property (GObject * object,
                                    guint property_id,
                                    GValue * value,
                                    GParamSpec * pspec)
{
	SoundIndicator * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (object, TYPE_SOUND_INDICATOR, SoundIndicator);
	switch (property_id) {
		case SOUND_INDICATOR_WIDGET_PROPERTY:
		g_value_set_object (value, sound_indicator_get_widget (self));
		break;
		case SOUND_INDICATOR_MIXER_PROPERTY:
		g_value_set_object (value, sound_indicator_get_mixer (self));
		break;
		default:
		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
		break;
	}
}

static void
_vala_sound_indicator_set_property (GObject * object,
                                    guint property_id,
                                    const GValue * value,
                                    GParamSpec * pspec)
{
	SoundIndicator * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (object, TYPE_SOUND_INDICATOR, SoundIndicator);
	switch (property_id) {
		case SOUND_INDICATOR_WIDGET_PROPERTY:
		sound_indicator_set_widget (self, g_value_get_object (value));
		break;
		case SOUND_INDICATOR_MIXER_PROPERTY:
		sound_indicator_set_mixer (self, g_value_get_object (value));
		break;
		default:
		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
		break;
	}
}

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);
}

