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

/**/
/*  Copyright (C) 2014 Tom Beckmann*/
/**/
/*  This program is free software: you can redistribute it and/or modify*/
/*  it under the terms of the GNU General Public License as published by*/
/*  the Free Software Foundation, either version 3 of the License, or*/
/*  (at your option) any later version.*/
/**/
/*  This program is distributed in the hope that it will be useful,*/
/*  but WITHOUT ANY WARRANTY; without even the implied warranty of*/
/*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the*/
/*  GNU General Public License for more details.*/
/**/
/*  You should have received a copy of the GNU General Public License*/
/*  along with this program.  If not, see <http://www.gnu.org/licenses/>.*/
/**/

#include <glib-object.h>
#include <gee.h>
#include <meta/window.h>
#include <meta/boxes.h>
#include <glib.h>
#include <meta/display.h>
#include <meta/compositor-mutter.h>
#include <meta/meta-window-actor.h>
#include <stdlib.h>
#include <string.h>

#if !defined(VALA_EXTERN)
#if defined(_MSC_VER)
#define VALA_EXTERN __declspec(dllexport) extern
#elif __GNUC__ >= 4
#define VALA_EXTERN __attribute__((visibility("default"))) extern
#else
#define VALA_EXTERN extern
#endif
#endif

#define GALA_TYPE_WINDOW_LISTENER (gala_window_listener_get_type ())
#define GALA_WINDOW_LISTENER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GALA_TYPE_WINDOW_LISTENER, GalaWindowListener))
#define GALA_WINDOW_LISTENER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GALA_TYPE_WINDOW_LISTENER, GalaWindowListenerClass))
#define GALA_IS_WINDOW_LISTENER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GALA_TYPE_WINDOW_LISTENER))
#define GALA_IS_WINDOW_LISTENER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GALA_TYPE_WINDOW_LISTENER))
#define GALA_WINDOW_LISTENER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GALA_TYPE_WINDOW_LISTENER, GalaWindowListenerClass))

typedef struct _GalaWindowListener GalaWindowListener;
typedef struct _GalaWindowListenerClass GalaWindowListenerClass;
typedef struct _GalaWindowListenerPrivate GalaWindowListenerPrivate;

#define GALA_WINDOW_LISTENER_TYPE_WINDOW_GEOMETRY (gala_window_listener_window_geometry_get_type ())
typedef struct _GalaWindowListenerWindowGeometry GalaWindowListenerWindowGeometry;
enum  {
	GALA_WINDOW_LISTENER_0_PROPERTY,
	GALA_WINDOW_LISTENER_NUM_PROPERTIES
};
static GParamSpec* gala_window_listener_properties[GALA_WINDOW_LISTENER_NUM_PROPERTIES];
#define _g_object_unref0(var) ((var == NULL) ? NULL : (var = (g_object_unref (var), NULL)))
enum  {
	GALA_WINDOW_LISTENER_WINDOW_NO_LONGER_ON_ALL_WORKSPACES_SIGNAL,
	GALA_WINDOW_LISTENER_NUM_SIGNALS
};
static guint gala_window_listener_signals[GALA_WINDOW_LISTENER_NUM_SIGNALS] = {0};
#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 _GalaWindowListener {
	GObject parent_instance;
	GalaWindowListenerPrivate * priv;
};

struct _GalaWindowListenerClass {
	GObjectClass parent_class;
};

struct _GalaWindowListenerWindowGeometry {
	MetaRectangle inner;
	MetaRectangle outer;
};

struct _GalaWindowListenerPrivate {
	GeeHashMap* unmaximized_state_geometry;
};

static gint GalaWindowListener_private_offset;
static gpointer gala_window_listener_parent_class = NULL;
static GalaWindowListener* gala_window_listener_instance;
static GalaWindowListener* gala_window_listener_instance = NULL;

