

#include <glib.h>
#include <glib-object.h>

/**********************************************************************
 * TestFlags
 **********************************************************************/

typedef enum { /*< flags >*/
	TEST_FLAG_NONE = 0,
	TEST_FLAG_1    = (1 << 0),
	TEST_FLAG_2    = (1 << 1),
	TEST_FLAG_3    = (1 << 2),
	TEST_FLAG_4    = (1 << 3),
} TestFlags;

/* generated with glib-mkenums and c&p here... */

GType test_flags_get_type (void) G_GNUC_CONST;
#define TEST_TYPE_FLAGS (test_flags_get_type ())

GType
test_flags_get_type (void)
{ 
  static volatile gsize g_define_type_id__volatile = 0;

  if (g_once_init_enter (&g_define_type_id__volatile))
    { 
      static const GFlagsValue values[] = {
        { TEST_FLAG_NONE, "TEST_FLAG_NONE", "none" },
        { TEST_FLAG_1, "TEST_FLAG_1", "1" },
        { TEST_FLAG_2, "TEST_FLAG_2", "2" },
        { TEST_FLAG_3, "TEST_FLAG_3", "3" },
        { TEST_FLAG_4, "TEST_FLAG_4", "4" },
        { 0, NULL, NULL }
      };
      GType g_define_type_id =
        g_flags_register_static (g_intern_static_string ("TestFlags"), values);
      g_once_init_leave (&g_define_type_id__volatile, g_define_type_id);
    }

  return g_define_type_id__volatile;
}

/**********************************************************************
 * Maman class
 **********************************************************************/

#define MAMAN_TYPE_BAR                  (maman_bar_get_type ())
#define MAMAN_BAR(obj)                  (G_TYPE_CHECK_INSTANCE_CAST ((obj), MAMAN_TYPE_BAR, MamanBar))
#define MAMAN_IS_BAR(obj)               (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MAMAN_TYPE_BAR))
#define MAMAN_BAR_CLASS(klass)          (G_TYPE_CHECK_CLASS_CAST ((klass), MAMAN_TYPE_BAR, MamanBarClass))
#define MAMAN_IS_BAR_CLASS(klass)       (G_TYPE_CHECK_CLASS_TYPE ((klass), MAMAN_TYPE_BAR))
#define MAMAN_BAR_GET_CLASS(obj)        (G_TYPE_INSTANCE_GET_CLASS ((obj), MAMAN_TYPE_BAR, MamanBarClass))

#define MAMAN_SIGNAL_1 "signal-1"

enum {
	SIGNAL_1,

	LAST_SIGNAL
};

static guint signals[LAST_SIGNAL] = { 0 };

typedef struct _MamanBar        MamanBar;
typedef struct _MamanBarClass   MamanBarClass;

struct _MamanBar {
	GObject parent_instance;
};

struct _MamanBarClass {
	GObjectClass parent_class;
};

/* will create maman_bar_get_type and set maman_bar_parent_class */
G_DEFINE_TYPE (MamanBar, maman_bar, G_TYPE_OBJECT);

static void
maman_bar_class_init (MamanBarClass *klass)
{
	GObjectClass *gobject_class = G_OBJECT_CLASS (klass);

	signals[SIGNAL_1] =
	    g_signal_new (MAMAN_SIGNAL_1,
	                  G_OBJECT_CLASS_TYPE (gobject_class),
	                  G_SIGNAL_RUN_FIRST,
	                  0,
	                  NULL, NULL, NULL,
	                  G_TYPE_NONE,
	                  3,
	                  G_TYPE_OBJECT,
	                  TEST_TYPE_FLAGS,
	                  G_TYPE_OBJECT);
}

static void
maman_bar_init (MamanBar *self)
{
}

/**********************************************************************/

static void
_signal_cb1 (MamanBar *obj, GObject *dummy1, TestFlags test_flags, GObject *dummy2, TestFlags *expected)
{
	g_assert_cmpint (test_flags, ==, *expected);
	g_message ("(%s) signal accepted", G_STRFUNC);
}

static void
_signal_cb2 (MamanBar *obj, GObject *dummy1, TestFlags test_flags, GObject *dummy2, TestFlags *expected)
{
	g_assert_cmpint (test_flags, ==, *expected);
	g_message ("(%s) signal accepted", G_STRFUNC);
}

static void
_signal_emit (MamanBar *obj, TestFlags flags)
{
	g_signal_emit (obj, signals[SIGNAL_1], 0, obj, flags, obj);
}

int main (void)
{
	MamanBar *obj;
	TestFlags expected;

	obj = g_object_new (MAMAN_TYPE_BAR, NULL);

	g_signal_connect (G_OBJECT (obj),
	                  MAMAN_SIGNAL_1,
	                  G_CALLBACK (_signal_cb1),
	                  &expected);
	expected = TEST_FLAG_1;
	_signal_emit (obj, expected);

	/* connect a second signal... */

	g_signal_connect (G_OBJECT (obj),
	                  MAMAN_SIGNAL_1,
	                  G_CALLBACK (_signal_cb2),
	                  &expected);
	expected = TEST_FLAG_2;
	_signal_emit (obj, expected);

	g_signal_handlers_disconnect_by_func (obj, _signal_cb1, &expected);
	g_signal_handlers_disconnect_by_func (obj, _signal_cb2, &expected);

	g_object_unref (obj);
	return 0;
}


