Add a quick utility to test datetime formatting
[platform/upstream/glib.git] / gio / gdbusobjectproxy.c
1 /* GDBus - GLib D-Bus Library
2  *
3  * Copyright (C) 2008-2010 Red Hat, Inc.
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General
16  * Public License along with this library; if not, write to the
17  * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
18  * Boston, MA 02111-1307, USA.
19  *
20  * Author: David Zeuthen <davidz@redhat.com>
21  */
22
23 #include "config.h"
24
25 #include "gdbusobject.h"
26 #include "gdbusobjectproxy.h"
27 #include "gdbusconnection.h"
28 #include "gdbusprivate.h"
29 #include "gdbusutils.h"
30 #include "gdbusproxy.h"
31
32 #include "glibintl.h"
33
34 /**
35  * SECTION:gdbusobjectproxy
36  * @short_description: Client-side D-Bus object
37  * @include: gio/gio.h
38  *
39  * A #GDBusObjectProxy is an object used to represent a remote object
40  * with one or more D-Bus interfaces. Normally, you don't instantiate
41  * a #GDBusObjectProxy yourself - typically #GDBusObjectManagerClient
42  * is used to obtain it.
43  *
44  * Since: 2.30
45  */
46
47 struct _GDBusObjectProxyPrivate
48 {
49   GHashTable *map_name_to_iface;
50   gchar *object_path;
51   GDBusConnection *connection;
52 };
53
54 enum
55 {
56   PROP_0,
57   PROP_OBJECT_PATH,
58   PROP_CONNECTION
59 };
60
61 static void dbus_object_interface_init (GDBusObjectIface *iface);
62
63 G_DEFINE_TYPE_WITH_CODE (GDBusObjectProxy, g_dbus_object_proxy, G_TYPE_OBJECT,
64                          G_IMPLEMENT_INTERFACE (G_TYPE_DBUS_OBJECT, dbus_object_interface_init));
65
66 static void
67 g_dbus_object_proxy_finalize (GObject *object)
68 {
69   GDBusObjectProxy *proxy = G_DBUS_OBJECT_PROXY (object);
70
71   g_hash_table_unref (proxy->priv->map_name_to_iface);
72
73   if (G_OBJECT_CLASS (g_dbus_object_proxy_parent_class)->finalize != NULL)
74     G_OBJECT_CLASS (g_dbus_object_proxy_parent_class)->finalize (object);
75 }
76
77 static void
78 g_dbus_object_proxy_get_property (GObject    *object,
79                                   guint       prop_id,
80                                   GValue     *value,
81                                   GParamSpec *pspec)
82 {
83   GDBusObjectProxy *proxy = G_DBUS_OBJECT_PROXY (object);
84
85   switch (prop_id)
86     {
87     case PROP_OBJECT_PATH:
88       g_value_set_string (value, proxy->priv->object_path);
89       break;
90
91     case PROP_CONNECTION:
92       g_value_set_object (value, g_dbus_object_proxy_get_connection (proxy));
93       break;
94
95     default:
96       G_OBJECT_WARN_INVALID_PROPERTY_ID (_object, prop_id, pspec);
97       break;
98     }
99 }
100
101 static void
102 g_dbus_object_proxy_set_property (GObject       *object,
103                                   guint          prop_id,
104                                   const GValue  *value,
105                                   GParamSpec    *pspec)
106 {
107   GDBusObjectProxy *proxy = G_DBUS_OBJECT_PROXY (object);
108
109   switch (prop_id)
110     {
111     case PROP_OBJECT_PATH:
112       proxy->priv->object_path = g_value_dup_string (value);
113       break;
114
115     case PROP_CONNECTION:
116       proxy->priv->connection = g_value_dup_object (value);
117       break;
118
119     default:
120       G_OBJECT_WARN_INVALID_PROPERTY_ID (_object, prop_id, pspec);
121       break;
122     }
123 }
124
125 static void
126 g_dbus_object_proxy_class_init (GDBusObjectProxyClass *klass)
127 {
128   GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
129
130   gobject_class->finalize     = g_dbus_object_proxy_finalize;
131   gobject_class->set_property = g_dbus_object_proxy_set_property;
132   gobject_class->get_property = g_dbus_object_proxy_get_property;
133
134   /**
135    * GDBusObjectProxy:object-path:
136    *
137    * The object path of the proxy.
138    *
139    * Since: 2.30
140    */
141   g_object_class_install_property (gobject_class,
142                                    PROP_OBJECT_PATH,
143                                    g_param_spec_string ("object-path",
144                                                         "Object Path",
145                                                         "The object path of the proxy",
146                                                         NULL,
147                                                         G_PARAM_READWRITE |
148                                                         G_PARAM_CONSTRUCT_ONLY |
149                                                         G_PARAM_STATIC_STRINGS));
150
151   /**
152    * GDBusObjectProxy:connection:
153    *
154    * The connection of the proxy.
155    *
156    * Since: 2.30
157    */
158   g_object_class_install_property (gobject_class,
159                                    PROP_CONNECTION,
160                                    g_param_spec_object ("connection",
161                                                         "Connection",
162                                                         "The connection of the proxy",
163                                                         G_TYPE_DBUS_CONNECTION,
164                                                         G_PARAM_READWRITE |
165                                                         G_PARAM_CONSTRUCT_ONLY |
166                                                         G_PARAM_STATIC_STRINGS));
167
168   g_type_class_add_private (klass, sizeof (GDBusObjectProxyPrivate));
169 }
170
171 static void
172 g_dbus_object_proxy_init (GDBusObjectProxy *proxy)
173 {
174   proxy->priv = G_TYPE_INSTANCE_GET_PRIVATE (proxy,
175                                              G_TYPE_DBUS_OBJECT_PROXY,
176                                              GDBusObjectProxyPrivate);
177   proxy->priv->map_name_to_iface = g_hash_table_new_full (g_str_hash,
178                                                           g_str_equal,
179                                                           g_free,
180                                                           (GDestroyNotify) g_object_unref);
181 }
182
183 static const gchar *
184 g_dbus_object_proxy_get_object_path (GDBusObject *object)
185 {
186   GDBusObjectProxy *proxy = G_DBUS_OBJECT_PROXY (object);
187   return proxy->priv->object_path;
188 }
189
190 /**
191  * g_dbus_object_proxy_get_connection:
192  * @proxy: a #GDBusObjectProxy
193  *
194  * Gets the connection that @proxy is for.
195  *
196  * Returns: (transfer none): A #GDBusConnection. Do not free, the
197  *   object is owned by @proxy.
198  *
199  * Since: 2.30
200  */
201 GDBusConnection *
202 g_dbus_object_proxy_get_connection (GDBusObjectProxy *proxy)
203 {
204   g_return_val_if_fail (G_IS_DBUS_OBJECT_PROXY (proxy), NULL);
205   return proxy->priv->connection;
206 }
207
208 static GDBusInterface *
209 g_dbus_object_proxy_get_interface (GDBusObject *object,
210                                    const gchar *interface_name)
211 {
212   GDBusObjectProxy *proxy = G_DBUS_OBJECT_PROXY (object);
213   GDBusProxy *ret;
214
215   g_return_val_if_fail (G_IS_DBUS_OBJECT_PROXY (proxy), NULL);
216   g_return_val_if_fail (g_dbus_is_interface_name (interface_name), NULL);
217
218   ret = g_hash_table_lookup (proxy->priv->map_name_to_iface, interface_name);
219   if (ret != NULL)
220     g_object_ref (ret);
221   return (GDBusInterface *) ret; /* TODO: proper cast */
222 }
223
224 static GList *
225 g_dbus_object_proxy_get_interfaces (GDBusObject *object)
226 {
227   GDBusObjectProxy *proxy = G_DBUS_OBJECT_PROXY (object);
228   GList *ret;
229   GHashTableIter iter;
230   GDBusProxy *interface_proxy;
231
232   g_return_val_if_fail (G_IS_DBUS_OBJECT_PROXY (proxy), NULL);
233
234   ret = NULL;
235
236   g_hash_table_iter_init (&iter, proxy->priv->map_name_to_iface);
237   while (g_hash_table_iter_next (&iter, NULL, (gpointer) &interface_proxy))
238     ret = g_list_prepend (ret, g_object_ref (interface_proxy));
239
240   return ret;
241 }
242
243 /* ---------------------------------------------------------------------------------------------------- */
244
245 /**
246  * g_dbus_object_proxy_new:
247  * @connection: a #GDBusConnection
248  * @object_path: the object path
249  *
250  * Creates a new #GDBusObjectProxy for the given connection and
251  * object path.
252  *
253  * Returns: a new #GDBusObjectProxy
254  *
255  * Since: 2.30
256  */
257 GDBusObjectProxy *
258 g_dbus_object_proxy_new (GDBusConnection *connection,
259                          const gchar     *object_path)
260 {
261   g_return_val_if_fail (G_IS_DBUS_CONNECTION (connection), NULL);
262   g_return_val_if_fail (g_variant_is_object_path (object_path), NULL);
263   return G_DBUS_OBJECT_PROXY (g_object_new (G_TYPE_DBUS_OBJECT_PROXY,
264                                             "object-path", object_path,
265                                             "connection", connection,
266                                             NULL));
267 }
268
269 void
270 _g_dbus_object_proxy_add_interface (GDBusObjectProxy *proxy,
271                                     GDBusProxy       *interface_proxy)
272 {
273   const gchar *interface_name;
274
275   g_return_if_fail (G_IS_DBUS_OBJECT_PROXY (proxy));
276   g_return_if_fail (G_IS_DBUS_PROXY (interface_proxy));
277
278   interface_name = g_dbus_proxy_get_interface_name (interface_proxy);
279   _g_dbus_object_proxy_remove_interface (proxy, interface_name);
280   g_hash_table_insert (proxy->priv->map_name_to_iface,
281                        g_strdup (interface_name),
282                        g_object_ref (interface_proxy));
283   g_signal_emit_by_name (proxy, "interface-added", interface_proxy);
284 }
285
286 void
287 _g_dbus_object_proxy_remove_interface (GDBusObjectProxy *proxy,
288                                        const gchar      *interface_name)
289 {
290   GDBusProxy *interface_proxy;
291
292   g_return_if_fail (G_IS_DBUS_OBJECT_PROXY (proxy));
293   g_return_if_fail (g_dbus_is_interface_name (interface_name));
294
295   interface_proxy = g_hash_table_lookup (proxy->priv->map_name_to_iface, interface_name);
296   if (interface_proxy != NULL)
297     {
298       g_object_ref (interface_proxy);
299       g_warn_if_fail (g_hash_table_remove (proxy->priv->map_name_to_iface, interface_name));
300       g_signal_emit_by_name (proxy, "interface-removed", interface_proxy);
301       g_object_unref (interface_proxy);
302     }
303 }
304
305 static void
306 dbus_object_interface_init (GDBusObjectIface *iface)
307 {
308   iface->get_object_path       = g_dbus_object_proxy_get_object_path;
309   iface->get_interfaces        = g_dbus_object_proxy_get_interfaces;
310   iface->get_interface         = g_dbus_object_proxy_get_interface;
311 }