Add gobject introspection
[profile/ivi/GUPnP.git] / libgupnp / gupnp-device.c
1 /*
2  * Copyright (C) 2007 OpenedHand Ltd.
3  *
4  * Author: Jorn Baayen <jorn@openedhand.com>
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Library General Public
8  * License as published by the Free Software Foundation; either
9  * version 2 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Library General Public License for more details.
15  *
16  * You should have received a copy of the GNU Library General Public
17  * License along with this library; if not, write to the
18  * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19  * Boston, MA 02110-1301, USA.
20  */
21
22 /**
23  * SECTION:gupnp-device
24  * @short_description: Class for device implementations.
25  *
26  * #GUPnPDevice allows for retrieving a device's subdevices
27  * and services. #GUPnPDevice implements the #GUPnPDeviceInfo
28  * interface.
29  */
30
31 #include <string.h>
32
33 #include "gupnp-device.h"
34 #include "gupnp-service.h"
35 #include "gupnp-root-device.h"
36 #include "gupnp-resource-factory-private.h"
37 #include "xml-util.h"
38
39 G_DEFINE_TYPE (GUPnPDevice,
40                gupnp_device,
41                GUPNP_TYPE_DEVICE_INFO);
42
43 struct _GUPnPDevicePrivate {
44         GUPnPRootDevice *root_device;
45 };
46
47 enum {
48         PROP_0,
49         PROP_ROOT_DEVICE
50 };
51
52 static GUPnPDeviceInfo *
53 gupnp_device_get_device (GUPnPDeviceInfo *info,
54                          xmlNode         *element)
55 {
56         GUPnPDevice          *device;
57         GUPnPResourceFactory *factory;
58         GUPnPContext         *context;
59         GUPnPDevice          *root_device;
60         const char           *location;
61         const SoupURI        *url_base;
62
63         device = GUPNP_DEVICE (info);
64
65         root_device = GUPNP_IS_ROOT_DEVICE (device) ? device :
66                       GUPNP_DEVICE (device->priv->root_device);
67         if (root_device == NULL) {
68                 g_warning ("Root device not found.");
69
70                 return NULL;
71         }
72
73         factory = gupnp_device_info_get_resource_factory (info);
74         context = gupnp_device_info_get_context (info);
75         location = gupnp_device_info_get_location (info);
76         url_base = gupnp_device_info_get_url_base (info);
77
78         device = gupnp_resource_factory_create_device (factory,
79                                                        context,
80                                                        root_device,
81                                                        element,
82                                                        NULL,
83                                                        location,
84                                                        url_base);
85
86         return GUPNP_DEVICE_INFO (device);
87 }
88
89 static GUPnPServiceInfo *
90 gupnp_device_get_service (GUPnPDeviceInfo *info,
91                           xmlNode         *element)
92 {
93         GUPnPDevice          *device;
94         GUPnPService         *service;
95         GUPnPResourceFactory *factory;
96         GUPnPContext         *context;
97         GUPnPDevice          *root_device;
98         const char           *location, *udn;
99         const SoupURI        *url_base;
100
101         device = GUPNP_DEVICE (info);
102
103         root_device = GUPNP_IS_ROOT_DEVICE (device) ? device :
104                       GUPNP_DEVICE (device->priv->root_device);
105         if (root_device == NULL) {
106                 g_warning ("Root device not found.");
107
108                 return NULL;
109         }
110
111         factory = gupnp_device_info_get_resource_factory (info);
112         context = gupnp_device_info_get_context (info);
113         udn = gupnp_device_info_get_udn (info);
114         location = gupnp_device_info_get_location (info);
115         url_base = gupnp_device_info_get_url_base (info);
116
117         service = gupnp_resource_factory_create_service (factory,
118                                                          context,
119                                                          root_device,
120                                                          element,
121                                                          udn,
122                                                          location,
123                                                          url_base);
124
125         return GUPNP_SERVICE_INFO (service);
126 }
127
128 static void
129 gupnp_device_set_property (GObject      *object,
130                            guint         property_id,
131                            const GValue *value,
132                            GParamSpec   *pspec)
133 {
134         GUPnPDevice *device;
135
136         device = GUPNP_DEVICE (object);
137
138         switch (property_id) {
139         case PROP_ROOT_DEVICE:
140                 device->priv->root_device = g_value_get_object (value);
141
142                 /* This can be NULL in which case *this* is the root device */
143                 if (device->priv->root_device) {
144                         GUPnPRootDevice **dev = &(device->priv->root_device);
145
146                         g_object_add_weak_pointer
147                                 (G_OBJECT (device->priv->root_device),
148                                  (gpointer *) dev);
149                 }
150
151                 break;
152         default:
153                 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
154                 break;
155         }
156 }
157
158 static void
159 gupnp_device_get_property (GObject    *object,
160                            guint       property_id,
161                            GValue     *value,
162                            GParamSpec *pspec)
163 {
164         GUPnPDevice *device;
165
166         device = GUPNP_DEVICE (object);
167
168         switch (property_id) {
169         case PROP_ROOT_DEVICE:
170                 g_value_set_object (value, device->priv->root_device);
171                 break;
172         default:
173                 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
174                 break;
175         }
176 }
177
178 static void
179 gupnp_device_dispose (GObject *object)
180 {
181         GUPnPDevice *device;
182         GObjectClass *object_class;
183
184         device = GUPNP_DEVICE (object);
185
186         if (device->priv->root_device) {
187                 GUPnPRootDevice **dev = &(device->priv->root_device);
188
189                 g_object_remove_weak_pointer
190                         (G_OBJECT (device->priv->root_device),
191                          (gpointer *) dev);
192
193                 device->priv->root_device = NULL;
194         }
195
196         /* Call super */
197         object_class = G_OBJECT_CLASS (gupnp_device_parent_class);
198         object_class->dispose (object);
199 }
200
201 static void
202 gupnp_device_init (GUPnPDevice *device)
203 {
204         device->priv = G_TYPE_INSTANCE_GET_PRIVATE (device,
205                                                     GUPNP_TYPE_DEVICE,
206                                                     GUPnPDevicePrivate);
207 }
208
209 static void
210 gupnp_device_class_init (GUPnPDeviceClass *klass)
211 {
212         GObjectClass *object_class;
213         GUPnPDeviceInfoClass *info_class;
214
215         object_class = G_OBJECT_CLASS (klass);
216
217         object_class->set_property = gupnp_device_set_property;
218         object_class->get_property = gupnp_device_get_property;
219         object_class->dispose      = gupnp_device_dispose;
220
221         info_class = GUPNP_DEVICE_INFO_CLASS (klass);
222
223         info_class->get_device  = gupnp_device_get_device;
224         info_class->get_service = gupnp_device_get_service;
225
226         g_type_class_add_private (klass, sizeof (GUPnPDevicePrivate));
227
228         /**
229          * GUPnPDevice:root-device:
230          *
231          * The containing #GUPnPRootDevice, or NULL if this is the root
232          * device.
233          **/
234         g_object_class_install_property
235                 (object_class,
236                  PROP_ROOT_DEVICE,
237                  g_param_spec_object ("root-device",
238                                       "Root device",
239                                       "The GUPnPRootDevice",
240                                       GUPNP_TYPE_ROOT_DEVICE,
241                                       G_PARAM_READWRITE |
242                                       G_PARAM_CONSTRUCT_ONLY |
243                                       G_PARAM_STATIC_NAME |
244                                       G_PARAM_STATIC_NICK |
245                                       G_PARAM_STATIC_BLURB));
246
247 }