a couple more ifdefs
[platform/upstream/gstreamer.git] / gst / gstobject.c
1 /* GStreamer
2  * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
3  *                    2000 Wim Taymans <wtay@chello.be>
4  *
5  * gstobject.c: Fundamental class used for all of GStreamer
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Library General Public
9  * License as published by the Free Software Foundation; either
10  * version 2 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Library General Public License for more details.
16  *
17  * You should have received a copy of the GNU Library General Public
18  * License along with this library; if not, write to the
19  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20  * Boston, MA 02111-1307, USA.
21  */
22
23 #include "gst_private.h"
24
25 #include "gstobject.h"
26
27 /* Object signals and args */
28 enum {
29   PARENT_SET,
30   DEEP_NOTIFY,
31 #ifndef GST_DISABLE_LOADSAVE_REGISTRY
32   OBJECT_SAVED,
33 #endif
34   LAST_SIGNAL
35 };
36
37 enum {
38   ARG_0,
39   ARG_NAME,
40   /* FILL ME */
41 };
42
43 enum {
44   SO_OBJECT_LOADED,
45   SO_LAST_SIGNAL
46 };
47
48 GType _gst_object_type = 0;
49
50 typedef struct _GstSignalObject GstSignalObject;
51 typedef struct _GstSignalObjectClass GstSignalObjectClass;
52
53 static GType            gst_signal_object_get_type      (void);
54 static void             gst_signal_object_class_init    (GstSignalObjectClass *klass);
55 static void             gst_signal_object_init          (GstSignalObject *object);
56
57 static guint gst_signal_object_signals[SO_LAST_SIGNAL] = { 0 };
58
59 static void             gst_object_class_init           (GstObjectClass *klass);
60 static void             gst_object_init                 (GstObject *object);
61
62 static void             gst_object_set_property         (GObject * object, guint prop_id, const GValue * value,
63                                                          GParamSpec * pspec);
64 static void             gst_object_get_property         (GObject * object, guint prop_id, GValue * value,
65                                                          GParamSpec * pspec);
66 static void             gst_object_dispatch_properties_changed (GObject * object, guint n_pspecs, GParamSpec **pspecs);
67
68 static void             gst_object_dispose              (GObject *object);
69 static void             gst_object_finalize             (GObject *object);
70
71 #ifndef GST_DISABLE_LOADSAVE_REGISTRY
72 static void             gst_object_real_restore_thyself (GstObject *object, xmlNodePtr self);
73 #endif
74
75 static GObjectClass *parent_class = NULL;
76 static guint gst_object_signals[LAST_SIGNAL] = { 0 };
77
78 GType
79 gst_object_get_type (void)
80 {
81   if (!_gst_object_type) {
82     static const GTypeInfo object_info = {
83       sizeof (GstObjectClass),
84       NULL,
85       NULL,
86       (GClassInitFunc) gst_object_class_init,
87       NULL,
88       NULL,
89       sizeof (GstObject),
90       32,
91       (GInstanceInitFunc) gst_object_init,
92       NULL
93     };
94     _gst_object_type = g_type_register_static (G_TYPE_OBJECT, "GstObject", &object_info, G_TYPE_FLAG_ABSTRACT);
95   }
96   return _gst_object_type;
97 }
98
99 static void
100 gst_object_class_init (GstObjectClass *klass)
101 {
102   GObjectClass *gobject_class;
103
104   gobject_class = (GObjectClass*) klass;
105
106   parent_class = g_type_class_ref (G_TYPE_OBJECT);
107
108   gobject_class->set_property = GST_DEBUG_FUNCPTR (gst_object_set_property);
109   gobject_class->get_property = GST_DEBUG_FUNCPTR (gst_object_get_property);
110   gobject_class->dispatch_properties_changed = GST_DEBUG_FUNCPTR (gst_object_dispatch_properties_changed);
111
112   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_NAME,
113     g_param_spec_string ("name", "Name", "The name of the object",
114                          NULL, G_PARAM_READWRITE));
115
116   gst_object_signals[PARENT_SET] =
117     g_signal_new ("parent_set", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
118                   G_STRUCT_OFFSET (GstObjectClass, parent_set), NULL, NULL,
119                   g_cclosure_marshal_VOID__OBJECT, G_TYPE_NONE, 1,
120                   G_TYPE_OBJECT);
121   gst_object_signals[DEEP_NOTIFY] =
122     g_signal_new ("deep_notify", G_TYPE_FROM_CLASS (klass), 
123                   G_SIGNAL_RUN_FIRST | G_SIGNAL_NO_RECURSE | G_SIGNAL_DETAILED | G_SIGNAL_NO_HOOKS,
124                   G_STRUCT_OFFSET (GstObjectClass, deep_notify), NULL, NULL,
125                   gst_marshal_VOID__OBJECT_PARAM, G_TYPE_NONE,
126                   2, G_TYPE_OBJECT, G_TYPE_PARAM);
127 #ifndef GST_DISABLE_LOADSAVE_REGISTRY
128   gst_object_signals[OBJECT_SAVED] =
129     g_signal_new ("object_saved", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
130                   G_STRUCT_OFFSET (GstObjectClass, object_saved), NULL, NULL,
131                   g_cclosure_marshal_VOID__POINTER, G_TYPE_NONE, 1,
132                   G_TYPE_POINTER);
133   
134   klass->restore_thyself = gst_object_real_restore_thyself;
135 #endif
136
137   klass->path_string_separator = "/";
138
139   klass->signal_object = g_object_new (gst_signal_object_get_type (), NULL);
140
141   gobject_class->dispose = gst_object_dispose;
142   gobject_class->finalize = gst_object_finalize;
143 }
144
145 static void
146 gst_object_init (GstObject *object)
147 {
148   object->lock = g_mutex_new();
149   object->parent = NULL;
150   object->name = NULL;
151
152   object->flags = 0;
153   GST_FLAG_SET (object, GST_FLOATING);
154 }
155
156 /**
157  * gst_object_ref:
158  * @object: GstObject to reference
159  *
160  * Increments the refence count on the object.
161  *
162  * Returns: A pointer to the object
163  */
164 GstObject*
165 gst_object_ref (GstObject *object)
166 {
167   g_return_val_if_fail (GST_IS_OBJECT (object), NULL);
168
169   GST_DEBUG (GST_CAT_REFCOUNTING, "ref '%s' %d->%d\n",GST_OBJECT_NAME(object),
170              G_OBJECT(object)->ref_count,G_OBJECT(object)->ref_count+1);
171
172   g_object_ref (G_OBJECT (object));
173   return object;
174 }
175 #define gst_object_ref gst_object_ref
176
177 /**
178  * gst_object_unref:
179  * @object: GstObject to unreference
180  *
181  * Decrements the refence count on the object.  If reference count hits
182  * zero, destroy the object.
183  */
184 void
185 gst_object_unref (GstObject *object)
186 {
187   g_return_if_fail (GST_IS_OBJECT (object));
188
189   GST_DEBUG (GST_CAT_REFCOUNTING, "unref '%s' %d->%d\n",GST_OBJECT_NAME(object),
190              G_OBJECT(object)->ref_count,G_OBJECT(object)->ref_count-1);
191
192   g_object_unref (G_OBJECT (object));
193 }
194 #define gst_object_unref gst_object_unref
195
196 /**
197  * gst_object_sink:
198  * @object: GstObject to sink
199  *
200  * Removes floating reference on an object.  Any newly created object has
201  * a refcount of 1 and is FLOATING.  This function should be used when
202  * creating a new object to symbolically 'take ownership of' the object.
203  */
204 void
205 gst_object_sink (GstObject *object)
206 {
207   g_return_if_fail (object != NULL);
208   g_return_if_fail (GST_IS_OBJECT (object));
209
210   GST_DEBUG (GST_CAT_REFCOUNTING, "sink '%s'\n",GST_OBJECT_NAME(object));
211   if (GST_OBJECT_FLOATING (object))
212   {
213     GST_FLAG_UNSET (object, GST_FLOATING);
214     gst_object_unref (object);
215   }
216 }
217
218 /**
219  * gst_object_destroy:
220  * @object: GstObject to destroy
221  *
222  * Destroy the object.
223  */
224 void
225 gst_object_destroy (GstObject *object)
226 {
227   g_return_if_fail (object != NULL);
228   g_return_if_fail (GST_IS_OBJECT (object));
229
230   GST_DEBUG (GST_CAT_REFCOUNTING, "destroy '%s'\n",GST_OBJECT_NAME(object));
231   if (!GST_OBJECT_DESTROYED (object))
232   {
233     /* need to hold a reference count around all class method
234      * invocations.
235      */
236     g_object_run_dispose (G_OBJECT (object));
237   }
238 }
239
240 static void
241 gst_object_dispose (GObject *object)
242 {
243   GST_DEBUG (GST_CAT_REFCOUNTING, "dispose '%s'\n",GST_OBJECT_NAME(object));
244   GST_FLAG_SET (GST_OBJECT (object), GST_DESTROYED);
245   GST_OBJECT_PARENT (object) = NULL;
246
247   parent_class->dispose (object);
248 }
249
250 /* finilize is called when the object has to free its resources */
251 static void
252 gst_object_finalize (GObject *object)
253 {
254   GstObject *gstobject = GST_OBJECT (object);
255
256   GST_DEBUG (GST_CAT_REFCOUNTING, "finalize '%s'\n",GST_OBJECT_NAME(object));
257
258   g_signal_handlers_destroy (object);
259
260   if (gstobject->name != NULL)
261     g_free (gstobject->name);
262
263   g_mutex_free (gstobject->lock);
264
265   parent_class->finalize (object);
266 }
267
268 /**
269  * gst_object_set_name:
270  * @object: GstObject to set the name of
271  * @name: new name of object
272  *
273  * Set the name of the object.
274  */
275 void
276 gst_object_set_name (GstObject *object, const gchar *name)
277 {
278   g_return_if_fail (object != NULL);
279   g_return_if_fail (GST_IS_OBJECT (object));
280   g_return_if_fail (name != NULL);
281
282   if (object->name != NULL)
283     g_free (object->name);
284
285   object->name = g_strdup (name);
286 }
287
288 /**
289  * gst_object_get_name:
290  * @object: GstObject to get the name of
291  *
292  * Get the name of the object.
293  *
294  * Returns: name of the object
295  */
296 const gchar*
297 gst_object_get_name (GstObject *object)
298 {
299   g_return_val_if_fail (object != NULL, NULL);
300   g_return_val_if_fail (GST_IS_OBJECT (object), NULL);
301
302   return object->name;
303 }
304
305 /**
306  * gst_object_set_parent:
307  * @object: GstObject to set parent of
308  * @parent: new parent of object
309  *
310  * Set the parent of the object.  The object's reference count is
311  * incremented.
312  * signals the parent-set signal
313  */
314 void
315 gst_object_set_parent (GstObject *object, GstObject *parent)
316 {
317   g_return_if_fail (object != NULL);
318   g_return_if_fail (GST_IS_OBJECT (object));
319   g_return_if_fail (parent != NULL);
320   g_return_if_fail (GST_IS_OBJECT (parent));
321   g_return_if_fail (object != parent);
322
323   if (object->parent != NULL) {
324     GST_ERROR_OBJECT (object,object->parent, "object's parent is already set, must unparent first");
325     return;
326   }
327
328   gst_object_ref (object);
329   gst_object_sink (object);
330   object->parent = parent;
331
332   g_signal_emit (G_OBJECT (object), gst_object_signals[PARENT_SET], 0, parent);
333 }
334
335 /**
336  * gst_object_get_parent:
337  * @object: GstObject to get parent of
338  *
339  * Return the parent of the object.
340  *
341  * Returns: parent of the object
342  */
343 GstObject*
344 gst_object_get_parent (GstObject *object)
345 {
346   g_return_val_if_fail (object != NULL, NULL);
347   g_return_val_if_fail (GST_IS_OBJECT (object), NULL);
348
349   return object->parent;
350 }
351
352 /**
353  * gst_object_unparent:
354  * @object: GstObject to unparent
355  *
356  * Clear the parent of the object, removing the associated reference.
357  */
358 void
359 gst_object_unparent (GstObject *object)
360 {
361   g_return_if_fail (object != NULL);
362   g_return_if_fail (GST_IS_OBJECT(object));
363   if (object->parent == NULL)
364     return;
365
366   GST_DEBUG (GST_CAT_REFCOUNTING, "unparent '%s'\n",GST_OBJECT_NAME(object));
367   
368   object->parent = NULL;
369   gst_object_unref (object);
370 }
371
372 /**
373  * gst_object_ref:
374  * @object: GstObject to reference
375  *
376  * Increments the refence count on the object.
377  *
378  * Returns: Apointer to the Object
379  */
380 #ifndef gst_object_ref
381 GstObject*
382 gst_object_ref (GstObject *object)
383 {
384   g_return_if_fail (object != NULL, NULL);
385   g_return_if_fail (GST_IS_OBJECT (object), NULL);
386
387 /* #ifdef HAVE_ATOMIC_H */
388 /*  g_return_if_fail (atomic_read (&(object->refcount)) > 0); */
389 /*  atomic_inc (&(object->refcount)) */
390 /* #else */
391   g_return_if_fail (object->refcount > 0);
392   GST_LOCK (object);
393 /*  object->refcount++; */
394   g_object_ref((GObject *)object);
395   GST_UNLOCK (object);
396 /* #endif */
397
398   return object;
399 }
400 #endif /* gst_object_ref */
401
402 /**
403  * gst_object_unref:
404  * @object: GstObject to unreference
405  *
406  * Decrements the refence count on the object.  If reference count hits
407  * zero, destroy the object.
408  */
409 #ifndef gst_object_unref
410 void
411 gst_object_unref (GstObject *object)
412 {
413   int reftest;
414
415   g_return_if_fail (object != NULL);
416   g_return_if_fail (GST_IS_OBJECT (object));
417
418 #ifdef HAVE_ATOMIC_H
419   g_return_if_fail (atomic_read (&(object->refcount)) > 0);
420   reftest = atomic_dec_and_test (&(object->refcount))
421 #else
422   g_return_if_fail (object->refcount > 0);
423   GST_LOCK (object);
424   object->refcount--;
425   reftest = (object->refcount == 0);
426   GST_UNLOCK (object);
427 #endif
428
429   /* if we ended up with the refcount at zero */
430   if (reftest) {
431     /* get the count to 1 for gtk_object_destroy() */
432 #ifdef HAVE_ATOMIC_H
433     atomic_set (&(object->refcount),1);
434 #else
435     object->refcount = 1;
436 #endif
437     /* destroy it */
438     gtk_object_destroy (G_OBJECT (object));
439     /* drop the refcount back to zero */
440 #ifdef HAVE_ATOMIC_H
441     atomic_set (&(object->refcount),0);
442 #else
443     object->refcount = 0;
444 #endif
445     /* finalize the object */
446     /* FIXME this is an evil hack that should be killed */
447 /* FIXMEFIXMEFIXMEFIXME */
448 /*    gtk_object_finalize(G_OBJECT(object)); */
449   }
450 }
451 #endif /* gst_object_unref */
452
453 /**
454  * gst_object_check_uniqueness:
455  * @list: a list of #GstObject to check through
456  * @name: the name to search for
457  *
458  * This function checks through the list of objects to see if the name
459  * given appears in the list as the name of an object.  It returns TRUE if
460  * the name does not exist in the list.
461  *
462  * Returns: TRUE if the name doesn't appear in the list, FALSE if it does.
463  */
464 gboolean
465 gst_object_check_uniqueness (GList *list, const gchar *name)
466 {
467   g_return_val_if_fail (name != NULL, FALSE);
468
469   while (list) {
470     GstObject *child = GST_OBJECT (list->data);
471
472     list = g_list_next(list);
473       
474     if (strcmp(GST_OBJECT_NAME(child), name) == 0) 
475       return FALSE;
476   }
477
478   return TRUE;
479 }
480
481
482 #ifndef GST_DISABLE_LOADSAVE_REGISTRY
483 /**
484  * gst_object_save_thyself:
485  * @object: GstObject to save
486  * @parent: The parent XML node to save the object into
487  *
488  * Saves the given object into the parent XML node.
489  *
490  * Returns: the new xmlNodePtr with the saved object
491  */
492 xmlNodePtr
493 gst_object_save_thyself (GstObject *object, xmlNodePtr parent)
494 {
495   GstObjectClass *oclass;
496
497   g_return_val_if_fail (object != NULL, parent);
498   g_return_val_if_fail (GST_IS_OBJECT (object), parent);
499   g_return_val_if_fail (parent != NULL, parent);
500
501   oclass = (GstObjectClass *)G_OBJECT_GET_CLASS(object);
502   if (oclass->save_thyself)
503     oclass->save_thyself (object, parent);
504
505   g_signal_emit (G_OBJECT (object), gst_object_signals[OBJECT_SAVED], 0, parent);
506
507   return parent;
508 }
509
510 /**
511  * gst_object_restore_thyself:
512  * @object: GstObject to load into
513  * @self: The XML node to load the object from
514  *
515  * Restores the given object with the data from the parent XML node.
516  */
517 void
518 gst_object_restore_thyself (GstObject *object, xmlNodePtr self)
519 {
520   GstObjectClass *oclass;
521
522   g_return_if_fail (object != NULL);
523   g_return_if_fail (GST_IS_OBJECT (object));
524   g_return_if_fail (self != NULL);
525
526   oclass = (GstObjectClass *) G_OBJECT_GET_CLASS(object);
527   if (oclass->restore_thyself)
528     oclass->restore_thyself (object, self);
529 }
530
531 static void
532 gst_object_real_restore_thyself (GstObject *object, xmlNodePtr self)
533 {
534   GstObjectClass *oclass;
535
536   g_return_if_fail (object != NULL);
537   g_return_if_fail (GST_IS_OBJECT (object));
538   g_return_if_fail (self != NULL);
539   
540 /* FIXME: the signalobject stuff doesn't work
541  *  gst_class_signal_emit_by_name (object, "object_loaded", self); */
542 }
543 #endif /* GST_DISABLE_LOADSAVE_REGISTRY */
544
545 static void
546 gst_object_set_property (GObject* object, guint prop_id, 
547                          const GValue* value, GParamSpec* pspec)
548 {
549   GstObject *gstobject;
550             
551   /* it's not null if we got it, but it might not be ours */
552   g_return_if_fail (GST_IS_OBJECT (object));
553               
554   gstobject = GST_OBJECT (object);
555
556   switch (prop_id) {
557     case ARG_NAME:
558       gst_object_set_name (gstobject, g_value_get_string (value));
559       break;
560     default:
561       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
562       break;
563   }
564 }
565
566 static void
567 gst_object_get_property (GObject* object, guint prop_id, 
568                          GValue* value, GParamSpec* pspec)
569 {
570   GstObject *gstobject;
571             
572   /* it's not null if we got it, but it might not be ours */
573   g_return_if_fail (GST_IS_OBJECT (object));
574               
575   gstobject = GST_OBJECT (object);
576
577   switch (prop_id) {
578     case ARG_NAME:
579       g_value_set_string (value, (gchar*)GST_OBJECT_NAME (gstobject));
580       break;
581     default:
582       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
583       break;
584   }
585 }
586 static void
587 gst_object_dispatch_properties_changed (GObject     *object,
588                                       guint        n_pspecs,
589                                       GParamSpec **pspecs)
590 {
591   GstObject *gst_object;
592   guint i;
593
594   /* do the standard dispatching */
595   parent_class->dispatch_properties_changed (object, n_pspecs, pspecs);
596
597   /* now let the parent dispatch those, too */
598   gst_object = GST_OBJECT (object);
599   while (gst_object)
600   {
601     /* need own category? */
602     GST_DEBUG (GST_CAT_EVENT, "deep notification from %s to %s\n", GST_OBJECT_NAME (object), GST_OBJECT_NAME (gst_object));
603     for (i = 0; i < n_pspecs; i++)
604       g_signal_emit (gst_object, gst_object_signals[DEEP_NOTIFY], g_quark_from_string (pspecs[i]->name), (GstObject *) object, pspecs[i]);
605
606     gst_object = GST_OBJECT_PARENT (gst_object);
607   }
608 }
609
610 /**
611  * gst_object_get_path_string:
612  * @object: GstObject to get the path from
613  *
614  * Generates a string describing the path of the object in
615  * the object hierarchy. Usefull for debugging
616  *
617  * Returns: a string describing the path of the object
618  */
619 gchar*
620 gst_object_get_path_string (GstObject *object)
621 {
622   GSList *parentage = NULL;
623   GSList *parents;
624   void *parent;
625   gchar *prevpath, *path;
626   const char *component;
627   gchar *separator = "";
628   gboolean free_component;
629
630   parentage = g_slist_prepend (NULL, object);
631
632   path = g_strdup ("");
633
634   /* first walk the object hierarchy to build a list of the parents */
635   do {
636     if (GST_IS_OBJECT (object)) {
637       parent = gst_object_get_parent (object);
638     } else {
639       parentage = g_slist_prepend (parentage, NULL);
640       parent = NULL;
641     }
642
643     if (parent != NULL) {
644       parentage = g_slist_prepend (parentage, parent);
645     }
646
647     object = parent;
648   } while (object != NULL);
649
650   /* then walk the parent list and print them out */
651   parents = parentage;
652   while (parents) {
653     if (GST_IS_OBJECT (parents->data)) {
654       GstObjectClass *oclass = (GstObjectClass *)G_OBJECT_GET_CLASS(parents->data);
655
656       component = gst_object_get_name (parents->data);
657       separator = oclass->path_string_separator;
658       free_component = FALSE;
659     } else {
660       component = g_strdup_printf("%p",parents->data);
661       separator = "/";
662       free_component = TRUE;
663     }
664
665     prevpath = path;
666     path = g_strjoin (separator, prevpath, component, NULL);
667     g_free(prevpath);
668     if (free_component)
669       g_free((gchar *)component);
670
671     parents = g_slist_next(parents);
672   }
673
674   g_slist_free (parentage);
675
676   return path;
677 }
678
679
680
681 struct _GstSignalObject {
682   GObject object;
683 };
684
685 struct _GstSignalObjectClass {
686   GObjectClass        parent_class;
687
688   /* signals */
689 #ifndef GST_DISABLE_LOADSAVE_REGISTRY
690   void          (*object_loaded)           (GstSignalObject *object, GstObject *new, xmlNodePtr self);
691 #endif /* GST_DISABLE_LOADSAVE_REGISTRY */
692 };
693
694 static GType
695 gst_signal_object_get_type (void)
696 {
697   static GType signal_object_type = 0;
698
699   if (!signal_object_type) {
700     static const GTypeInfo signal_object_info = {
701       sizeof(GstSignalObjectClass),
702       NULL,
703       NULL,
704       (GClassInitFunc)gst_signal_object_class_init,
705       NULL,
706       NULL,
707       sizeof(GstSignalObject),
708       16,
709       (GInstanceInitFunc)gst_signal_object_init,
710       NULL
711     };
712     signal_object_type = g_type_register_static(G_TYPE_OBJECT, "GstSignalObject", &signal_object_info, 0);
713   }
714   return signal_object_type;
715 }
716
717 static void
718 gst_signal_object_class_init (GstSignalObjectClass *klass)
719 {
720   GObjectClass *gobject_class;
721
722   gobject_class = (GObjectClass*) klass;
723
724   parent_class = g_type_class_ref (G_TYPE_OBJECT);
725
726 #ifndef GST_DISABLE_LOADSAVE_REGISTRY
727   gst_signal_object_signals[SO_OBJECT_LOADED] =
728     g_signal_new("object_loaded", G_TYPE_FROM_CLASS(klass), G_SIGNAL_RUN_LAST,
729                   G_STRUCT_OFFSET (GstObjectClass, parent_set), NULL, NULL,
730                   gst_marshal_VOID__OBJECT_POINTER,G_TYPE_NONE,2,
731                   G_TYPE_OBJECT,G_TYPE_POINTER);
732 #endif
733 }
734
735 static void
736 gst_signal_object_init (GstSignalObject *object)
737 {
738 }
739
740 /**
741  * gst_class_signal_connect
742  * @klass: the GstObjectClass to attach the signal to
743  * @name: the name of the signal to attach to
744  * @func: the signal function
745  * @func_data: a pointer to user data
746  *
747  * Connect to a class signal.
748  *
749  * Returns: the signal id.
750  */
751 guint
752 gst_class_signal_connect (GstObjectClass *klass,
753                           const gchar    *name,
754                           gpointer  func,
755                           gpointer       func_data)
756 {
757   return g_signal_connect (klass->signal_object, name, func, func_data);
758 }
759
760 #ifndef GST_DISABLE_LOADSAVE_REGISTRY
761 /**
762  * gst_class_signal_emit_by_name:
763  * @object: the object that sends the signal
764  * @name: the name of the signal to emit
765  * @self: data for the signal
766  *
767  * emits the named class signal.
768  */
769 void
770 gst_class_signal_emit_by_name (GstObject *object,
771                                const gchar *name,
772                                xmlNodePtr self)
773 {
774   GstObjectClass *oclass;
775
776   oclass = (GstObjectClass *)G_OBJECT_GET_CLASS(object);
777
778   g_signal_emit_by_name (oclass->signal_object, name, object, self);
779 }
780
781 #endif /* GST_DISABLE_LOADSAVE_REGISTRY */