Example #1
0
    public static object Emit (Gst.GLib.Object o, string name, params object[] parameters) {
      SignalQuery query;
      IntPtr type = gstsharp_g_type_from_instance (o.Handle);
      GType gtype = new GType (type);
      string signal_name, signal_detail;
      uint signal_detail_quark = 0;
      int colon;

      colon = name.LastIndexOf ("::");

      if (colon == -1) {
        signal_name = name;
        signal_detail = String.Empty;
      } else {
        signal_name = name.Substring (0, colon);
        signal_detail = name.Substring (colon + 2);
      }

      GTypeSignalKey key = new GTypeSignalKey (gtype, signal_name);

      if (SignalEmitInfo[key] == null) {
        IntPtr native_string = Gst.GLib.Marshaller.StringToPtrGStrdup (signal_name);
        uint signal_id = g_signal_lookup (native_string, type);
        Gst.GLib.Marshaller.Free (native_string);

        if (signal_id == 0)
          throw new NotSupportedException (String.Format ("{0} has no signal of name {1}", o, name));
        GSignalQuery q = new GSignalQuery ();
        g_signal_query (signal_id, ref q);

        if (q.signal_id == 0)
          throw new NotSupportedException (String.Format ("{0} couldn't be queried for signal with name {1}", o, name));

        query = new SignalQuery ();

        query.signal_id = signal_id;
        query.signal_name = Gst.GLib.Marshaller.Utf8PtrToString (q.signal_name);
        query.itype = new GType (q.itype);
        query.signal_flags = q.signal_flags;
        query.return_type = new GType (q.return_type);
        query.n_params = q.n_params;
        query.param_types = new Type[q.n_params];

        for (int i = 0; i < query.n_params; i++) {
          IntPtr t = Marshal.ReadIntPtr (q.param_types, i);
          GType g = new GType (t);

          query.param_types[i] = (Type) g;
        }

        SignalEmitInfo.Add (key, query);
      }

      query = (SignalQuery) SignalEmitInfo[key];
      Gst.GLib.Value[] signal_parameters = new Gst.GLib.Value[query.n_params + 1];
      signal_parameters[0] = new Gst.GLib.Value (o);

      if (parameters.Length != query.n_params)
        throw new ApplicationException (String.Format ("Invalid number of parameters: expected {0}, got {1}", query.n_params, parameters.Length));

      for (int i = 0; i < query.n_params; i++) {
        Type expected_type = (Type) query.param_types[i];
        Type given_type = parameters[i].GetType ();

        if (expected_type != given_type && ! given_type.IsSubclassOf (given_type))
          throw new ApplicationException (String.Format ("Invalid parameter type: expected {0}, got {1}", expected_type, given_type));

        signal_parameters[i + 1] = new Gst.GLib.Value (parameters[i]);
      }

      Gst.GLib.Value return_value = new Gst.GLib.Value ();
      if (query.return_type != GType.Invalid && query.return_type != GType.None)
        return_value.Init (query.return_type);

      if (signal_detail != String.Empty) {
        IntPtr native_string = Gst.GLib.Marshaller.StringToPtrGStrdup (signal_detail);
        signal_detail_quark = g_quark_from_string (native_string);
        Gst.GLib.Marshaller.Free (native_string);
      }

      g_signal_emitv (signal_parameters, query.signal_id, signal_detail_quark, ref return_value);

      foreach (Gst.GLib.Value v in signal_parameters)
        v.Dispose ();

      object ret = (query.return_type != GType.Invalid && query.return_type != GType.None) ? return_value.Val : null;

      if (ret != null)
        return_value.Dispose ();

      return ret;
    }