VALA_EXTERN GType gala_window_listener_get_type (void) G_GNUC_CONST ;
G_DEFINE_AUTOPTR_CLEANUP_FUNC (GalaWindowListener, g_object_unref)
VALA_EXTERN GType gala_window_listener_window_geometry_get_type (void) G_GNUC_CONST ;
VALA_EXTERN GalaWindowListenerWindowGeometry* gala_window_listener_window_geometry_dup (const GalaWindowListenerWindowGeometry* self);
VALA_EXTERN void gala_window_listener_window_geometry_free (GalaWindowListenerWindowGeometry* self);
VALA_EXTERN void gala_window_listener_init (MetaDisplay* display);
static GalaWindowListener* gala_window_listener_new (void);
static GalaWindowListener* gala_window_listener_construct (GType object_type);
static void gala_window_listener_monitor_window (GalaWindowListener* self,
                                          MetaWindow* window);
static void __lambda46_ (MetaWindow* window);
static void ___lambda46__meta_display_window_created (MetaDisplay* _sender,
                                               MetaWindow* object,
                                               gpointer self);
VALA_EXTERN GalaWindowListener* gala_window_listener_get_default (void);
static void gala_window_listener_window_notify (GalaWindowListener* self,
                                         GObject* object,
                                         GParamSpec* pspec);
static void _gala_window_listener_window_notify_g_object_notify (GObject* _sender,
                                                          GParamSpec* pspec,
                                                          gpointer self);
static void gala_window_listener_window_removed (GalaWindowListener* self,
                                          MetaWindow* window);
static void _gala_window_listener_window_removed_meta_window_unmanaged (MetaWindow* _sender,
                                                                 gpointer self);
static void gala_window_listener_window_maximized_changed (GalaWindowListener* self,
                                                    MetaWindow* window);
static void gala_window_listener_window_on_all_workspaces_changed (GalaWindowListener* self,
                                                            MetaWindow* window);
VALA_EXTERN GalaWindowListenerWindowGeometry* gala_window_listener_get_unmaximized_state_geometry (GalaWindowListener* self,
                                                                                       MetaWindow* window);
static void gala_window_listener_finalize (GObject * obj);
static GType gala_window_listener_get_type_once (void);
static inline gpointer _vala_memdup2 (gconstpointer mem,
                        gsize byte_size);

static inline gpointer
gala_window_listener_get_instance_private (GalaWindowListener* self)
{
	return G_STRUCT_MEMBER_P (self, GalaWindowListener_private_offset);
}

static void
__lambda46_ (MetaWindow* window)
{
	MetaWindowType _tmp0_;
	MetaWindowType _tmp1_;
	g_return_if_fail (window != NULL);
	_tmp0_ = meta_window_get_window_type (window);
	_tmp1_ = _tmp0_;
	if (_tmp1_ == META_WINDOW_NORMAL) {
		GalaWindowListener* _tmp2_;
		_tmp2_ = gala_window_listener_instance;
		gala_window_listener_monitor_window (_tmp2_, window);
	}
}

static void
___lambda46__meta_display_window_created (MetaDisplay* _sender,
                                          MetaWindow* object,
                                          gpointer self)
{
	__lambda46_ (object);
}

void
gala_window_listener_init (MetaDisplay* display)
{
	GalaWindowListener* _tmp0_;
	GalaWindowListener* _tmp1_;
	GList* _tmp2_;
	g_return_if_fail (display != NULL);
	_tmp0_ = gala_window_listener_instance;
	if (_tmp0_ != NULL) {
		return;
	}
	_tmp1_ = gala_window_listener_new ();
	_g_object_unref0 (gala_window_listener_instance);
	gala_window_listener_instance = _tmp1_;
	_tmp2_ = meta_get_window_actors (display);
	{
		GList* actor_collection = NULL;
		GList* actor_it = NULL;
		actor_collection = _tmp2_;
		for (actor_it = actor_collection; actor_it != NULL; actor_it = actor_it->next) {
			MetaWindowActor* actor = NULL;
			actor = (MetaWindowActor*) actor_it->data;
			{
				MetaWindowActor* _tmp3_;
				MetaWindow* window = NULL;
				MetaWindowActor* _tmp4_;
				MetaWindow* _tmp5_;
				MetaWindow* _tmp6_;
				MetaWindowType _tmp7_;
				MetaWindowType _tmp8_;
				_tmp3_ = actor;
				if (meta_window_actor_is_destroyed (_tmp3_)) {
					continue;
				}
				_tmp4_ = actor;
				_tmp5_ = meta_window_actor_get_meta_window (_tmp4_);
				window = _tmp5_;
				_tmp6_ = window;
				_tmp7_ = meta_window_get_window_type (_tmp6_);
				_tmp8_ = _tmp7_;
				if (_tmp8_ == META_WINDOW_NORMAL) {
					GalaWindowListener* _tmp9_;
					MetaWindow* _tmp10_;
					_tmp9_ = gala_window_listener_instance;
					_tmp10_ = window;
					gala_window_listener_monitor_window (_tmp9_, _tmp10_);
				}
			}
		}
	}
	g_signal_connect (display, "window-created", (GCallback) ___lambda46__meta_display_window_created, NULL);
}

