(root)/
glib-2.79.0/
gobject/
tests/
signals.c
       1  #include <glib-object.h>
       2  #include "marshalers.h"
       3  
       4  #define g_assert_cmpflags(type,n1, cmp, n2) G_STMT_START { \
       5                                                 type __n1 = (n1), __n2 = (n2); \
       6                                                 if (__n1 cmp __n2) ; else \
       7                                                   g_assertion_message_cmpint (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, \
       8                                                                               #n1 " " #cmp " " #n2, __n1, #cmp, __n2, 'i'); \
       9                                              } G_STMT_END
      10  #define g_assert_cmpenum(type,n1, cmp, n2) G_STMT_START { \
      11                                                 type __n1 = (n1), __n2 = (n2); \
      12                                                 if (__n1 cmp __n2) ; else \
      13                                                   g_assertion_message_cmpint (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, \
      14                                                                               #n1 " " #cmp " " #n2, __n1, #cmp, __n2, 'i'); \
      15                                              } G_STMT_END
      16  
      17  typedef enum {
      18    TEST_ENUM_NEGATIVE = -30,
      19    TEST_ENUM_NONE = 0,
      20    TEST_ENUM_FOO = 1,
      21    TEST_ENUM_BAR = 2
      22  } TestEnum;
      23  
      24  typedef enum {
      25    TEST_UNSIGNED_ENUM_FOO = 1,
      26    TEST_UNSIGNED_ENUM_BAR = 42
      27    /* Don't test 0x80000000 for now- nothing appears to do this in
      28     * practice, and it triggers GValue/GEnum bugs on ppc64.
      29     */
      30  } TestUnsignedEnum;
      31  
      32  static void
      33  custom_marshal_VOID__INVOCATIONHINT (GClosure     *closure,
      34                                       GValue       *return_value G_GNUC_UNUSED,
      35                                       guint         n_param_values,
      36                                       const GValue *param_values,
      37                                       gpointer      invocation_hint,
      38                                       gpointer      marshal_data)
      39  {
      40    typedef void (*GMarshalFunc_VOID__INVOCATIONHINT) (gpointer     data1,
      41                                                       gpointer     invocation_hint,
      42                                                       gpointer     data2);
      43    GMarshalFunc_VOID__INVOCATIONHINT callback;
      44    GCClosure *cc = (GCClosure*) closure;
      45    gpointer data1, data2;
      46  
      47    g_return_if_fail (n_param_values == 2);
      48  
      49    if (G_CCLOSURE_SWAP_DATA (closure))
      50      {
      51        data1 = closure->data;
      52        data2 = g_value_peek_pointer (param_values + 0);
      53      }
      54    else
      55      {
      56        data1 = g_value_peek_pointer (param_values + 0);
      57        data2 = closure->data;
      58      }
      59    callback = (GMarshalFunc_VOID__INVOCATIONHINT) (marshal_data ? marshal_data : cc->callback);
      60  
      61    callback (data1,
      62              invocation_hint,
      63              data2);
      64  }
      65  
      66  static GType
      67  test_enum_get_type (void)
      68  {
      69    static GType static_g_define_type_id = 0;
      70  
      71    if (g_once_init_enter_pointer (&static_g_define_type_id))
      72      {
      73        static const GEnumValue values[] = {
      74          { TEST_ENUM_NEGATIVE, "TEST_ENUM_NEGATIVE", "negative" },
      75          { TEST_ENUM_NONE, "TEST_ENUM_NONE", "none" },
      76          { TEST_ENUM_FOO, "TEST_ENUM_FOO", "foo" },
      77          { TEST_ENUM_BAR, "TEST_ENUM_BAR", "bar" },
      78          { 0, NULL, NULL }
      79        };
      80        GType g_define_type_id =
      81          g_enum_register_static (g_intern_static_string ("TestEnum"), values);
      82        g_once_init_leave_pointer (&static_g_define_type_id, g_define_type_id);
      83      }
      84  
      85    return static_g_define_type_id;
      86  }
      87  
      88  static GType
      89  test_unsigned_enum_get_type (void)
      90  {
      91    static GType static_g_define_type_id = 0;
      92  
      93    if (g_once_init_enter_pointer (&static_g_define_type_id))
      94      {
      95        static const GEnumValue values[] = {
      96          { TEST_UNSIGNED_ENUM_FOO, "TEST_UNSIGNED_ENUM_FOO", "foo" },
      97          { TEST_UNSIGNED_ENUM_BAR, "TEST_UNSIGNED_ENUM_BAR", "bar" },
      98          { 0, NULL, NULL }
      99        };
     100        GType g_define_type_id =
     101          g_enum_register_static (g_intern_static_string ("TestUnsignedEnum"), values);
     102        g_once_init_leave_pointer (&static_g_define_type_id, g_define_type_id);
     103      }
     104  
     105    return static_g_define_type_id;
     106  }
     107  
     108  typedef enum {
     109    MY_ENUM_VALUE = 1,
     110  } MyEnum;
     111  
     112  static const GEnumValue my_enum_values[] =
     113  {
     114    { MY_ENUM_VALUE, "the first value", "one" },
     115    { 0, NULL, NULL }
     116  };
     117  
     118  typedef enum {
     119    MY_FLAGS_FIRST_BIT = (1 << 0),
     120    MY_FLAGS_THIRD_BIT = (1 << 2),
     121    MY_FLAGS_LAST_BIT = (1 << 31)
     122  } MyFlags;
     123  
     124  static const GFlagsValue my_flag_values[] =
     125  {
     126    { MY_FLAGS_FIRST_BIT, "the first bit", "first-bit" },
     127    { MY_FLAGS_THIRD_BIT, "the third bit", "third-bit" },
     128    { MY_FLAGS_LAST_BIT, "the last bit", "last-bit" },
     129    { 0, NULL, NULL }
     130  };
     131  
     132  static GType enum_type;
     133  static GType flags_type;
     134  
     135  static guint simple_id;
     136  static guint simple2_id;
     137  
     138  typedef struct {
     139    GTypeInterface g_iface;
     140  } FooInterface;
     141  
     142  GType foo_get_type (void);
     143  
     144  G_DEFINE_INTERFACE (Foo, foo, G_TYPE_OBJECT)
     145  
     146  static void
     147  foo_default_init (FooInterface *iface)
     148  {
     149  }
     150  
     151  typedef struct {
     152    GObject parent;
     153  } Baa;
     154  
     155  typedef struct {
     156    GObjectClass parent_class;
     157  } BaaClass;
     158  
     159  static void
     160  baa_init_foo (FooInterface *iface)
     161  {
     162  }
     163  
     164  GType baa_get_type (void);
     165  
     166  G_DEFINE_TYPE_WITH_CODE (Baa, baa, G_TYPE_OBJECT,
     167                           G_IMPLEMENT_INTERFACE (foo_get_type (), baa_init_foo))
     168  
     169  static void
     170  baa_init (Baa *baa)
     171  {
     172  }
     173  
     174  static void
     175  baa_class_init (BaaClass *class)
     176  {
     177  }
     178  
     179  typedef struct _Test Test;
     180  typedef struct _TestClass TestClass;
     181  
     182  struct _Test
     183  {
     184    GObject parent_instance;
     185  };
     186  
     187  static void all_types_handler (Test *test, int i, gboolean b, char c, guchar uc, guint ui, glong l, gulong ul, MyEnum e, MyFlags f, float fl, double db, char *str, GParamSpec *param, GBytes *bytes, gpointer ptr, Test *obj, GVariant *var, gint64 i64, guint64 ui64);
     188  static gboolean accumulator_sum (GSignalInvocationHint *ihint, GValue *return_accu, const GValue *handler_return, gpointer data);
     189  static gboolean accumulator_concat_string (GSignalInvocationHint *ihint, GValue *return_accu, const GValue *handler_return, gpointer data);
     190  static gchar * accumulator_class (Test *test);
     191  
     192  struct _TestClass
     193  {
     194    GObjectClass parent_class;
     195  
     196    void (* variant_changed) (Test *, GVariant *);
     197    void (* all_types) (Test *test, int i, gboolean b, char c, guchar uc, guint ui, glong l, gulong ul, MyEnum e, MyFlags f, float fl, double db, char *str, GParamSpec *param, GBytes *bytes, gpointer ptr, Test *obj, GVariant *var, gint64 i64, guint64 ui64);
     198    void (* all_types_null) (Test *test, int i, gboolean b, char c, guchar uc, guint ui, glong l, gulong ul, MyEnum e, MyFlags f, float fl, double db, char *str, GParamSpec *param, GBytes *bytes, gpointer ptr, Test *obj, GVariant *var, gint64 i64, guint64 ui64);
     199    gchar * (*accumulator_class) (Test *test);
     200  };
     201  
     202  static GType test_get_type (void);
     203  G_DEFINE_TYPE (Test, test, G_TYPE_OBJECT)
     204  
     205  static void
     206  test_init (Test *test)
     207  {
     208  }
     209  
     210  static void
     211  test_class_init (TestClass *klass)
     212  {
     213    guint s;
     214  
     215    enum_type = g_enum_register_static ("MyEnum", my_enum_values);
     216    flags_type = g_flags_register_static ("MyFlag", my_flag_values);
     217  
     218    klass->all_types = all_types_handler;
     219    klass->accumulator_class = accumulator_class;
     220  
     221    simple_id = g_signal_new ("simple",
     222                  G_TYPE_FROM_CLASS (klass),
     223                  G_SIGNAL_RUN_LAST,
     224                  0,
     225                  NULL, NULL,
     226                  NULL,
     227                  G_TYPE_NONE,
     228                  0);
     229    g_signal_new ("simple-detailed",
     230                  G_TYPE_FROM_CLASS (klass),
     231                  G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED,
     232                  0,
     233                  NULL, NULL,
     234                  NULL,
     235                  G_TYPE_NONE,
     236                  0);
     237    /* Deliberately install this one in non-canonical form to check that’s handled correctly: */
     238    simple2_id = g_signal_new ("simple_2",
     239                  G_TYPE_FROM_CLASS (klass),
     240                  G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE,
     241                  0,
     242                  NULL, NULL,
     243                  NULL,
     244                  G_TYPE_NONE,
     245                  0);
     246    g_signal_new ("simple-accumulator",
     247                  G_TYPE_FROM_CLASS (klass),
     248                  G_SIGNAL_RUN_LAST,
     249                  0,
     250                  accumulator_sum, NULL,
     251                  NULL,
     252                  G_TYPE_INT,
     253                  0);
     254    g_signal_new ("accumulator-class-first",
     255                  G_TYPE_FROM_CLASS (klass),
     256                  G_SIGNAL_RUN_FIRST,
     257                  G_STRUCT_OFFSET (TestClass, accumulator_class),
     258                  accumulator_concat_string, NULL,
     259                  NULL,
     260                  G_TYPE_STRING,
     261                  0);
     262    g_signal_new ("accumulator-class-last",
     263                  G_TYPE_FROM_CLASS (klass),
     264                  G_SIGNAL_RUN_LAST,
     265                  G_STRUCT_OFFSET (TestClass, accumulator_class),
     266                  accumulator_concat_string, NULL,
     267                  NULL,
     268                  G_TYPE_STRING,
     269                  0);
     270    g_signal_new ("accumulator-class-cleanup",
     271                  G_TYPE_FROM_CLASS (klass),
     272                  G_SIGNAL_RUN_CLEANUP,
     273                  G_STRUCT_OFFSET (TestClass, accumulator_class),
     274                  accumulator_concat_string, NULL,
     275                  NULL,
     276                  G_TYPE_STRING,
     277                  0);
     278    g_signal_new ("accumulator-class-first-last",
     279                  G_TYPE_FROM_CLASS (klass),
     280                  G_SIGNAL_RUN_FIRST | G_SIGNAL_RUN_LAST,
     281                  G_STRUCT_OFFSET (TestClass, accumulator_class),
     282                  accumulator_concat_string, NULL,
     283                  NULL,
     284                  G_TYPE_STRING,
     285                  0);
     286    g_signal_new ("accumulator-class-first-last-cleanup",
     287                  G_TYPE_FROM_CLASS (klass),
     288                  G_SIGNAL_RUN_FIRST | G_SIGNAL_RUN_LAST | G_SIGNAL_RUN_CLEANUP,
     289                  G_STRUCT_OFFSET (TestClass, accumulator_class),
     290                  accumulator_concat_string, NULL,
     291                  NULL,
     292                  G_TYPE_STRING,
     293                  0);
     294    g_signal_new ("accumulator-class-last-cleanup",
     295                  G_TYPE_FROM_CLASS (klass),
     296                  G_SIGNAL_RUN_LAST | G_SIGNAL_RUN_CLEANUP,
     297                  G_STRUCT_OFFSET (TestClass, accumulator_class),
     298                  accumulator_concat_string, NULL,
     299                  NULL,
     300                  G_TYPE_STRING,
     301                  0);
     302    g_signal_new ("generic-marshaller-1",
     303                  G_TYPE_FROM_CLASS (klass),
     304                  G_SIGNAL_RUN_LAST,
     305                  0,
     306                  NULL, NULL,
     307                  NULL,
     308                  G_TYPE_NONE,
     309                  7,
     310                  G_TYPE_CHAR, G_TYPE_UCHAR, G_TYPE_INT, G_TYPE_LONG, G_TYPE_POINTER, G_TYPE_DOUBLE, G_TYPE_FLOAT);
     311    g_signal_new ("generic-marshaller-2",
     312                  G_TYPE_FROM_CLASS (klass),
     313                  G_SIGNAL_RUN_LAST,
     314                  0,
     315                  NULL, NULL,
     316                  NULL,
     317                  G_TYPE_NONE,
     318                  5,
     319                  G_TYPE_INT, test_enum_get_type(), G_TYPE_INT, test_unsigned_enum_get_type (), G_TYPE_INT);
     320    g_signal_new ("generic-marshaller-enum-return-signed",
     321                  G_TYPE_FROM_CLASS (klass),
     322                  G_SIGNAL_RUN_LAST,
     323                  0,
     324                  NULL, NULL,
     325                  NULL,
     326                  test_enum_get_type(),
     327                  0);
     328    g_signal_new ("generic-marshaller-enum-return-unsigned",
     329                  G_TYPE_FROM_CLASS (klass),
     330                  G_SIGNAL_RUN_LAST,
     331                  0,
     332                  NULL, NULL,
     333                  NULL,
     334                  test_unsigned_enum_get_type(),
     335                  0);
     336    g_signal_new ("generic-marshaller-int-return",
     337                  G_TYPE_FROM_CLASS (klass),
     338                  G_SIGNAL_RUN_LAST,
     339                  0,
     340                  NULL, NULL,
     341                  NULL,
     342                  G_TYPE_INT,
     343                  0);
     344    s = g_signal_new ("va-marshaller-int-return",
     345                  G_TYPE_FROM_CLASS (klass),
     346                  G_SIGNAL_RUN_LAST,
     347                  0,
     348                  NULL, NULL,
     349                  test_INT__VOID,
     350                  G_TYPE_INT,
     351                  0);
     352    g_signal_set_va_marshaller (s, G_TYPE_FROM_CLASS (klass),
     353  			      test_INT__VOIDv);
     354    g_signal_new ("generic-marshaller-uint-return",
     355                  G_TYPE_FROM_CLASS (klass),
     356                  G_SIGNAL_RUN_LAST,
     357                  0,
     358                  NULL, NULL,
     359                  NULL,
     360                  G_TYPE_UINT,
     361                  0);
     362    g_signal_new ("generic-marshaller-interface-return",
     363                  G_TYPE_FROM_CLASS (klass),
     364                  G_SIGNAL_RUN_LAST,
     365                  0,
     366                  NULL, NULL,
     367                  NULL,
     368                  foo_get_type (),
     369                  0);
     370    s = g_signal_new ("va-marshaller-uint-return",
     371                  G_TYPE_FROM_CLASS (klass),
     372                  G_SIGNAL_RUN_LAST,
     373                  0,
     374                  NULL, NULL,
     375                  test_INT__VOID,
     376                  G_TYPE_UINT,
     377                  0);
     378    g_signal_set_va_marshaller (s, G_TYPE_FROM_CLASS (klass),
     379  			      test_UINT__VOIDv);
     380    g_signal_new ("custom-marshaller",
     381                  G_TYPE_FROM_CLASS (klass),
     382                  G_SIGNAL_RUN_LAST,
     383                  0,
     384                  NULL, NULL,
     385                  custom_marshal_VOID__INVOCATIONHINT,
     386                  G_TYPE_NONE,
     387                  1,
     388                  G_TYPE_POINTER);
     389    g_signal_new ("variant-changed-no-slot",
     390                  G_TYPE_FROM_CLASS (klass),
     391                  G_SIGNAL_RUN_LAST | G_SIGNAL_MUST_COLLECT,
     392                  0,
     393                  NULL, NULL,
     394                  g_cclosure_marshal_VOID__VARIANT,
     395                  G_TYPE_NONE,
     396                  1,
     397                  G_TYPE_VARIANT);
     398    g_signal_new ("variant-changed",
     399                  G_TYPE_FROM_CLASS (klass),
     400                  G_SIGNAL_RUN_LAST | G_SIGNAL_MUST_COLLECT,
     401                  G_STRUCT_OFFSET (TestClass, variant_changed),
     402                  NULL, NULL,
     403                  g_cclosure_marshal_VOID__VARIANT,
     404                  G_TYPE_NONE,
     405                  1,
     406                  G_TYPE_VARIANT);
     407    g_signal_new ("all-types",
     408                  G_TYPE_FROM_CLASS (klass),
     409                  G_SIGNAL_RUN_LAST,
     410                  G_STRUCT_OFFSET (TestClass, all_types),
     411                  NULL, NULL,
     412                  test_VOID__INT_BOOLEAN_CHAR_UCHAR_UINT_LONG_ULONG_ENUM_FLAGS_FLOAT_DOUBLE_STRING_PARAM_BOXED_POINTER_OBJECT_VARIANT_INT64_UINT64,
     413                  G_TYPE_NONE,
     414                  19,
     415  		G_TYPE_INT,
     416  		G_TYPE_BOOLEAN,
     417  		G_TYPE_CHAR,
     418  		G_TYPE_UCHAR,
     419  		G_TYPE_UINT,
     420  		G_TYPE_LONG,
     421  		G_TYPE_ULONG,
     422  		enum_type,
     423  		flags_type,
     424  		G_TYPE_FLOAT,
     425  		G_TYPE_DOUBLE,
     426  		G_TYPE_STRING,
     427  		G_TYPE_PARAM_LONG,
     428  		G_TYPE_BYTES,
     429  		G_TYPE_POINTER,
     430  		test_get_type (),
     431                  G_TYPE_VARIANT,
     432  		G_TYPE_INT64,
     433  		G_TYPE_UINT64);
     434    s = g_signal_new ("all-types-va",
     435                  G_TYPE_FROM_CLASS (klass),
     436                  G_SIGNAL_RUN_LAST,
     437                  G_STRUCT_OFFSET (TestClass, all_types),
     438                  NULL, NULL,
     439                  test_VOID__INT_BOOLEAN_CHAR_UCHAR_UINT_LONG_ULONG_ENUM_FLAGS_FLOAT_DOUBLE_STRING_PARAM_BOXED_POINTER_OBJECT_VARIANT_INT64_UINT64,
     440                  G_TYPE_NONE,
     441                  19,
     442  		G_TYPE_INT,
     443  		G_TYPE_BOOLEAN,
     444  		G_TYPE_CHAR,
     445  		G_TYPE_UCHAR,
     446  		G_TYPE_UINT,
     447  		G_TYPE_LONG,
     448  		G_TYPE_ULONG,
     449  		enum_type,
     450  		flags_type,
     451  		G_TYPE_FLOAT,
     452  		G_TYPE_DOUBLE,
     453  		G_TYPE_STRING,
     454  		G_TYPE_PARAM_LONG,
     455  		G_TYPE_BYTES,
     456  		G_TYPE_POINTER,
     457  		test_get_type (),
     458                  G_TYPE_VARIANT,
     459  		G_TYPE_INT64,
     460  		G_TYPE_UINT64);
     461    g_signal_set_va_marshaller (s, G_TYPE_FROM_CLASS (klass),
     462  			      test_VOID__INT_BOOLEAN_CHAR_UCHAR_UINT_LONG_ULONG_ENUM_FLAGS_FLOAT_DOUBLE_STRING_PARAM_BOXED_POINTER_OBJECT_VARIANT_INT64_UINT64v);
     463  
     464    g_signal_new ("all-types-generic",
     465                  G_TYPE_FROM_CLASS (klass),
     466                  G_SIGNAL_RUN_LAST,
     467                  G_STRUCT_OFFSET (TestClass, all_types),
     468                  NULL, NULL,
     469                  NULL,
     470                  G_TYPE_NONE,
     471                  19,
     472  		G_TYPE_INT,
     473  		G_TYPE_BOOLEAN,
     474  		G_TYPE_CHAR,
     475  		G_TYPE_UCHAR,
     476  		G_TYPE_UINT,
     477  		G_TYPE_LONG,
     478  		G_TYPE_ULONG,
     479  		enum_type,
     480  		flags_type,
     481  		G_TYPE_FLOAT,
     482  		G_TYPE_DOUBLE,
     483  		G_TYPE_STRING,
     484  		G_TYPE_PARAM_LONG,
     485  		G_TYPE_BYTES,
     486  		G_TYPE_POINTER,
     487  		test_get_type (),
     488                  G_TYPE_VARIANT,
     489  		G_TYPE_INT64,
     490  		G_TYPE_UINT64);
     491    g_signal_new ("all-types-null",
     492                  G_TYPE_FROM_CLASS (klass),
     493                  G_SIGNAL_RUN_LAST,
     494                  G_STRUCT_OFFSET (TestClass, all_types_null),
     495                  NULL, NULL,
     496                  test_VOID__INT_BOOLEAN_CHAR_UCHAR_UINT_LONG_ULONG_ENUM_FLAGS_FLOAT_DOUBLE_STRING_PARAM_BOXED_POINTER_OBJECT_VARIANT_INT64_UINT64,
     497                  G_TYPE_NONE,
     498                  19,
     499  		G_TYPE_INT,
     500  		G_TYPE_BOOLEAN,
     501  		G_TYPE_CHAR,
     502  		G_TYPE_UCHAR,
     503  		G_TYPE_UINT,
     504  		G_TYPE_LONG,
     505  		G_TYPE_ULONG,
     506  		enum_type,
     507  		flags_type,
     508  		G_TYPE_FLOAT,
     509  		G_TYPE_DOUBLE,
     510  		G_TYPE_STRING,
     511  		G_TYPE_PARAM_LONG,
     512  		G_TYPE_BYTES,
     513  		G_TYPE_POINTER,
     514  		test_get_type (),
     515                  G_TYPE_VARIANT,
     516  		G_TYPE_INT64,
     517  		G_TYPE_UINT64);
     518    g_signal_new ("all-types-empty",
     519                  G_TYPE_FROM_CLASS (klass),
     520                  G_SIGNAL_RUN_LAST,
     521                  0,
     522                  NULL, NULL,
     523                  test_VOID__INT_BOOLEAN_CHAR_UCHAR_UINT_LONG_ULONG_ENUM_FLAGS_FLOAT_DOUBLE_STRING_PARAM_BOXED_POINTER_OBJECT_VARIANT_INT64_UINT64,
     524                  G_TYPE_NONE,
     525                  19,
     526  		G_TYPE_INT,
     527  		G_TYPE_BOOLEAN,
     528  		G_TYPE_CHAR,
     529  		G_TYPE_UCHAR,
     530  		G_TYPE_UINT,
     531  		G_TYPE_LONG,
     532  		G_TYPE_ULONG,
     533  		enum_type,
     534  		flags_type,
     535  		G_TYPE_FLOAT,
     536  		G_TYPE_DOUBLE,
     537  		G_TYPE_STRING,
     538  		G_TYPE_PARAM_LONG,
     539  		G_TYPE_BYTES,
     540  		G_TYPE_POINTER,
     541  		test_get_type (),
     542                  G_TYPE_VARIANT,
     543  		G_TYPE_INT64,
     544  		G_TYPE_UINT64);
     545  }
     546  
     547  typedef struct _Test Test2;
     548  typedef struct _TestClass Test2Class;
     549  
     550  static GType test2_get_type (void);
     551  G_DEFINE_TYPE (Test2, test2, G_TYPE_OBJECT)
     552  
     553  static void
     554  test2_init (Test2 *test)
     555  {
     556  }
     557  
     558  static void
     559  test2_class_init (Test2Class *klass)
     560  {
     561  }
     562  
     563  static void
     564  test_variant_signal (void)
     565  {
     566    Test *test;
     567    GVariant *v;
     568  
     569    /* Tests that the signal emission consumes the variant,
     570     * even if there are no handlers connected.
     571     */
     572  
     573    test = g_object_new (test_get_type (), NULL);
     574  
     575    v = g_variant_new_boolean (TRUE);
     576    g_variant_ref (v);
     577    g_assert_true (g_variant_is_floating (v));
     578    g_signal_emit_by_name (test, "variant-changed-no-slot", v);
     579    g_assert_false (g_variant_is_floating (v));
     580    g_variant_unref (v);
     581  
     582    v = g_variant_new_boolean (TRUE);
     583    g_variant_ref (v);
     584    g_assert_true (g_variant_is_floating (v));
     585    g_signal_emit_by_name (test, "variant-changed", v);
     586    g_assert_false (g_variant_is_floating (v));
     587    g_variant_unref (v);
     588  
     589    g_object_unref (test);
     590  }
     591  
     592  static void
     593  on_generic_marshaller_1 (Test *obj,
     594  			 gint8 v_schar,
     595  			 guint8 v_uchar,
     596  			 gint v_int,
     597  			 glong v_long,
     598  			 gpointer v_pointer,
     599  			 gdouble v_double,
     600  			 gfloat v_float,
     601  			 gpointer user_data)
     602  {
     603    g_assert_cmpint (v_schar, ==, 42);
     604    g_assert_cmpint (v_uchar, ==, 43);
     605    g_assert_cmpint (v_int, ==, 4096);
     606    g_assert_cmpint (v_long, ==, 8192);
     607    g_assert_null (v_pointer);
     608    g_assert_cmpfloat (v_double, >, 0.0);
     609    g_assert_cmpfloat (v_double, <, 1.0);
     610    g_assert_cmpfloat (v_float, >, 5.0);
     611    g_assert_cmpfloat (v_float, <, 6.0);
     612  }
     613  			 
     614  static void
     615  test_generic_marshaller_signal_1 (void)
     616  {
     617    Test *test;
     618    test = g_object_new (test_get_type (), NULL);
     619  
     620    g_signal_connect (test, "generic-marshaller-1", G_CALLBACK (on_generic_marshaller_1), NULL);
     621  
     622    g_signal_emit_by_name (test, "generic-marshaller-1", 42, 43, 4096, 8192, NULL, 0.5, 5.5);
     623  
     624    g_object_unref (test);
     625  }
     626  
     627  static void
     628  on_generic_marshaller_2 (Test *obj,
     629  			 gint        v_int1,
     630  			 TestEnum    v_enum,
     631  			 gint        v_int2,
     632  			 TestUnsignedEnum v_uenum,
     633  			 gint        v_int3)
     634  {
     635    g_assert_cmpint (v_int1, ==, 42);
     636    g_assert_cmpint (v_enum, ==, TEST_ENUM_BAR);
     637    g_assert_cmpint (v_int2, ==, 43);
     638    g_assert_cmpint (v_uenum, ==, TEST_UNSIGNED_ENUM_BAR);
     639    g_assert_cmpint (v_int3, ==, 44);
     640  }
     641  
     642  static void
     643  test_generic_marshaller_signal_2 (void)
     644  {
     645    Test *test;
     646    test = g_object_new (test_get_type (), NULL);
     647  
     648    g_signal_connect (test, "generic-marshaller-2", G_CALLBACK (on_generic_marshaller_2), NULL);
     649  
     650    g_signal_emit_by_name (test, "generic-marshaller-2", 42, TEST_ENUM_BAR, 43, TEST_UNSIGNED_ENUM_BAR, 44);
     651  
     652    g_object_unref (test);
     653  }
     654  
     655  static TestEnum
     656  on_generic_marshaller_enum_return_signed_1 (Test *obj)
     657  {
     658    return TEST_ENUM_NEGATIVE;
     659  }
     660  
     661  static TestEnum
     662  on_generic_marshaller_enum_return_signed_2 (Test *obj)
     663  {
     664    return TEST_ENUM_BAR;
     665  }
     666  
     667  static void
     668  test_generic_marshaller_signal_enum_return_signed (void)
     669  {
     670    Test *test;
     671    guint id;
     672    TestEnum retval = 0;
     673  
     674    test = g_object_new (test_get_type (), NULL);
     675  
     676    /* Test return value NEGATIVE */
     677    id = g_signal_connect (test,
     678                           "generic-marshaller-enum-return-signed",
     679                           G_CALLBACK (on_generic_marshaller_enum_return_signed_1),
     680                           NULL);
     681    g_signal_emit_by_name (test, "generic-marshaller-enum-return-signed", &retval);
     682    g_assert_cmpint (retval, ==, TEST_ENUM_NEGATIVE);
     683    g_signal_handler_disconnect (test, id);
     684  
     685    /* Test return value BAR */
     686    retval = 0;
     687    id = g_signal_connect (test,
     688                           "generic-marshaller-enum-return-signed",
     689                           G_CALLBACK (on_generic_marshaller_enum_return_signed_2),
     690                           NULL);
     691    g_signal_emit_by_name (test, "generic-marshaller-enum-return-signed", &retval);
     692    g_assert_cmpint (retval, ==, TEST_ENUM_BAR);
     693    g_signal_handler_disconnect (test, id);
     694  
     695    g_object_unref (test);
     696  }
     697  
     698  static TestUnsignedEnum
     699  on_generic_marshaller_enum_return_unsigned_1 (Test *obj)
     700  {
     701    return TEST_UNSIGNED_ENUM_FOO;
     702  }
     703  
     704  static TestUnsignedEnum
     705  on_generic_marshaller_enum_return_unsigned_2 (Test *obj)
     706  {
     707    return TEST_UNSIGNED_ENUM_BAR;
     708  }
     709  
     710  static void
     711  test_generic_marshaller_signal_enum_return_unsigned (void)
     712  {
     713    Test *test;
     714    guint id;
     715    TestUnsignedEnum retval = 0;
     716  
     717    test = g_object_new (test_get_type (), NULL);
     718  
     719    /* Test return value FOO */
     720    id = g_signal_connect (test,
     721                           "generic-marshaller-enum-return-unsigned",
     722                           G_CALLBACK (on_generic_marshaller_enum_return_unsigned_1),
     723                           NULL);
     724    g_signal_emit_by_name (test, "generic-marshaller-enum-return-unsigned", &retval);
     725    g_assert_cmpint (retval, ==, TEST_UNSIGNED_ENUM_FOO);
     726    g_signal_handler_disconnect (test, id);
     727  
     728    /* Test return value BAR */
     729    retval = 0;
     730    id = g_signal_connect (test,
     731                           "generic-marshaller-enum-return-unsigned",
     732                           G_CALLBACK (on_generic_marshaller_enum_return_unsigned_2),
     733                           NULL);
     734    g_signal_emit_by_name (test, "generic-marshaller-enum-return-unsigned", &retval);
     735    g_assert_cmpint (retval, ==, TEST_UNSIGNED_ENUM_BAR);
     736    g_signal_handler_disconnect (test, id);
     737  
     738    g_object_unref (test);
     739  }
     740  
     741  /**********************/
     742  
     743  static gint
     744  on_generic_marshaller_int_return_signed_1 (Test *obj)
     745  {
     746    return -30;
     747  }
     748  
     749  static gint
     750  on_generic_marshaller_int_return_signed_2 (Test *obj)
     751  {
     752    return 2;
     753  }
     754  
     755  static void
     756  test_generic_marshaller_signal_int_return (void)
     757  {
     758    Test *test;
     759    guint id;
     760    gint retval = 0;
     761  
     762    test = g_object_new (test_get_type (), NULL);
     763  
     764    /* Test return value -30 */
     765    id = g_signal_connect (test,
     766                           "generic-marshaller-int-return",
     767                           G_CALLBACK (on_generic_marshaller_int_return_signed_1),
     768                           NULL);
     769    g_signal_emit_by_name (test, "generic-marshaller-int-return", &retval);
     770    g_assert_cmpint (retval, ==, -30);
     771    g_signal_handler_disconnect (test, id);
     772  
     773    /* Test return value positive */
     774    retval = 0;
     775    id = g_signal_connect (test,
     776                           "generic-marshaller-int-return",
     777                           G_CALLBACK (on_generic_marshaller_int_return_signed_2),
     778                           NULL);
     779    g_signal_emit_by_name (test, "generic-marshaller-int-return", &retval);
     780    g_assert_cmpint (retval, ==, 2);
     781    g_signal_handler_disconnect (test, id);
     782  
     783    /* Same test for va marshaller */
     784  
     785    /* Test return value -30 */
     786    id = g_signal_connect (test,
     787                           "va-marshaller-int-return",
     788                           G_CALLBACK (on_generic_marshaller_int_return_signed_1),
     789                           NULL);
     790    g_signal_emit_by_name (test, "va-marshaller-int-return", &retval);
     791    g_assert_cmpint (retval, ==, -30);
     792    g_signal_handler_disconnect (test, id);
     793  
     794    /* Test return value positive */
     795    retval = 0;
     796    id = g_signal_connect (test,
     797                           "va-marshaller-int-return",
     798                           G_CALLBACK (on_generic_marshaller_int_return_signed_2),
     799                           NULL);
     800    g_signal_emit_by_name (test, "va-marshaller-int-return", &retval);
     801    g_assert_cmpint (retval, ==, 2);
     802    g_signal_handler_disconnect (test, id);
     803  
     804    g_object_unref (test);
     805  }
     806  
     807  static guint
     808  on_generic_marshaller_uint_return_1 (Test *obj)
     809  {
     810    return 1;
     811  }
     812  
     813  static guint
     814  on_generic_marshaller_uint_return_2 (Test *obj)
     815  {
     816    return G_MAXUINT;
     817  }
     818  
     819  static void
     820  test_generic_marshaller_signal_uint_return (void)
     821  {
     822    Test *test;
     823    guint id;
     824    guint retval = 0;
     825  
     826    test = g_object_new (test_get_type (), NULL);
     827  
     828    id = g_signal_connect (test,
     829                           "generic-marshaller-uint-return",
     830                           G_CALLBACK (on_generic_marshaller_uint_return_1),
     831                           NULL);
     832    g_signal_emit_by_name (test, "generic-marshaller-uint-return", &retval);
     833    g_assert_cmpint (retval, ==, 1);
     834    g_signal_handler_disconnect (test, id);
     835  
     836    retval = 0;
     837    id = g_signal_connect (test,
     838                           "generic-marshaller-uint-return",
     839                           G_CALLBACK (on_generic_marshaller_uint_return_2),
     840                           NULL);
     841    g_signal_emit_by_name (test, "generic-marshaller-uint-return", &retval);
     842    g_assert_cmpint (retval, ==, G_MAXUINT);
     843    g_signal_handler_disconnect (test, id);
     844  
     845    /* Same test for va marshaller */
     846  
     847    id = g_signal_connect (test,
     848                           "va-marshaller-uint-return",
     849                           G_CALLBACK (on_generic_marshaller_uint_return_1),
     850                           NULL);
     851    g_signal_emit_by_name (test, "va-marshaller-uint-return", &retval);
     852    g_assert_cmpint (retval, ==, 1);
     853    g_signal_handler_disconnect (test, id);
     854  
     855    retval = 0;
     856    id = g_signal_connect (test,
     857                           "va-marshaller-uint-return",
     858                           G_CALLBACK (on_generic_marshaller_uint_return_2),
     859                           NULL);
     860    g_signal_emit_by_name (test, "va-marshaller-uint-return", &retval);
     861    g_assert_cmpint (retval, ==, G_MAXUINT);
     862    g_signal_handler_disconnect (test, id);
     863  
     864    g_object_unref (test);
     865  }
     866  
     867  static gpointer
     868  on_generic_marshaller_interface_return (Test *test)
     869  {
     870    return g_object_new (baa_get_type (), NULL);
     871  }
     872  
     873  static void
     874  test_generic_marshaller_signal_interface_return (void)
     875  {
     876    Test *test;
     877    guint id;
     878    gpointer retval;
     879  
     880    test = g_object_new (test_get_type (), NULL);
     881  
     882    /* Test return value -30 */
     883    id = g_signal_connect (test,
     884                           "generic-marshaller-interface-return",
     885                           G_CALLBACK (on_generic_marshaller_interface_return),
     886                           NULL);
     887    g_signal_emit_by_name (test, "generic-marshaller-interface-return", &retval);
     888    g_assert_true (g_type_check_instance_is_a ((GTypeInstance*)retval, foo_get_type ()));
     889    g_object_unref (retval);
     890  
     891    g_signal_handler_disconnect (test, id);
     892  
     893    g_object_unref (test);
     894  }
     895  
     896  static const GSignalInvocationHint dont_use_this = { 0, };
     897  
     898  static void
     899  custom_marshaller_callback (Test                  *test,
     900                              GSignalInvocationHint *hint,
     901                              gpointer               unused)
     902  {
     903    GSignalInvocationHint *ihint;
     904  
     905    g_assert_true (hint != &dont_use_this);
     906  
     907    ihint = g_signal_get_invocation_hint (test);
     908  
     909    g_assert_cmpuint (hint->signal_id, ==, ihint->signal_id);
     910    g_assert_cmpuint (hint->detail , ==, ihint->detail);
     911    g_assert_cmpflags (GSignalFlags, hint->run_type, ==, ihint->run_type); 
     912  }
     913  
     914  static void
     915  test_custom_marshaller (void)
     916  {
     917    Test *test;
     918  
     919    test = g_object_new (test_get_type (), NULL);
     920  
     921    g_signal_connect (test,
     922                      "custom-marshaller",
     923                      G_CALLBACK (custom_marshaller_callback),
     924                      NULL);
     925  
     926    g_signal_emit_by_name (test, "custom-marshaller", &dont_use_this);
     927  
     928    g_object_unref (test);
     929  }
     930  
     931  static int all_type_handlers_count = 0;
     932  
     933  static void
     934  all_types_handler (Test *test, int i, gboolean b, char c, guchar uc, guint ui, glong l, gulong ul, MyEnum e, MyFlags f, float fl, double db, char *str, GParamSpec *param, GBytes *bytes, gpointer ptr, Test *obj, GVariant *var, gint64 i64, guint64 ui64)
     935  {
     936    all_type_handlers_count++;
     937  
     938    g_assert_cmpint (i, ==, 42);
     939    g_assert_cmpint (b, ==, TRUE);
     940    g_assert_cmpint (c, ==, 17);
     941    g_assert_cmpuint (uc, ==, 140);
     942    g_assert_cmpuint (ui, ==, G_MAXUINT - 42);
     943    g_assert_cmpint (l, ==, -1117);
     944    g_assert_cmpuint (ul, ==, G_MAXULONG - 999);
     945    g_assert_cmpenum (MyEnum, e, ==, MY_ENUM_VALUE);
     946    g_assert_cmpflags (MyFlags, f, ==, MY_FLAGS_FIRST_BIT | MY_FLAGS_THIRD_BIT | MY_FLAGS_LAST_BIT);
     947    g_assert_cmpfloat (fl, ==, 0.25);
     948    g_assert_cmpfloat (db, ==, 1.5);
     949    g_assert_cmpstr (str, ==, "Test");
     950    g_assert_cmpstr (g_param_spec_get_nick (param), ==, "nick");
     951    g_assert_cmpstr (g_bytes_get_data (bytes, NULL), ==, "Blah");
     952    g_assert_true (ptr == &enum_type);
     953    g_assert_cmpuint (g_variant_get_uint16 (var), == , 99);
     954    g_assert_cmpint (i64, ==, G_MAXINT64 - 1234);
     955    g_assert_cmpuint (ui64, ==, G_MAXUINT64 - 123456);
     956  }
     957  
     958  static void
     959  all_types_handler_cb (Test *test, int i, gboolean b, char c, guchar uc, guint ui, glong l, gulong ul, MyEnum e, guint f, float fl, double db, char *str, GParamSpec *param, GBytes *bytes, gpointer ptr, Test *obj, GVariant *var, gint64 i64, guint64 ui64, gpointer user_data)
     960  {
     961    g_assert_true (user_data == &flags_type);
     962    all_types_handler (test, i, b, c, uc, ui, l, ul, e, f, fl, db, str, param, bytes, ptr, obj, var, i64, ui64);
     963  }
     964  
     965  static void
     966  test_all_types (void)
     967  {
     968    Test *test;
     969  
     970    int i = 42;
     971    gboolean b = TRUE;
     972    char c = 17;
     973    guchar uc = 140;
     974    guint ui = G_MAXUINT - 42;
     975    glong l =  -1117;
     976    gulong ul = G_MAXULONG - 999;
     977    MyEnum e = MY_ENUM_VALUE;
     978    MyFlags f = MY_FLAGS_FIRST_BIT | MY_FLAGS_THIRD_BIT | MY_FLAGS_LAST_BIT;
     979    float fl = 0.25;
     980    double db = 1.5;
     981    char *str = "Test";
     982    GParamSpec *param = g_param_spec_long	 ("param", "nick", "blurb", 0, 10, 4, 0);
     983    GBytes *bytes = g_bytes_new_static ("Blah", 5);
     984    gpointer ptr = &enum_type;
     985    GVariant *var = g_variant_new_uint16 (99);
     986    gint64 i64;
     987    guint64 ui64;
     988    g_variant_ref_sink (var);
     989    i64 = G_MAXINT64 - 1234;
     990    ui64 = G_MAXUINT64 - 123456;
     991  
     992    test = g_object_new (test_get_type (), NULL);
     993  
     994    all_type_handlers_count = 0;
     995  
     996    g_signal_emit_by_name (test, "all-types",
     997  			 i, b, c, uc, ui, l, ul, e, f, fl, db, str, param, bytes, ptr, test, var, i64, ui64);
     998    g_signal_emit_by_name (test, "all-types-va",
     999  			 i, b, c, uc, ui, l, ul, e, f, fl, db, str, param, bytes, ptr, test, var, i64, ui64);
    1000    g_signal_emit_by_name (test, "all-types-generic",
    1001  			 i, b, c, uc, ui, l, ul, e, f, fl, db, str, param, bytes, ptr, test, var, i64, ui64);
    1002    g_signal_emit_by_name (test, "all-types-empty",
    1003  			 i, b, c, uc, ui, l, ul, e, f, fl, db, str, param, bytes, ptr, test, var, i64, ui64);
    1004    g_signal_emit_by_name (test, "all-types-null",
    1005  			 i, b, c, uc, ui, l, ul, e, f, fl, db, str, param, bytes, ptr, test, var, i64, ui64);
    1006  
    1007    g_assert_cmpint (all_type_handlers_count, ==, 3);
    1008  
    1009    all_type_handlers_count = 0;
    1010  
    1011    g_signal_connect (test, "all-types", G_CALLBACK (all_types_handler_cb), &flags_type);
    1012    g_signal_connect (test, "all-types-va", G_CALLBACK (all_types_handler_cb), &flags_type);
    1013    g_signal_connect (test, "all-types-generic", G_CALLBACK (all_types_handler_cb), &flags_type);
    1014    g_signal_connect (test, "all-types-empty", G_CALLBACK (all_types_handler_cb), &flags_type);
    1015    g_signal_connect (test, "all-types-null", G_CALLBACK (all_types_handler_cb), &flags_type);
    1016  
    1017    g_signal_emit_by_name (test, "all-types",
    1018  			 i, b, c, uc, ui, l, ul, e, f, fl, db, str, param, bytes, ptr, test, var, i64, ui64);
    1019    g_signal_emit_by_name (test, "all-types-va",
    1020  			 i, b, c, uc, ui, l, ul, e, f, fl, db, str, param, bytes, ptr, test, var, i64, ui64);
    1021    g_signal_emit_by_name (test, "all-types-generic",
    1022  			 i, b, c, uc, ui, l, ul, e, f, fl, db, str, param, bytes, ptr, test, var, i64, ui64);
    1023    g_signal_emit_by_name (test, "all-types-empty",
    1024  			 i, b, c, uc, ui, l, ul, e, f, fl, db, str, param, bytes, ptr, test, var, i64, ui64);
    1025    g_signal_emit_by_name (test, "all-types-null",
    1026  			 i, b, c, uc, ui, l, ul, e, f, fl, db, str, param, bytes, ptr, test, var, i64, ui64);
    1027  
    1028    g_assert_cmpint (all_type_handlers_count, ==, 3 + 5);
    1029  
    1030    all_type_handlers_count = 0;
    1031  
    1032    g_signal_connect (test, "all-types", G_CALLBACK (all_types_handler_cb), &flags_type);
    1033    g_signal_connect (test, "all-types-va", G_CALLBACK (all_types_handler_cb), &flags_type);
    1034    g_signal_connect (test, "all-types-generic", G_CALLBACK (all_types_handler_cb), &flags_type);
    1035    g_signal_connect (test, "all-types-empty", G_CALLBACK (all_types_handler_cb), &flags_type);
    1036    g_signal_connect (test, "all-types-null", G_CALLBACK (all_types_handler_cb), &flags_type);
    1037  
    1038    g_signal_emit_by_name (test, "all-types",
    1039  			 i, b, c, uc, ui, l, ul, e, f, fl, db, str, param, bytes, ptr, test, var, i64, ui64);
    1040    g_signal_emit_by_name (test, "all-types-va",
    1041  			 i, b, c, uc, ui, l, ul, e, f, fl, db, str, param, bytes, ptr, test, var, i64, ui64);
    1042    g_signal_emit_by_name (test, "all-types-generic",
    1043  			 i, b, c, uc, ui, l, ul, e, f, fl, db, str, param, bytes, ptr, test, var, i64, ui64);
    1044    g_signal_emit_by_name (test, "all-types-empty",
    1045  			 i, b, c, uc, ui, l, ul, e, f, fl, db, str, param, bytes, ptr, test, var, i64, ui64);
    1046    g_signal_emit_by_name (test, "all-types-null",
    1047  			 i, b, c, uc, ui, l, ul, e, f, fl, db, str, param, bytes, ptr, test, var, i64, ui64);
    1048  
    1049    g_assert_cmpint (all_type_handlers_count, ==, 3 + 5 + 5);
    1050  
    1051    g_object_unref (test);
    1052    g_param_spec_unref (param);
    1053    g_bytes_unref (bytes);
    1054    g_variant_unref (var);
    1055  }
    1056  
    1057  static void
    1058  test_connect (void)
    1059  {
    1060    GObject *test;
    1061    gint retval;
    1062  
    1063    test = g_object_new (test_get_type (), NULL);
    1064  
    1065    g_object_connect (test,
    1066                      "signal::generic-marshaller-int-return",
    1067                      G_CALLBACK (on_generic_marshaller_int_return_signed_1),
    1068                      NULL,
    1069                      "object-signal::va-marshaller-int-return",
    1070                      G_CALLBACK (on_generic_marshaller_int_return_signed_2),
    1071                      NULL,
    1072                      NULL);
    1073    g_signal_emit_by_name (test, "generic-marshaller-int-return", &retval);
    1074    g_assert_cmpint (retval, ==, -30);
    1075    g_signal_emit_by_name (test, "va-marshaller-int-return", &retval);
    1076    g_assert_cmpint (retval, ==, 2);
    1077  
    1078    g_object_disconnect (test,
    1079                         "any-signal",
    1080                         G_CALLBACK (on_generic_marshaller_int_return_signed_1),
    1081                         NULL,
    1082                         "any-signal::va-marshaller-int-return",
    1083                         G_CALLBACK (on_generic_marshaller_int_return_signed_2),
    1084                         NULL,
    1085                         NULL);
    1086  
    1087    g_object_unref (test);
    1088  }
    1089  
    1090  static void
    1091  simple_handler1 (GObject *sender,
    1092                   GObject *target)
    1093  {
    1094    g_object_unref (target);
    1095  }
    1096  
    1097  static void
    1098  simple_handler2 (GObject *sender,
    1099                   GObject *target)
    1100  {
    1101    g_object_unref (target);
    1102  }
    1103  
    1104  static void
    1105  test_destroy_target_object (void)
    1106  {
    1107    Test *sender, *target1, *target2;
    1108  
    1109    sender = g_object_new (test_get_type (), NULL);
    1110    target1 = g_object_new (test_get_type (), NULL);
    1111    target2 = g_object_new (test_get_type (), NULL);
    1112    g_signal_connect_object (sender, "simple", G_CALLBACK (simple_handler1),
    1113                             target1, G_CONNECT_DEFAULT);
    1114    g_signal_connect_object (sender, "simple", G_CALLBACK (simple_handler2),
    1115                             target2, G_CONNECT_DEFAULT);
    1116    g_signal_emit_by_name (sender, "simple");
    1117    g_object_unref (sender);
    1118  }
    1119  
    1120  static gboolean
    1121  hook_func (GSignalInvocationHint *ihint,
    1122             guint                  n_params,
    1123             const GValue          *params,
    1124             gpointer               data)
    1125  {
    1126    gint *count = data;
    1127  
    1128    (*count)++;
    1129  
    1130    return TRUE;
    1131  }
    1132  
    1133  static gboolean
    1134  hook_func_removal (GSignalInvocationHint *ihint,
    1135                     guint                  n_params,
    1136                     const GValue          *params,
    1137                     gpointer               data)
    1138  {
    1139    gint *count = data;
    1140  
    1141    (*count)++;
    1142  
    1143    return FALSE;
    1144  }
    1145  
    1146  static void
    1147  simple_handler_remove_hook (GObject *sender,
    1148                              gpointer data)
    1149  {
    1150    gulong *hook = data;
    1151  
    1152    g_signal_remove_emission_hook (simple_id, *hook);
    1153  }
    1154  
    1155  static void
    1156  test_emission_hook (void)
    1157  {
    1158    GObject *test1, *test2;
    1159    gint count = 0;
    1160    gulong hook;
    1161    gulong connection_id;
    1162  
    1163    test1 = g_object_new (test_get_type (), NULL);
    1164    test2 = g_object_new (test_get_type (), NULL);
    1165  
    1166    hook = g_signal_add_emission_hook (simple_id, 0, hook_func, &count, NULL);
    1167    g_assert_cmpint (count, ==, 0);
    1168    g_signal_emit_by_name (test1, "simple");
    1169    g_assert_cmpint (count, ==, 1);
    1170    g_signal_emit_by_name (test2, "simple");
    1171    g_assert_cmpint (count, ==, 2);
    1172    g_signal_remove_emission_hook (simple_id, hook);
    1173    g_signal_emit_by_name (test1, "simple");
    1174    g_assert_cmpint (count, ==, 2);
    1175  
    1176    count = 0;
    1177    hook = g_signal_add_emission_hook (simple_id, 0, hook_func_removal, &count, NULL);
    1178    g_assert_cmpint (count, ==, 0);
    1179    g_signal_emit_by_name (test1, "simple");
    1180    g_assert_cmpint (count, ==, 1);
    1181    g_signal_emit_by_name (test2, "simple");
    1182    g_assert_cmpint (count, ==, 1);
    1183  
    1184    g_test_expect_message ("GLib-GObject", G_LOG_LEVEL_CRITICAL,
    1185                           "*simple* had no hook * to remove");
    1186    g_signal_remove_emission_hook (simple_id, hook);
    1187    g_test_assert_expected_messages ();
    1188  
    1189    count = 0;
    1190    hook = g_signal_add_emission_hook (simple_id, 0, hook_func, &count, NULL);
    1191    connection_id = g_signal_connect (test1, "simple",
    1192                                      G_CALLBACK (simple_handler_remove_hook), &hook);
    1193    g_assert_cmpint (count, ==, 0);
    1194    g_signal_emit_by_name (test1, "simple");
    1195    g_assert_cmpint (count, ==, 1);
    1196    g_signal_emit_by_name (test2, "simple");
    1197    g_assert_cmpint (count, ==, 1);
    1198  
    1199    g_test_expect_message ("GLib-GObject", G_LOG_LEVEL_CRITICAL,
    1200                           "*simple* had no hook * to remove");
    1201    g_signal_remove_emission_hook (simple_id, hook);
    1202    g_test_assert_expected_messages ();
    1203  
    1204    g_clear_signal_handler (&connection_id, test1);
    1205  
    1206    gulong hooks[10];
    1207    count = 0;
    1208  
    1209    for (size_t i = 0; i < G_N_ELEMENTS (hooks); ++i)
    1210      hooks[i] = g_signal_add_emission_hook (simple_id, 0, hook_func, &count, NULL);
    1211  
    1212    g_assert_cmpint (count, ==, 0);
    1213    g_signal_emit_by_name (test1, "simple");
    1214    g_assert_cmpint (count, ==, 10);
    1215    g_signal_emit_by_name (test2, "simple");
    1216    g_assert_cmpint (count, ==, 20);
    1217  
    1218    for (size_t i = 0; i < G_N_ELEMENTS (hooks); ++i)
    1219      g_signal_remove_emission_hook (simple_id, hooks[i]);
    1220  
    1221    g_signal_emit_by_name (test1, "simple");
    1222    g_assert_cmpint (count, ==, 20);
    1223  
    1224    count = 0;
    1225  
    1226    for (size_t i = 0; i < G_N_ELEMENTS (hooks); ++i)
    1227      hooks[i] = g_signal_add_emission_hook (simple_id, 0, hook_func_removal, &count, NULL);
    1228  
    1229    g_assert_cmpint (count, ==, 0);
    1230    g_signal_emit_by_name (test1, "simple");
    1231    g_assert_cmpint (count, ==, 10);
    1232    g_signal_emit_by_name (test2, "simple");
    1233    g_assert_cmpint (count, ==, 10);
    1234  
    1235    for (size_t i = 0; i < G_N_ELEMENTS (hooks); ++i)
    1236      {
    1237        g_test_expect_message ("GLib-GObject", G_LOG_LEVEL_CRITICAL,
    1238                           "*simple* had no hook * to remove");
    1239        g_signal_remove_emission_hook (simple_id, hooks[i]);
    1240        g_test_assert_expected_messages ();
    1241      }
    1242  
    1243    g_object_unref (test1);
    1244    g_object_unref (test2);
    1245  }
    1246  
    1247  static void
    1248  simple_cb (gpointer instance, gpointer data)
    1249  {
    1250    GSignalInvocationHint *ihint;
    1251  
    1252    ihint = g_signal_get_invocation_hint (instance);
    1253  
    1254    g_assert_cmpstr (g_signal_name (ihint->signal_id), ==, "simple");
    1255  
    1256    g_signal_emit_by_name (instance, "simple-2");
    1257  }
    1258  
    1259  static void
    1260  simple2_cb (gpointer instance, gpointer data)
    1261  {
    1262    GSignalInvocationHint *ihint;
    1263  
    1264    ihint = g_signal_get_invocation_hint (instance);
    1265  
    1266    g_assert_cmpstr (g_signal_name (ihint->signal_id), ==, "simple-2");
    1267  }
    1268  
    1269  static void
    1270  test_invocation_hint (void)
    1271  {
    1272    GObject *test;
    1273  
    1274    test = g_object_new (test_get_type (), NULL);
    1275  
    1276    g_signal_connect (test, "simple", G_CALLBACK (simple_cb), NULL);
    1277    g_signal_connect (test, "simple-2", G_CALLBACK (simple2_cb), NULL);
    1278    g_signal_emit_by_name (test, "simple");
    1279  
    1280    g_object_unref (test);
    1281  }
    1282  
    1283  static gboolean
    1284  accumulator_sum (GSignalInvocationHint *ihint,
    1285                   GValue                *return_accu,
    1286                   const GValue          *handler_return,
    1287                   gpointer               data)
    1288  {
    1289    gint acc = g_value_get_int (return_accu);
    1290    gint ret = g_value_get_int (handler_return);
    1291  
    1292    g_assert_cmpint (ret, >, 0);
    1293  
    1294    if (ihint->run_type & G_SIGNAL_ACCUMULATOR_FIRST_RUN)
    1295      {
    1296        g_assert_cmpint (acc, ==, 0);
    1297        g_assert_cmpint (ret, ==, 1);
    1298        g_assert_true (ihint->run_type & G_SIGNAL_RUN_FIRST);
    1299        g_assert_false (ihint->run_type & G_SIGNAL_RUN_LAST);
    1300      }
    1301    else if (ihint->run_type & G_SIGNAL_RUN_FIRST)
    1302      {
    1303        /* Only the first signal handler was called so far */
    1304        g_assert_cmpint (acc, ==, 1);
    1305        g_assert_cmpint (ret, ==, 2);
    1306        g_assert_false (ihint->run_type & G_SIGNAL_RUN_LAST);
    1307      }
    1308    else if (ihint->run_type & G_SIGNAL_RUN_LAST)
    1309      {
    1310        /* Only the first two signal handler were called so far */
    1311        g_assert_cmpint (acc, ==, 3);
    1312        g_assert_cmpint (ret, ==, 3);
    1313        g_assert_false (ihint->run_type & G_SIGNAL_RUN_FIRST);
    1314      }
    1315    else
    1316      {
    1317        g_assert_not_reached ();
    1318      }
    1319  
    1320    g_value_set_int (return_accu, acc + ret);
    1321  
    1322    /* Continue with the other signal handlers as long as the sum is < 6,
    1323     * i.e. don't run simple_accumulator_4_cb() */
    1324    return acc + ret < 6;
    1325  }
    1326  
    1327  static gint
    1328  simple_accumulator_1_cb (gpointer instance, gpointer data)
    1329  {
    1330    return 1;
    1331  }
    1332  
    1333  static gint
    1334  simple_accumulator_2_cb (gpointer instance, gpointer data)
    1335  {
    1336    return 2;
    1337  }
    1338  
    1339  static gint
    1340  simple_accumulator_3_cb (gpointer instance, gpointer data)
    1341  {
    1342    return 3;
    1343  }
    1344  
    1345  static gint
    1346  simple_accumulator_4_cb (gpointer instance, gpointer data)
    1347  {
    1348    return 4;
    1349  }
    1350  
    1351  static void
    1352  test_accumulator (void)
    1353  {
    1354    GObject *test;
    1355    gint ret = -1;
    1356  
    1357    test = g_object_new (test_get_type (), NULL);
    1358  
    1359    /* Connect in reverse order to make sure that LAST signal handlers are
    1360     * called after FIRST signal handlers but signal handlers in each "group"
    1361     * are called in the order they were registered */
    1362    g_signal_connect_after (test, "simple-accumulator", G_CALLBACK (simple_accumulator_3_cb), NULL);
    1363    g_signal_connect_after (test, "simple-accumulator", G_CALLBACK (simple_accumulator_4_cb), NULL);
    1364    g_signal_connect (test, "simple-accumulator", G_CALLBACK (simple_accumulator_1_cb), NULL);
    1365    g_signal_connect (test, "simple-accumulator", G_CALLBACK (simple_accumulator_2_cb), NULL);
    1366    g_signal_emit_by_name (test, "simple-accumulator", &ret);
    1367  
    1368    /* simple_accumulator_4_cb() is not run because accumulator is 6 */
    1369    g_assert_cmpint (ret, ==, 6);
    1370  
    1371    g_object_unref (test);
    1372  }
    1373  
    1374  static gboolean
    1375  accumulator_concat_string (GSignalInvocationHint *ihint, GValue *return_accu, const GValue *handler_return, gpointer data)
    1376  {
    1377    const gchar *acc = g_value_get_string (return_accu);
    1378    const gchar *ret = g_value_get_string (handler_return);
    1379  
    1380    g_assert_nonnull (ret);
    1381  
    1382    if (acc == NULL)
    1383      g_value_set_string (return_accu, ret);
    1384    else
    1385      g_value_take_string (return_accu, g_strconcat (acc, ret, NULL));
    1386  
    1387    return TRUE;
    1388  }
    1389  
    1390  static gchar *
    1391  accumulator_class_before_cb (gpointer instance, gpointer data)
    1392  {
    1393    return g_strdup ("before");
    1394  }
    1395  
    1396  static gchar *
    1397  accumulator_class_after_cb (gpointer instance, gpointer data)
    1398  {
    1399    return g_strdup ("after");
    1400  }
    1401  
    1402  static gchar *
    1403  accumulator_class (Test *test)
    1404  {
    1405    return g_strdup ("class");
    1406  }
    1407  
    1408  static void
    1409  test_accumulator_class (void)
    1410  {
    1411    const struct {
    1412      const gchar *signal_name;
    1413      const gchar *return_string;
    1414    } tests[] = {
    1415      {"accumulator-class-first", "classbeforeafter"},
    1416      {"accumulator-class-last", "beforeclassafter"},
    1417      {"accumulator-class-cleanup", "beforeafterclass"},
    1418      {"accumulator-class-first-last", "classbeforeclassafter"},
    1419      {"accumulator-class-first-last-cleanup", "classbeforeclassafterclass"},
    1420      {"accumulator-class-last-cleanup", "beforeclassafterclass"},
    1421    };
    1422    gsize i;
    1423  
    1424    for (i = 0; i < G_N_ELEMENTS (tests); i++)
    1425      {
    1426        GObject *test;
    1427        gchar *ret = NULL;
    1428  
    1429        g_test_message ("Signal: %s", tests[i].signal_name);
    1430  
    1431        test = g_object_new (test_get_type (), NULL);
    1432  
    1433        g_signal_connect (test, tests[i].signal_name, G_CALLBACK (accumulator_class_before_cb), NULL);
    1434        g_signal_connect_after (test, tests[i].signal_name, G_CALLBACK (accumulator_class_after_cb), NULL);
    1435        g_signal_emit_by_name (test, tests[i].signal_name, &ret);
    1436  
    1437        g_assert_cmpstr (ret, ==, tests[i].return_string);
    1438        g_free (ret);
    1439  
    1440        g_object_unref (test);
    1441      }
    1442  }
    1443  
    1444  static gboolean
    1445  in_set (const gchar *s,
    1446          const gchar *set[])
    1447  {
    1448    gint i;
    1449  
    1450    for (i = 0; set[i]; i++)
    1451      {
    1452        if (g_strcmp0 (s, set[i]) == 0)
    1453          return TRUE;
    1454      }
    1455  
    1456    return FALSE;
    1457  }
    1458  
    1459  static void
    1460  test_introspection (void)
    1461  {
    1462    guint *ids;
    1463    guint n_ids;
    1464    const gchar *name;
    1465    guint i;
    1466    const gchar *names[] = {
    1467      "simple",
    1468      "simple-detailed",
    1469      "simple-2",
    1470      "simple-accumulator",
    1471      "accumulator-class-first",
    1472      "accumulator-class-last",
    1473      "accumulator-class-cleanup",
    1474      "accumulator-class-first-last",
    1475      "accumulator-class-first-last-cleanup",
    1476      "accumulator-class-last-cleanup",
    1477      "generic-marshaller-1",
    1478      "generic-marshaller-2",
    1479      "generic-marshaller-enum-return-signed",
    1480      "generic-marshaller-enum-return-unsigned",
    1481      "generic-marshaller-int-return",
    1482      "va-marshaller-int-return",
    1483      "generic-marshaller-uint-return",
    1484      "generic-marshaller-interface-return",
    1485      "va-marshaller-uint-return",
    1486      "variant-changed-no-slot",
    1487      "variant-changed",
    1488      "all-types",
    1489      "all-types-va",
    1490      "all-types-generic",
    1491      "all-types-null",
    1492      "all-types-empty",
    1493      "custom-marshaller",
    1494      NULL
    1495    };
    1496    GSignalQuery query;
    1497  
    1498    ids = g_signal_list_ids (test_get_type (), &n_ids);
    1499    g_assert_cmpuint (n_ids, ==, g_strv_length ((gchar**)names));
    1500  
    1501    for (i = 0; i < n_ids; i++)
    1502      {
    1503        name = g_signal_name (ids[i]);
    1504        g_assert_true (in_set (name, names));
    1505      }
    1506  
    1507    g_signal_query (simple_id, &query);
    1508    g_assert_cmpuint (query.signal_id, ==, simple_id);
    1509    g_assert_cmpstr (query.signal_name, ==, "simple");
    1510    g_assert_true (query.itype == test_get_type ());
    1511    g_assert_cmpint (query.signal_flags, ==, G_SIGNAL_RUN_LAST);
    1512    g_assert_cmpint (query.return_type, ==, G_TYPE_NONE);
    1513    g_assert_cmpuint (query.n_params, ==, 0);
    1514  
    1515    g_free (ids);
    1516  }
    1517  
    1518  static void
    1519  test_handler (gpointer instance, gpointer data)
    1520  {
    1521    gint *count = data;
    1522  
    1523    (*count)++;
    1524  }
    1525  
    1526  static void
    1527  test_block_handler (void)
    1528  {
    1529    GObject *test1, *test2;
    1530    gint count1 = 0;
    1531    gint count2 = 0;
    1532    gulong handler1, handler;
    1533  
    1534    test1 = g_object_new (test_get_type (), NULL);
    1535    test2 = g_object_new (test_get_type (), NULL);
    1536  
    1537    handler1 = g_signal_connect (test1, "simple", G_CALLBACK (test_handler), &count1);
    1538    g_signal_connect (test2, "simple", G_CALLBACK (test_handler), &count2);
    1539  
    1540    handler = g_signal_handler_find (test1, G_SIGNAL_MATCH_ID, simple_id, 0, NULL, NULL, NULL);
    1541  
    1542    g_assert_true (handler == handler1);
    1543  
    1544    g_assert_cmpint (count1, ==, 0);
    1545    g_assert_cmpint (count2, ==, 0);
    1546  
    1547    g_signal_emit_by_name (test1, "simple");
    1548    g_signal_emit_by_name (test2, "simple");
    1549  
    1550    g_assert_cmpint (count1, ==, 1);
    1551    g_assert_cmpint (count2, ==, 1);
    1552  
    1553    g_signal_handler_block (test1, handler1);
    1554  
    1555    g_signal_emit_by_name (test1, "simple");
    1556    g_signal_emit_by_name (test2, "simple");
    1557  
    1558    g_assert_cmpint (count1, ==, 1);
    1559    g_assert_cmpint (count2, ==, 2);
    1560  
    1561    g_signal_handler_unblock (test1, handler1);
    1562  
    1563    g_signal_emit_by_name (test1, "simple");
    1564    g_signal_emit_by_name (test2, "simple");
    1565  
    1566    g_assert_cmpint (count1, ==, 2);
    1567    g_assert_cmpint (count2, ==, 3);
    1568  
    1569    g_assert_cmpuint (g_signal_handlers_block_matched (test1, G_SIGNAL_MATCH_FUNC, 0, 0, NULL, test_block_handler, NULL), ==, 0);
    1570    g_assert_cmpuint (g_signal_handlers_block_matched (test2, G_SIGNAL_MATCH_FUNC, 0, 0, NULL, test_handler, NULL), ==, 1);
    1571  
    1572    g_signal_emit_by_name (test1, "simple");
    1573    g_signal_emit_by_name (test2, "simple");
    1574  
    1575    g_assert_cmpint (count1, ==, 3);
    1576    g_assert_cmpint (count2, ==, 3);
    1577  
    1578    g_signal_handlers_unblock_matched (test2, G_SIGNAL_MATCH_FUNC, 0, 0, NULL, test_handler, NULL);
    1579  
    1580    /* Test match by signal ID. */
    1581    g_assert_cmpuint (g_signal_handlers_block_matched (test1, G_SIGNAL_MATCH_ID, simple_id, 0, NULL, NULL, NULL), ==, 1);
    1582  
    1583    g_signal_emit_by_name (test1, "simple");
    1584    g_signal_emit_by_name (test2, "simple");
    1585  
    1586    g_assert_cmpint (count1, ==, 3);
    1587    g_assert_cmpint (count2, ==, 4);
    1588  
    1589    g_assert_cmpuint (g_signal_handlers_unblock_matched (test1, G_SIGNAL_MATCH_ID, simple_id, 0, NULL, NULL, NULL), ==, 1);
    1590  
    1591    /* Match types are conjunctive */
    1592    g_assert_cmpuint (g_signal_handlers_block_matched (test1, G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA, 0, 0, NULL, test_handler, "will not match"), ==, 0);
    1593    g_assert_cmpuint (g_signal_handlers_block_matched (test1, G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA, 0, 0, NULL, test_handler, &count1), ==, 1);
    1594    g_assert_cmpuint (g_signal_handlers_unblock_matched (test1, G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA, 0, 0, NULL, test_handler, &count1), ==, 1);
    1595  
    1596    /* Test g_signal_handlers_disconnect_matched for G_SIGNAL_MATCH_ID match */
    1597    g_assert_cmpuint (g_signal_handlers_disconnect_matched (test1,
    1598                                                            G_SIGNAL_MATCH_ID,
    1599                                                            simple_id, 0,
    1600                                                            NULL, NULL, NULL),
    1601                      ==,
    1602                      1);
    1603    g_assert_cmpuint (g_signal_handler_find (test1,
    1604                                             G_SIGNAL_MATCH_ID,
    1605                                             simple_id, 0,
    1606                                             NULL, NULL, NULL),
    1607                      ==,
    1608                      0);
    1609  
    1610    g_object_unref (test1);
    1611    g_object_unref (test2);
    1612  }
    1613  
    1614  static void
    1615  stop_emission (gpointer instance, gpointer data)
    1616  {
    1617    g_signal_stop_emission (instance, simple_id, 0);
    1618  }
    1619  
    1620  static void
    1621  stop_emission_by_name (gpointer instance, gpointer data)
    1622  {
    1623    g_signal_stop_emission_by_name (instance, "simple");
    1624  }
    1625  
    1626  static void
    1627  dont_reach (gpointer instance, gpointer data)
    1628  {
    1629    g_assert_not_reached ();
    1630  }
    1631  
    1632  static void
    1633  test_stop_emission (void)
    1634  {
    1635    GObject *test1;
    1636    gulong handler;
    1637  
    1638    test1 = g_object_new (test_get_type (), NULL);
    1639    handler = g_signal_connect (test1, "simple", G_CALLBACK (stop_emission), NULL);
    1640    g_signal_connect_after (test1, "simple", G_CALLBACK (dont_reach), NULL);
    1641  
    1642    g_signal_emit_by_name (test1, "simple");
    1643  
    1644    g_signal_handler_disconnect (test1, handler);
    1645    g_signal_connect (test1, "simple", G_CALLBACK (stop_emission_by_name), NULL);
    1646  
    1647    g_signal_emit_by_name (test1, "simple");
    1648  
    1649    g_object_unref (test1);
    1650  }
    1651  
    1652  static void
    1653  test_signal_disconnect_wrong_object (void)
    1654  {
    1655    Test *object, *object2;
    1656    Test2 *object3;
    1657    guint signal_id;
    1658  
    1659    object = g_object_new (test_get_type (), NULL);
    1660    object2 = g_object_new (test_get_type (), NULL);
    1661    object3 = g_object_new (test2_get_type (), NULL);
    1662  
    1663    signal_id = g_signal_connect (object,
    1664                                  "simple",
    1665                                  G_CALLBACK (simple_handler1),
    1666                                  NULL);
    1667  
    1668    /* disconnect from the wrong object (same type), should warn */
    1669    g_test_expect_message ("GLib-GObject", G_LOG_LEVEL_CRITICAL,
    1670                           "*: instance '*' has no handler with id '*'");
    1671    g_signal_handler_disconnect (object2, signal_id);
    1672    g_test_assert_expected_messages ();
    1673  
    1674    /* and from an object of the wrong type */
    1675    g_test_expect_message ("GLib-GObject", G_LOG_LEVEL_CRITICAL,
    1676                           "*: instance '*' has no handler with id '*'");
    1677    g_signal_handler_disconnect (object3, signal_id);
    1678    g_test_assert_expected_messages ();
    1679  
    1680    /* it's still connected */
    1681    g_assert_true (g_signal_handler_is_connected (object, signal_id));
    1682  
    1683    g_object_unref (object);
    1684    g_object_unref (object2);
    1685    g_object_unref (object3);
    1686  }
    1687  
    1688  static void
    1689  test_clear_signal_handler (void)
    1690  {
    1691    GObject *test_obj;
    1692    gulong handler;
    1693  
    1694    test_obj = g_object_new (test_get_type (), NULL);
    1695  
    1696    handler = g_signal_connect (test_obj, "simple", G_CALLBACK (dont_reach), NULL);
    1697    g_assert_cmpuint (handler, >, 0);
    1698  
    1699    g_clear_signal_handler (&handler, test_obj);
    1700    g_assert_cmpuint (handler, ==, 0);
    1701  
    1702    g_signal_emit_by_name (test_obj, "simple");
    1703  
    1704    g_clear_signal_handler (&handler, test_obj);
    1705  
    1706    if (g_test_undefined ())
    1707      {
    1708        handler = g_random_int_range (0x01, 0xFF);
    1709        g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
    1710                               "*instance '* has no handler with id *'");
    1711        g_clear_signal_handler (&handler, test_obj);
    1712        g_assert_cmpuint (handler, ==, 0);
    1713        g_test_assert_expected_messages ();
    1714      }
    1715  
    1716    g_object_unref (test_obj);
    1717  }
    1718  
    1719  static void
    1720  test_lookup (void)
    1721  {
    1722    GTypeClass *test_class;
    1723    guint signal_id, saved_signal_id;
    1724  
    1725    g_test_summary ("Test that g_signal_lookup() works with a variety of inputs.");
    1726  
    1727    test_class = g_type_class_ref (test_get_type ());
    1728  
    1729    signal_id = g_signal_lookup ("all-types", test_get_type ());
    1730    g_assert_cmpint (signal_id, !=, 0);
    1731  
    1732    saved_signal_id = signal_id;
    1733  
    1734    /* Try with a non-canonical name. */
    1735    signal_id = g_signal_lookup ("all_types", test_get_type ());
    1736    g_assert_cmpint (signal_id, ==, saved_signal_id);
    1737  
    1738    /* Looking up a non-existent signal should return nothing. */
    1739    g_assert_cmpint (g_signal_lookup ("nope", test_get_type ()), ==, 0);
    1740  
    1741    g_type_class_unref (test_class);
    1742  }
    1743  
    1744  static void
    1745  test_lookup_invalid (void)
    1746  {
    1747    g_test_summary ("Test that g_signal_lookup() emits a warning if looking up an invalid signal name.");
    1748  
    1749    if (g_test_subprocess ())
    1750      {
    1751        GTypeClass *test_class;
    1752        guint signal_id;
    1753  
    1754        test_class = g_type_class_ref (test_get_type ());
    1755  
    1756        signal_id = g_signal_lookup ("", test_get_type ());
    1757        g_assert_cmpint (signal_id, ==, 0);
    1758  
    1759        g_type_class_unref (test_class);
    1760        return;
    1761      }
    1762  
    1763    g_test_trap_subprocess (NULL, 0, G_TEST_SUBPROCESS_DEFAULT);
    1764    g_test_trap_assert_failed ();
    1765    g_test_trap_assert_stderr ("*CRITICAL*unable to look up invalid signal name*");
    1766  }
    1767  
    1768  static void
    1769  test_parse_name (void)
    1770  {
    1771    GTypeClass *test_class;
    1772    guint signal_id, saved_signal_id;
    1773    gboolean retval;
    1774    GQuark detail, saved_detail;
    1775  
    1776    g_test_summary ("Test that g_signal_parse_name() works with a variety of inputs.");
    1777  
    1778    test_class = g_type_class_ref (test_get_type ());
    1779  
    1780    /* Simple test. */
    1781    retval = g_signal_parse_name ("simple-detailed", test_get_type (), &signal_id, &detail, TRUE);
    1782    g_assert_true (retval);
    1783    g_assert_cmpint (signal_id, !=, 0);
    1784    g_assert_cmpint (detail, ==, 0);
    1785  
    1786    saved_signal_id = signal_id;
    1787  
    1788    /* Simple test with detail. */
    1789    retval = g_signal_parse_name ("simple-detailed::a-detail", test_get_type (), &signal_id, &detail, TRUE);
    1790    g_assert_true (retval);
    1791    g_assert_cmpint (signal_id, ==, saved_signal_id);
    1792    g_assert_cmpint (detail, !=, 0);
    1793  
    1794    saved_detail = detail;
    1795  
    1796    /* Simple test with the same detail again. */
    1797    retval = g_signal_parse_name ("simple-detailed::a-detail", test_get_type (), &signal_id, &detail, FALSE);
    1798    g_assert_true (retval);
    1799    g_assert_cmpint (signal_id, ==, saved_signal_id);
    1800    g_assert_cmpint (detail, ==, saved_detail);
    1801  
    1802    /* Simple test with a new detail. */
    1803    retval = g_signal_parse_name ("simple-detailed::another-detail", test_get_type (), &signal_id, &detail, FALSE);
    1804    g_assert_true (retval);
    1805    g_assert_cmpint (signal_id, ==, saved_signal_id);
    1806    g_assert_cmpint (detail, ==, 0);  /* we didn’t force the quark */
    1807  
    1808    /* Canonicalisation shouldn’t affect the results. */
    1809    retval = g_signal_parse_name ("simple_detailed::a-detail", test_get_type (), &signal_id, &detail, FALSE);
    1810    g_assert_true (retval);
    1811    g_assert_cmpint (signal_id, ==, saved_signal_id);
    1812    g_assert_cmpint (detail, ==, saved_detail);
    1813  
    1814    /* Details don’t have to look like property names. */
    1815    retval = g_signal_parse_name ("simple-detailed::hello::world", test_get_type (), &signal_id, &detail, TRUE);
    1816    g_assert_true (retval);
    1817    g_assert_cmpint (signal_id, ==, saved_signal_id);
    1818    g_assert_cmpint (detail, !=, 0);
    1819  
    1820    /* Trying to parse a detail for a signal which isn’t %G_SIGNAL_DETAILED should fail. */
    1821    retval = g_signal_parse_name ("all-types::a-detail", test_get_type (), &signal_id, &detail, FALSE);
    1822    g_assert_false (retval);
    1823  
    1824    g_type_class_unref (test_class);
    1825  }
    1826  
    1827  static void
    1828  test_parse_name_invalid (void)
    1829  {
    1830    GTypeClass *test_class;
    1831    gsize i;
    1832    guint signal_id;
    1833    GQuark detail;
    1834    const gchar *vectors[] =
    1835      {
    1836        "",
    1837        "7zip",
    1838        "invalid:signal",
    1839        "simple-detailed::",
    1840        "simple-detailed:",
    1841        ":",
    1842        "::",
    1843        ":valid-detail",
    1844        "::valid-detail",
    1845      };
    1846  
    1847    g_test_summary ("Test that g_signal_parse_name() ignores a variety of invalid inputs.");
    1848  
    1849    test_class = g_type_class_ref (test_get_type ());
    1850  
    1851    for (i = 0; i < G_N_ELEMENTS (vectors); i++)
    1852      {
    1853        g_test_message ("Parser input: %s", vectors[i]);
    1854        g_assert_false (g_signal_parse_name (vectors[i], test_get_type (), &signal_id, &detail, TRUE));
    1855      }
    1856  
    1857    g_type_class_unref (test_class);
    1858  }
    1859  
    1860  static void
    1861  test_signals_invalid_name (gconstpointer test_data)
    1862  {
    1863    const gchar *signal_name = test_data;
    1864  
    1865    g_test_summary ("Check that g_signal_new() rejects invalid signal names.");
    1866  
    1867    if (g_test_subprocess ())
    1868      {
    1869        g_signal_new (signal_name,
    1870                      test_get_type (),
    1871                      G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE,
    1872                      0,
    1873                      NULL, NULL,
    1874                      NULL,
    1875                      G_TYPE_NONE,
    1876                      0);
    1877        return;
    1878      }
    1879  
    1880    g_test_trap_subprocess (NULL, 0, G_TEST_SUBPROCESS_DEFAULT);
    1881    g_test_trap_assert_failed ();
    1882    g_test_trap_assert_stderr ("*CRITICAL*g_signal_is_valid_name (signal_name)*");
    1883  }
    1884  
    1885  static void
    1886  test_signal_is_valid_name (void)
    1887  {
    1888    const gchar *valid_names[] =
    1889      {
    1890        "signal",
    1891        "i",
    1892        "multiple-segments",
    1893        "segment0-SEGMENT1",
    1894        "using_underscores",
    1895      };
    1896    const gchar *invalid_names[] =
    1897      {
    1898        "",
    1899        "7zip",
    1900        "my_int:hello",
    1901      };
    1902    gsize i;
    1903  
    1904    for (i = 0; i < G_N_ELEMENTS (valid_names); i++)
    1905      g_assert_true (g_signal_is_valid_name (valid_names[i]));
    1906  
    1907    for (i = 0; i < G_N_ELEMENTS (invalid_names); i++)
    1908      g_assert_false (g_signal_is_valid_name (invalid_names[i]));
    1909  }
    1910  
    1911  static void
    1912  test_emitv (void)
    1913  {
    1914    GArray *values;
    1915    GObject *test;
    1916    GValue return_value = G_VALUE_INIT;
    1917    gint count = 0;
    1918    guint signal_id;
    1919    gulong hook;
    1920    gulong id;
    1921  
    1922    test = g_object_new (test_get_type (), NULL);
    1923  
    1924    values = g_array_new (TRUE, TRUE, sizeof (GValue));
    1925    g_array_set_clear_func (values, (GDestroyNotify) g_value_unset);
    1926  
    1927    g_array_set_size (values, 1);
    1928    g_value_init (&g_array_index (values, GValue, 0), G_TYPE_OBJECT);
    1929    g_value_set_object (&g_array_index (values, GValue, 0), test);
    1930    hook = g_signal_add_emission_hook (simple_id, 0, hook_func, &count, NULL);
    1931    g_assert_cmpint (count, ==, 0);
    1932    g_signal_emitv ((GValue *) values->data, simple_id, 0, NULL);
    1933    g_assert_cmpint (count, ==, 1);
    1934    g_signal_remove_emission_hook (simple_id, hook);
    1935  
    1936    g_array_set_size (values, 20);
    1937    g_value_init (&g_array_index (values, GValue, 1), G_TYPE_INT);
    1938    g_value_set_int (&g_array_index (values, GValue, 1), 42);
    1939  
    1940    g_value_init (&g_array_index (values, GValue, 2), G_TYPE_BOOLEAN);
    1941    g_value_set_boolean (&g_array_index (values, GValue, 2), TRUE);
    1942  
    1943    g_value_init (&g_array_index (values, GValue, 3), G_TYPE_CHAR);
    1944    g_value_set_schar (&g_array_index (values, GValue, 3), 17);
    1945  
    1946    g_value_init (&g_array_index (values, GValue, 4), G_TYPE_UCHAR);
    1947    g_value_set_uchar (&g_array_index (values, GValue, 4), 140);
    1948  
    1949    g_value_init (&g_array_index (values, GValue, 5), G_TYPE_UINT);
    1950    g_value_set_uint (&g_array_index (values, GValue, 5), G_MAXUINT - 42);
    1951  
    1952    g_value_init (&g_array_index (values, GValue, 6), G_TYPE_LONG);
    1953    g_value_set_long (&g_array_index (values, GValue, 6), -1117);
    1954  
    1955    g_value_init (&g_array_index (values, GValue, 7), G_TYPE_ULONG);
    1956    g_value_set_ulong (&g_array_index (values, GValue, 7), G_MAXULONG - 999);
    1957  
    1958    g_value_init (&g_array_index (values, GValue, 8), enum_type);
    1959    g_value_set_enum (&g_array_index (values, GValue, 8), MY_ENUM_VALUE);
    1960  
    1961    g_value_init (&g_array_index (values, GValue, 9), flags_type);
    1962    g_value_set_flags (&g_array_index (values, GValue, 9),
    1963                       MY_FLAGS_FIRST_BIT | MY_FLAGS_THIRD_BIT | MY_FLAGS_LAST_BIT);
    1964  
    1965    g_value_init (&g_array_index (values, GValue, 10), G_TYPE_FLOAT);
    1966    g_value_set_float (&g_array_index (values, GValue, 10), 0.25);
    1967  
    1968    g_value_init (&g_array_index (values, GValue, 11), G_TYPE_DOUBLE);
    1969    g_value_set_double (&g_array_index (values, GValue, 11), 1.5);
    1970  
    1971    g_value_init (&g_array_index (values, GValue, 12), G_TYPE_STRING);
    1972    g_value_set_string (&g_array_index (values, GValue, 12), "Test");
    1973  
    1974    g_value_init (&g_array_index (values, GValue, 13), G_TYPE_PARAM_LONG);
    1975    g_value_take_param (&g_array_index (values, GValue, 13),
    1976                        g_param_spec_long	 ("param", "nick", "blurb", 0, 10, 4, 0));
    1977  
    1978    g_value_init (&g_array_index (values, GValue, 14), G_TYPE_BYTES);
    1979    g_value_take_boxed (&g_array_index (values, GValue, 14),
    1980                        g_bytes_new_static ("Blah", 5));
    1981  
    1982    g_value_init (&g_array_index (values, GValue, 15), G_TYPE_POINTER);
    1983    g_value_set_pointer (&g_array_index (values, GValue, 15), &enum_type);
    1984  
    1985    g_value_init (&g_array_index (values, GValue, 16), test_get_type ());
    1986    g_value_set_object (&g_array_index (values, GValue, 16), test);
    1987  
    1988    g_value_init (&g_array_index (values, GValue, 17), G_TYPE_VARIANT);
    1989    g_value_take_variant (&g_array_index (values, GValue, 17),
    1990                          g_variant_ref_sink (g_variant_new_uint16 (99)));
    1991  
    1992    g_value_init (&g_array_index (values, GValue, 18), G_TYPE_INT64);
    1993    g_value_set_int64 (&g_array_index (values, GValue, 18), G_MAXINT64 - 1234);
    1994  
    1995    g_value_init (&g_array_index (values, GValue, 19), G_TYPE_UINT64);
    1996    g_value_set_uint64 (&g_array_index (values, GValue, 19), G_MAXUINT64 - 123456);
    1997  
    1998    id = g_signal_connect (test, "all-types", G_CALLBACK (all_types_handler_cb), &flags_type);
    1999    signal_id = g_signal_lookup ("all-types", test_get_type ());
    2000    g_assert_cmpuint (signal_id, >, 0);
    2001  
    2002    count = 0;
    2003    hook = g_signal_add_emission_hook (signal_id, 0, hook_func, &count, NULL);
    2004    g_assert_cmpint (count, ==, 0);
    2005    g_signal_emitv ((GValue *) values->data, signal_id, 0, NULL);
    2006    g_assert_cmpint (count, ==, 1);
    2007    g_signal_remove_emission_hook (signal_id, hook);
    2008    g_clear_signal_handler (&id, test);
    2009  
    2010  
    2011    signal_id = g_signal_lookup ("generic-marshaller-int-return", test_get_type ());
    2012    g_assert_cmpuint (signal_id, >, 0);
    2013    g_array_set_size (values, 1);
    2014  
    2015    id = g_signal_connect (test,
    2016                           "generic-marshaller-int-return",
    2017                           G_CALLBACK (on_generic_marshaller_int_return_signed_1),
    2018                           NULL);
    2019  
    2020    count = 0;
    2021    hook = g_signal_add_emission_hook (signal_id, 0, hook_func, &count, NULL);
    2022    g_assert_cmpint (count, ==, 0);
    2023    g_value_init (&return_value, G_TYPE_INT);
    2024    g_signal_emitv ((GValue *) values->data, signal_id, 0, &return_value);
    2025    g_assert_cmpint (count, ==, 1);
    2026    g_assert_cmpint (g_value_get_int (&return_value), ==, -30);
    2027    g_signal_remove_emission_hook (signal_id, hook);
    2028    g_clear_signal_handler (&id, test);
    2029  
    2030  #ifdef G_ENABLE_DEBUG
    2031    g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
    2032                           "*return*value*generic-marshaller-int-return*NULL*");
    2033    g_signal_emitv ((GValue *) values->data, signal_id, 0, NULL);
    2034    g_test_assert_expected_messages ();
    2035  
    2036    g_value_unset (&return_value);
    2037    g_value_init (&return_value, G_TYPE_FLOAT);
    2038    g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
    2039                           "*return*value*generic-marshaller-int-return*gfloat*");
    2040    g_signal_emitv ((GValue *) values->data, signal_id, 0, &return_value);
    2041    g_test_assert_expected_messages ();
    2042  #endif
    2043  
    2044    g_object_unref (test);
    2045    g_array_unref (values);
    2046  }
    2047  
    2048  typedef struct
    2049  {
    2050    GWeakRef wr;
    2051    gulong handler;
    2052  } TestWeakRefDisconnect;
    2053  
    2054  static void
    2055  weak_ref_disconnect_notify (gpointer  data,
    2056                              GObject  *where_object_was)
    2057  {
    2058    TestWeakRefDisconnect *state = data;
    2059    g_assert_null (g_weak_ref_get (&state->wr));
    2060    state->handler = 0;
    2061  }
    2062  
    2063  static void
    2064  test_weak_ref_disconnect (void)
    2065  {
    2066    TestWeakRefDisconnect state;
    2067    GObject *test;
    2068  
    2069    test = g_object_new (test_get_type (), NULL);
    2070    g_weak_ref_init (&state.wr, test);
    2071    state.handler = g_signal_connect_data (test,
    2072                                           "simple",
    2073                                           G_CALLBACK (dont_reach),
    2074                                           &state,
    2075                                           (GClosureNotify) weak_ref_disconnect_notify,
    2076                                           0);
    2077    g_assert_cmpint (state.handler, >, 0);
    2078  
    2079    g_object_unref (test);
    2080  
    2081    g_assert_cmpint (state.handler, ==, 0);
    2082    g_assert_null (g_weak_ref_get (&state.wr));
    2083    g_weak_ref_clear (&state.wr);
    2084  }
    2085  
    2086  /* --- */
    2087  
    2088  int
    2089  main (int argc,
    2090       char *argv[])
    2091  {
    2092    g_test_init (&argc, &argv, NULL);
    2093  
    2094    g_test_add_func ("/gobject/signals/all-types", test_all_types);
    2095    g_test_add_func ("/gobject/signals/variant", test_variant_signal);
    2096    g_test_add_func ("/gobject/signals/destroy-target-object", test_destroy_target_object);
    2097    g_test_add_func ("/gobject/signals/generic-marshaller-1", test_generic_marshaller_signal_1);
    2098    g_test_add_func ("/gobject/signals/generic-marshaller-2", test_generic_marshaller_signal_2);
    2099    g_test_add_func ("/gobject/signals/generic-marshaller-enum-return-signed", test_generic_marshaller_signal_enum_return_signed);
    2100    g_test_add_func ("/gobject/signals/generic-marshaller-enum-return-unsigned", test_generic_marshaller_signal_enum_return_unsigned);
    2101    g_test_add_func ("/gobject/signals/generic-marshaller-int-return", test_generic_marshaller_signal_int_return);
    2102    g_test_add_func ("/gobject/signals/generic-marshaller-uint-return", test_generic_marshaller_signal_uint_return);
    2103    g_test_add_func ("/gobject/signals/generic-marshaller-interface-return", test_generic_marshaller_signal_interface_return);
    2104    g_test_add_func ("/gobject/signals/custom-marshaller", test_custom_marshaller);
    2105    g_test_add_func ("/gobject/signals/connect", test_connect);
    2106    g_test_add_func ("/gobject/signals/emission-hook", test_emission_hook);
    2107    g_test_add_func ("/gobject/signals/emitv", test_emitv);
    2108    g_test_add_func ("/gobject/signals/accumulator", test_accumulator);
    2109    g_test_add_func ("/gobject/signals/accumulator-class", test_accumulator_class);
    2110    g_test_add_func ("/gobject/signals/introspection", test_introspection);
    2111    g_test_add_func ("/gobject/signals/block-handler", test_block_handler);
    2112    g_test_add_func ("/gobject/signals/stop-emission", test_stop_emission);
    2113    g_test_add_func ("/gobject/signals/invocation-hint", test_invocation_hint);
    2114    g_test_add_func ("/gobject/signals/test-disconnection-wrong-object", test_signal_disconnect_wrong_object);
    2115    g_test_add_func ("/gobject/signals/clear-signal-handler", test_clear_signal_handler);
    2116    g_test_add_func ("/gobject/signals/lookup", test_lookup);
    2117    g_test_add_func ("/gobject/signals/lookup/invalid", test_lookup_invalid);
    2118    g_test_add_func ("/gobject/signals/parse-name", test_parse_name);
    2119    g_test_add_func ("/gobject/signals/parse-name/invalid", test_parse_name_invalid);
    2120    g_test_add_data_func ("/gobject/signals/invalid-name/colon", "my_int:hello", test_signals_invalid_name);
    2121    g_test_add_data_func ("/gobject/signals/invalid-name/first-char", "7zip", test_signals_invalid_name);
    2122    g_test_add_data_func ("/gobject/signals/invalid-name/empty", "", test_signals_invalid_name);
    2123    g_test_add_func ("/gobject/signals/is-valid-name", test_signal_is_valid_name);
    2124    g_test_add_func ("/gobject/signals/weak-ref-disconnect", test_weak_ref_disconnect);
    2125  
    2126    return g_test_run ();
    2127  }