1 /* GDBus - GLib D-Bus Library
2 *
3 * Copyright (C) 2008-2010 Red Hat, Inc.
4 *
5 * SPDX-License-Identifier: LGPL-2.1-or-later
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 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 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General
18 * Public License along with this library; if not, see <http://www.gnu.org/licenses/>.
19 *
20 * Author: David Zeuthen <davidz@redhat.com>
21 */
22
23 #include "config.h"
24
25 #include "gdbusobject.h"
26 #include "gdbusobjectmanager.h"
27 #include "gdbusinterface.h"
28 #include "gdbusutils.h"
29
30 #include "glibintl.h"
31 #include "gmarshal-internal.h"
32
33 /**
34 * GDBusObjectManager:
35 *
36 * The `GDBusObjectManager` type is the base type for service- and
37 * client-side implementations of the standardized
38 * [`org.freedesktop.DBus.ObjectManager`](http://dbus.freedesktop.org/doc/dbus-specification.html#standard-interfaces-objectmanager)
39 * interface.
40 *
41 * See [class@Gio.DBusObjectManagerClient] for the client-side implementation
42 * and [class@Gio.DBusObjectManagerServer] for the service-side implementation.
43 */
44
45 typedef GDBusObjectManagerIface GDBusObjectManagerInterface;
46 G_DEFINE_INTERFACE (GDBusObjectManager, g_dbus_object_manager, G_TYPE_OBJECT)
47
48 enum {
49 OBJECT_ADDED,
50 OBJECT_REMOVED,
51 INTERFACE_ADDED,
52 INTERFACE_REMOVED,
53 N_SIGNALS
54 };
55
56 static guint signals[N_SIGNALS];
57
58 static void
59 g_dbus_object_manager_default_init (GDBusObjectManagerIface *iface)
60 {
61 /**
62 * GDBusObjectManager::object-added:
63 * @manager: The #GDBusObjectManager emitting the signal.
64 * @object: The #GDBusObject that was added.
65 *
66 * Emitted when @object is added to @manager.
67 *
68 * Since: 2.30
69 */
70 signals[OBJECT_ADDED] =
71 g_signal_new (I_("object-added"),
72 G_TYPE_FROM_INTERFACE (iface),
73 G_SIGNAL_RUN_LAST,
74 G_STRUCT_OFFSET (GDBusObjectManagerIface, object_added),
75 NULL,
76 NULL,
77 NULL,
78 G_TYPE_NONE,
79 1,
80 G_TYPE_DBUS_OBJECT);
81
82 /**
83 * GDBusObjectManager::object-removed:
84 * @manager: The #GDBusObjectManager emitting the signal.
85 * @object: The #GDBusObject that was removed.
86 *
87 * Emitted when @object is removed from @manager.
88 *
89 * Since: 2.30
90 */
91 signals[OBJECT_REMOVED] =
92 g_signal_new (I_("object-removed"),
93 G_TYPE_FROM_INTERFACE (iface),
94 G_SIGNAL_RUN_LAST,
95 G_STRUCT_OFFSET (GDBusObjectManagerIface, object_removed),
96 NULL,
97 NULL,
98 NULL,
99 G_TYPE_NONE,
100 1,
101 G_TYPE_DBUS_OBJECT);
102
103 /**
104 * GDBusObjectManager::interface-added:
105 * @manager: The #GDBusObjectManager emitting the signal.
106 * @object: The #GDBusObject on which an interface was added.
107 * @interface: The #GDBusInterface that was added.
108 *
109 * Emitted when @interface is added to @object.
110 *
111 * This signal exists purely as a convenience to avoid having to
112 * connect signals to all objects managed by @manager.
113 *
114 * Since: 2.30
115 */
116 signals[INTERFACE_ADDED] =
117 g_signal_new (I_("interface-added"),
118 G_TYPE_FROM_INTERFACE (iface),
119 G_SIGNAL_RUN_LAST,
120 G_STRUCT_OFFSET (GDBusObjectManagerIface, interface_added),
121 NULL,
122 NULL,
123 _g_cclosure_marshal_VOID__OBJECT_OBJECT,
124 G_TYPE_NONE,
125 2,
126 G_TYPE_DBUS_OBJECT,
127 G_TYPE_DBUS_INTERFACE);
128 g_signal_set_va_marshaller (signals[INTERFACE_ADDED],
129 G_TYPE_FROM_INTERFACE (iface),
130 _g_cclosure_marshal_VOID__OBJECT_OBJECTv);
131
132 /**
133 * GDBusObjectManager::interface-removed:
134 * @manager: The #GDBusObjectManager emitting the signal.
135 * @object: The #GDBusObject on which an interface was removed.
136 * @interface: The #GDBusInterface that was removed.
137 *
138 * Emitted when @interface has been removed from @object.
139 *
140 * This signal exists purely as a convenience to avoid having to
141 * connect signals to all objects managed by @manager.
142 *
143 * Since: 2.30
144 */
145 signals[INTERFACE_REMOVED] =
146 g_signal_new (I_("interface-removed"),
147 G_TYPE_FROM_INTERFACE (iface),
148 G_SIGNAL_RUN_LAST,
149 G_STRUCT_OFFSET (GDBusObjectManagerIface, interface_removed),
150 NULL,
151 NULL,
152 _g_cclosure_marshal_VOID__OBJECT_OBJECT,
153 G_TYPE_NONE,
154 2,
155 G_TYPE_DBUS_OBJECT,
156 G_TYPE_DBUS_INTERFACE);
157 g_signal_set_va_marshaller (signals[INTERFACE_REMOVED],
158 G_TYPE_FROM_INTERFACE (iface),
159 _g_cclosure_marshal_VOID__OBJECT_OBJECTv);
160
161 }
162
163 /* ---------------------------------------------------------------------------------------------------- */
164
165 /**
166 * g_dbus_object_manager_get_object_path:
167 * @manager: A #GDBusObjectManager.
168 *
169 * Gets the object path that @manager is for.
170 *
171 * Returns: A string owned by @manager. Do not free.
172 *
173 * Since: 2.30
174 */
175 const gchar *
176 g_dbus_object_manager_get_object_path (GDBusObjectManager *manager)
177 {
178 GDBusObjectManagerIface *iface = G_DBUS_OBJECT_MANAGER_GET_IFACE (manager);
179 return iface->get_object_path (manager);
180 }
181
182 /**
183 * g_dbus_object_manager_get_objects:
184 * @manager: A #GDBusObjectManager.
185 *
186 * Gets all #GDBusObject objects known to @manager.
187 *
188 * Returns: (transfer full) (element-type GDBusObject): A list of
189 * #GDBusObject objects. The returned list should be freed with
190 * g_list_free() after each element has been freed with
191 * g_object_unref().
192 *
193 * Since: 2.30
194 */
195 GList *
196 g_dbus_object_manager_get_objects (GDBusObjectManager *manager)
197 {
198 GDBusObjectManagerIface *iface = G_DBUS_OBJECT_MANAGER_GET_IFACE (manager);
199 return iface->get_objects (manager);
200 }
201
202 /**
203 * g_dbus_object_manager_get_object:
204 * @manager: A #GDBusObjectManager.
205 * @object_path: Object path to look up.
206 *
207 * Gets the #GDBusObject at @object_path, if any.
208 *
209 * Returns: (transfer full) (nullable): A #GDBusObject or %NULL. Free with
210 * g_object_unref().
211 *
212 * Since: 2.30
213 */
214 GDBusObject *
215 g_dbus_object_manager_get_object (GDBusObjectManager *manager,
216 const gchar *object_path)
217 {
218 GDBusObjectManagerIface *iface = G_DBUS_OBJECT_MANAGER_GET_IFACE (manager);
219 g_return_val_if_fail (g_variant_is_object_path (object_path), NULL);
220 return iface->get_object (manager, object_path);
221 }
222
223 /**
224 * g_dbus_object_manager_get_interface:
225 * @manager: A #GDBusObjectManager.
226 * @object_path: Object path to look up.
227 * @interface_name: D-Bus interface name to look up.
228 *
229 * Gets the interface proxy for @interface_name at @object_path, if
230 * any.
231 *
232 * Returns: (transfer full) (nullable): A #GDBusInterface instance or %NULL. Free
233 * with g_object_unref().
234 *
235 * Since: 2.30
236 */
237 GDBusInterface *
238 g_dbus_object_manager_get_interface (GDBusObjectManager *manager,
239 const gchar *object_path,
240 const gchar *interface_name)
241 {
242 GDBusObjectManagerIface *iface = G_DBUS_OBJECT_MANAGER_GET_IFACE (manager);
243 g_return_val_if_fail (g_variant_is_object_path (object_path), NULL);
244 g_return_val_if_fail (g_dbus_is_interface_name (interface_name), NULL);
245 return iface->get_interface (manager, object_path, interface_name);
246 }