GalaWindowListener*
gala_window_listener_get_default (void)
{
	GalaWindowListener* _tmp0_;
	GalaWindowListener* _tmp1_;
	GalaWindowListener* result;
	_tmp0_ = gala_window_listener_instance;
	_vala_return_val_if_fail (_tmp0_ != NULL, "instance != null", NULL);
	_tmp1_ = gala_window_listener_instance;
	result = _tmp1_;
	return result;
}

static GalaWindowListener*
gala_window_listener_construct (GType object_type)
{
	GalaWindowListener * self = NULL;
	GeeHashMap* _tmp0_;
	self = (GalaWindowListener*) g_object_new (object_type, NULL);
	_tmp0_ = gee_hash_map_new (meta_window_get_type (), (GBoxedCopyFunc) g_object_ref, (GDestroyNotify) g_object_unref, GALA_WINDOW_LISTENER_TYPE_WINDOW_GEOMETRY, (GBoxedCopyFunc) gala_window_listener_window_geometry_dup, (GDestroyNotify) gala_window_listener_window_geometry_free, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
	_g_object_unref0 (self->priv->unmaximized_state_geometry);
	self->priv->unmaximized_state_geometry = _tmp0_;
	return self;
}

static GalaWindowListener*
gala_window_listener_new (void)
{
	return gala_window_listener_construct (GALA_TYPE_WINDOW_LISTENER);
}

static void
_gala_window_listener_window_notify_g_object_notify (GObject* _sender,
                                                     GParamSpec* pspec,
                                                     gpointer self)
{
	gala_window_listener_window_notify ((GalaWindowListener*) self, _sender, pspec);
}

static void
_gala_window_listener_window_removed_meta_window_unmanaged (MetaWindow* _sender,
                                                            gpointer self)
{
	gala_window_listener_window_removed ((GalaWindowListener*) self, _sender);
}

static void
gala_window_listener_monitor_window (GalaWindowListener* self,
                                     MetaWindow* window)
{
	g_return_if_fail (self != NULL);
	g_return_if_fail (window != NULL);
	g_signal_connect_object ((GObject*) window, "notify", (GCallback) _gala_window_listener_window_notify_g_object_notify, self, 0);
	g_signal_connect_object (window, "unmanaged", (GCallback) _gala_window_listener_window_removed_meta_window_unmanaged, self, 0);
	gala_window_listener_window_maximized_changed (self, window);
}

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

static void
gala_window_listener_window_notify (GalaWindowListener* self,
                                    GObject* object,
                                    GParamSpec* pspec)
{
	MetaWindow* window = NULL;
	MetaWindow* _tmp0_;
	const gchar* _tmp1_;
	const gchar* _tmp2_;
	GQuark _tmp4_ = 0U;
	static GQuark _tmp3_label0 = 0;
	static GQuark _tmp3_label1 = 0;
	static GQuark _tmp3_label2 = 0;
	g_return_if_fail (self != NULL);
	g_return_if_fail (object != NULL);
	g_return_if_fail (pspec != NULL);
	_tmp0_ = _g_object_ref0 (G_TYPE_CHECK_INSTANCE_CAST (object, meta_window_get_type (), MetaWindow));
	window = _tmp0_;
	_tmp1_ = pspec->name;
	_tmp2_ = _tmp1_;
	_tmp4_ = (NULL == _tmp2_) ? 0 : g_quark_from_string (_tmp2_);
	if ((_tmp4_ == ((0 != _tmp3_label0) ? _tmp3_label0 : (_tmp3_label0 = g_quark_from_static_string ("maximized-horizontally")))) || (_tmp4_ == ((0 != _tmp3_label1) ? _tmp3_label1 : (_tmp3_label1 = g_quark_from_static_string ("maximized-vertically"))))) {
		switch (0) {
			default:
			{
				MetaWindow* _tmp5_;
				_tmp5_ = window;
				gala_window_listener_window_maximized_changed (self, _tmp5_);
				break;
			}
		}
	} else if (_tmp4_ == ((0 != _tmp3_label2) ? _tmp3_label2 : (_tmp3_label2 = g_quark_from_static_string ("on-all-workspaces")))) {
		switch (0) {
			default:
			{
				MetaWindow* _tmp6_;
				_tmp6_ = window;
				gala_window_listener_window_on_all_workspaces_changed (self, _tmp6_);
				break;
			}
		}
	}
	_g_object_unref0 (window);
}

static void
gala_window_listener_window_on_all_workspaces_changed (GalaWindowListener* self,
                                                       MetaWindow* window)
{
	gboolean _tmp0_;
	gboolean _tmp1_;
	g_return_if_fail (self != NULL);
	g_return_if_fail (window != NULL);
	g_object_get (window, "on-all-workspaces", &_tmp0_, NULL);
	_tmp1_ = _tmp0_;
	if (_tmp1_) {
		return;
	}
	g_signal_emit (self, gala_window_listener_signals[GALA_WINDOW_LISTENER_WINDOW_NO_LONGER_ON_ALL_WORKSPACES_SIGNAL], 0, window);
}

static void
gala_window_listener_window_maximized_changed (GalaWindowListener* self,
                                               MetaWindow* window)
{
	GalaWindowListenerWindowGeometry window_geometry = {0};
	GalaWindowListenerWindowGeometry _tmp0_ = {0};
	MetaRectangle _tmp1_ = {0};
	MetaRectangle _tmp2_ = {0};
	GeeHashMap* _tmp3_;
	GalaWindowListenerWindowGeometry _tmp4_;
	g_return_if_fail (self != NULL);
	g_return_if_fail (window != NULL);
	window_geometry = _tmp0_;
	meta_window_get_frame_rect (window, &_tmp1_);
	window_geometry.inner = _tmp1_;
	meta_window_get_buffer_rect (window, &_tmp2_);
	window_geometry.outer = _tmp2_;
	_tmp3_ = self->priv->unmaximized_state_geometry;
	_tmp4_ = window_geometry;
	gee_abstract_map_set ((GeeAbstractMap*) _tmp3_, window, &_tmp4_);
}

GalaWindowListenerWindowGeometry*
gala_window_listener_get_unmaximized_state_geometry (GalaWindowListener* self,
                                                     MetaWindow* window)
{
	GeeHashMap* _tmp0_;
	gpointer _tmp1_;
	GalaWindowListenerWindowGeometry* result;
	g_return_val_if_fail (self != NULL, NULL);
	g_return_val_if_fail (window != NULL, NULL);
	_tmp0_ = self->priv->unmaximized_state_geometry;
	_tmp1_ = gee_abstract_map_get ((GeeAbstractMap*) _tmp0_, window);
	result = (GalaWindowListenerWindowGeometry*) _tmp1_;
	return result;
}

static void
gala_window_listener_window_removed (GalaWindowListener* self,
                                     MetaWindow* window)
{
	guint _tmp0_;
	guint _tmp1_;
	g_return_if_fail (self != NULL);
	g_return_if_fail (window != NULL);
	g_signal_parse_name ("notify", G_TYPE_OBJECT, &_tmp0_, NULL, FALSE);
	g_signal_handlers_disconnect_matched ((GObject*) window, G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA, _tmp0_, 0, NULL, (GCallback) _gala_window_listener_window_notify_g_object_notify, self);
	g_signal_parse_name ("unmanaged", meta_window_get_type (), &_tmp1_, NULL, FALSE);
	g_signal_handlers_disconnect_matched (window, G_SIGNAL_MATCH_ID | G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA, _tmp1_, 0, NULL, (GCallback) _gala_window_listener_window_removed_meta_window_unmanaged, self);
}

GalaWindowListenerWindowGeometry*
gala_window_listener_window_geometry_dup (const GalaWindowListenerWindowGeometry* self)
{
	GalaWindowListenerWindowGeometry* dup;
	dup = g_new0 (GalaWindowListenerWindowGeometry, 1);
	memcpy (dup, self, sizeof (GalaWindowListenerWindowGeometry));
	return dup;
}

void
gala_window_listener_window_geometry_free (GalaWindowListenerWindowGeometry* self)
{
	g_free (self);
}

static GType
gala_window_listener_window_geometry_get_type_once (void)
{
	GType gala_window_listener_window_geometry_type_id;
	gala_window_listener_window_geometry_type_id = g_boxed_type_register_static ("GalaWindowListenerWindowGeometry", (GBoxedCopyFunc) gala_window_listener_window_geometry_dup, (GBoxedFreeFunc) gala_window_listener_window_geometry_free);
	return gala_window_listener_window_geometry_type_id;
}

GType
gala_window_listener_window_geometry_get_type (void)
{
	static volatile gsize gala_window_listener_window_geometry_type_id__once = 0;
	if (g_once_init_enter (&gala_window_listener_window_geometry_type_id__once)) {
		GType gala_window_listener_window_geometry_type_id;
		gala_window_listener_window_geometry_type_id = gala_window_listener_window_geometry_get_type_once ();
		g_once_init_leave (&gala_window_listener_window_geometry_type_id__once, gala_window_listener_window_geometry_type_id);
	}
	return gala_window_listener_window_geometry_type_id__once;
}

static void
gala_window_listener_class_init (GalaWindowListenerClass * klass,
                                 gpointer klass_data)
{
	gala_window_listener_parent_class = g_type_class_peek_parent (klass);
	g_type_class_adjust_private_offset (klass, &GalaWindowListener_private_offset);
	G_OBJECT_CLASS (klass)->finalize = gala_window_listener_finalize;
	gala_window_listener_signals[GALA_WINDOW_LISTENER_WINDOW_NO_LONGER_ON_ALL_WORKSPACES_SIGNAL] = g_signal_new ("window-no-longer-on-all-workspaces", GALA_TYPE_WINDOW_LISTENER, G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_marshal_VOID__OBJECT, G_TYPE_NONE, 1, meta_window_get_type ());
}

static void
gala_window_listener_instance_init (GalaWindowListener * self,
                                    gpointer klass)
{
	self->priv = gala_window_listener_get_instance_private (self);
}

static void
gala_window_listener_finalize (GObject * obj)
{
	GalaWindowListener * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (obj, GALA_TYPE_WINDOW_LISTENER, GalaWindowListener);
	_g_object_unref0 (self->priv->unmaximized_state_geometry);
	G_OBJECT_CLASS (gala_window_listener_parent_class)->finalize (obj);
}

static GType
gala_window_listener_get_type_once (void)
{
	static const GTypeInfo g_define_type_info = { sizeof (GalaWindowListenerClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) gala_window_listener_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (GalaWindowListener), 0, (GInstanceInitFunc) gala_window_listener_instance_init, NULL };
	GType gala_window_listener_type_id;
	gala_window_listener_type_id = g_type_register_static (G_TYPE_OBJECT, "GalaWindowListener", &g_define_type_info, 0);
	GalaWindowListener_private_offset = g_type_add_instance_private (gala_window_listener_type_id, sizeof (GalaWindowListenerPrivate));
	return gala_window_listener_type_id;
}

GType
gala_window_listener_get_type (void)
{
	static volatile gsize gala_window_listener_type_id__once = 0;
	if (g_once_init_enter (&gala_window_listener_type_id__once)) {
		GType gala_window_listener_type_id;
		gala_window_listener_type_id = gala_window_listener_get_type_once ();
		g_once_init_leave (&gala_window_listener_type_id__once, gala_window_listener_type_id);
	}
	return gala_window_listener_type_id__once;
}

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

