summaryrefslogtreecommitdiff
path: root/gst/gstinterface.c
blob: 9e629e4d01cbdbd35226b7b60c794d04fcc0b40e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
/* GStreamer
 *
 * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
 *                    2000 Wim Taymans <wtay@chello.be>
 *
 * gstinterface.c: Interface functions
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 */

/**
 * SECTION:gstimplementsinterface
 * @short_description: Core interface implemented by #GstElement instances that
 * allows runtime querying of interface availabillity
 * @see_also: #GstElement
 *
 * Provides interface functionality on per instance basis and not per class
 * basis, which is the case for gobject.
 */

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include "gst_private.h"
#include "gstinterface.h"

static void
gst_implements_interface_class_init (GstImplementsInterfaceClass * ifklass);
static gboolean
gst_implements_interface_supported_default (GstImplementsInterface * iface,
    GType iface_type);

GType
gst_implements_interface_get_type (void)
{
  static volatile gsize gst_interface_type = 0;

  if (g_once_init_enter (&gst_interface_type)) {
    GType _type;
    static const GTypeInfo gst_interface_info = {
      sizeof (GstImplementsInterfaceClass),
      (GBaseInitFunc) gst_implements_interface_class_init,
      NULL,
      NULL,
      NULL,
      NULL,
      0,
      0,
      NULL,
      NULL
    };

    _type = g_type_register_static (G_TYPE_INTERFACE,
        "GstImplementsInterface", &gst_interface_info, 0);

    g_type_interface_add_prerequisite (_type, GST_TYPE_ELEMENT);
    g_once_init_leave (&gst_interface_type, _type);
  }

  return gst_interface_type;
}

static void
gst_implements_interface_class_init (GstImplementsInterfaceClass * klass)
{
  klass->supported = gst_implements_interface_supported_default;
}

static gboolean
gst_implements_interface_supported_default (GstImplementsInterface * interface,
    GType iface_type)
{
  /* Well, if someone didn't set the virtual function,
   * then something is clearly wrong. So big no-no here */

  return FALSE;
}

/**
 * gst_element_implements_interface:
 * @element: #GstElement to check for the implementation of the interface
 * @iface_type: (final) type of the interface which we want to be implemented
 *
 * Test whether the given element implements a certain interface of type
 * iface_type, and test whether it is supported for this specific instance.
 *
 * Returns: whether or not the element implements the interface.
 */

gboolean
gst_element_implements_interface (GstElement * element, GType iface_type)
{
  g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);

  if (G_TYPE_CHECK_INSTANCE_TYPE (G_OBJECT (element), iface_type)) {
    GstImplementsInterface *iface;
    GstImplementsInterfaceClass *ifclass;

    iface = G_TYPE_CHECK_INSTANCE_CAST (G_OBJECT (element),
        iface_type, GstImplementsInterface);
    ifclass = GST_IMPLEMENTS_INTERFACE_GET_CLASS (iface);

    /* element implements iface_type but not GstImplementsInterface, so
     * just assume the other interface is implemented unconditionally */
    if (ifclass == NULL)
      return TRUE;

    if (ifclass->supported != NULL &&
        ifclass->supported (iface, iface_type) == TRUE) {
      return TRUE;
    }
  }

  return FALSE;
}

/**
 * gst_implements_interface_cast:
 * @from: the object (any sort) from which to cast to the interface
 * @type: the interface type to cast to
 *
 * cast a given object to an interface type, and check whether this
 * interface is supported for this specific instance.
 *
 * Returns: a gpointer to the interface type
 */

gpointer
gst_implements_interface_cast (gpointer from, GType iface_type)
{
  GstImplementsInterface *iface;

  /* check cast, give warning+fail if it's invalid */
  if (!(iface = G_TYPE_CHECK_INSTANCE_CAST (from, iface_type,
              GstImplementsInterface))) {
    return NULL;
  }

  /* if we're an element, take care that this interface
   * is actually implemented */
  if (GST_IS_ELEMENT (from)) {
    g_return_val_if_fail (gst_element_implements_interface (GST_ELEMENT (from),
            iface_type), NULL);
  }

  return iface;
}

/**
 * gst_implements_interface_check:
 * @from: the object (any sort) from which to check from for the interface
 * @type: the interface type to check for
 *
 * check a given object for an interface implementation, and check
 * whether this interface is supported for this specific instance.
 *
 * Returns: whether or not the object implements the given interface
 */

gboolean
gst_implements_interface_check (gpointer from, GType type)
{
  /* check cast, return FALSE if it fails, don't give a warning... */
  if (!G_TYPE_CHECK_INSTANCE_TYPE (from, type)) {
    return FALSE;
  }

  /* now, if we're an element (or derivative), is this thing
   * actually implemented for real? */
  if (GST_IS_ELEMENT (from)) {
    if (!gst_element_implements_interface (GST_ELEMENT (from), type)) {
      return FALSE;
    }
  }

  return TRUE;
}