1 /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
2
3 /* GIO - GLib Input, Output and Streaming Library
4 *
5 * Copyright (C) 2006-2007 Red Hat, Inc.
6 *
7 * SPDX-License-Identifier: LGPL-2.1-or-later
8 *
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
13 *
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
18 *
19 * You should have received a copy of the GNU Lesser General
20 * Public License along with this library; if not, see <http://www.gnu.org/licenses/>.
21 *
22 * Author: Alexander Larsson <alexl@redhat.com>
23 * David Zeuthen <davidz@redhat.com>
24 */
25
26 #include "config.h"
27 #include "gvolumemonitor.h"
28 #include "gvolume.h"
29 #include "gmount.h"
30 #include "gdrive.h"
31 #include "glibintl.h"
32
33
34 /**
35 * GVolumeMonitor:
36 *
37 * `GVolumeMonitor` is for listing the user interesting devices and volumes
38 * on the computer. In other words, what a file selector or file manager
39 * would show in a sidebar.
40 *
41 * `GVolumeMonitor` is not
42 * thread-default-context aware (see
43 * [method@GLib.MainContext.push_thread_default]), and so should not be used
44 * other than from the main thread, with no thread-default-context active.
45 *
46 * In order to receive updates about volumes and mounts monitored through GVFS,
47 * a main loop must be running.
48 **/
49
50 G_DEFINE_TYPE (GVolumeMonitor, g_volume_monitor, G_TYPE_OBJECT)
51
52 enum {
53 VOLUME_ADDED,
54 VOLUME_REMOVED,
55 VOLUME_CHANGED,
56 MOUNT_ADDED,
57 MOUNT_REMOVED,
58 MOUNT_PRE_UNMOUNT,
59 MOUNT_CHANGED,
60 DRIVE_CONNECTED,
61 DRIVE_DISCONNECTED,
62 DRIVE_CHANGED,
63 DRIVE_EJECT_BUTTON,
64 DRIVE_STOP_BUTTON,
65 LAST_SIGNAL
66 };
67
68 static guint signals[LAST_SIGNAL] = { 0 };
69
70
71 static void
72 g_volume_monitor_finalize (GObject *object)
73 {
74 G_OBJECT_CLASS (g_volume_monitor_parent_class)->finalize (object);
75 }
76
77 static void
78 g_volume_monitor_class_init (GVolumeMonitorClass *klass)
79 {
80 GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
81
82 gobject_class->finalize = g_volume_monitor_finalize;
83
84 /**
85 * GVolumeMonitor::volume-added:
86 * @volume_monitor: The volume monitor emitting the signal.
87 * @volume: a #GVolume that was added.
88 *
89 * Emitted when a mountable volume is added to the system.
90 **/
91 signals[VOLUME_ADDED] = g_signal_new (I_("volume-added"),
92 G_TYPE_VOLUME_MONITOR,
93 G_SIGNAL_RUN_LAST,
94 G_STRUCT_OFFSET (GVolumeMonitorClass, volume_added),
95 NULL, NULL,
96 NULL,
97 G_TYPE_NONE, 1, G_TYPE_VOLUME);
98
99 /**
100 * GVolumeMonitor::volume-removed:
101 * @volume_monitor: The volume monitor emitting the signal.
102 * @volume: a #GVolume that was removed.
103 *
104 * Emitted when a mountable volume is removed from the system.
105 **/
106 signals[VOLUME_REMOVED] = g_signal_new (I_("volume-removed"),
107 G_TYPE_VOLUME_MONITOR,
108 G_SIGNAL_RUN_LAST,
109 G_STRUCT_OFFSET (GVolumeMonitorClass, volume_removed),
110 NULL, NULL,
111 NULL,
112 G_TYPE_NONE, 1, G_TYPE_VOLUME);
113
114 /**
115 * GVolumeMonitor::volume-changed:
116 * @volume_monitor: The volume monitor emitting the signal.
117 * @volume: a #GVolume that changed.
118 *
119 * Emitted when mountable volume is changed.
120 **/
121 signals[VOLUME_CHANGED] = g_signal_new (I_("volume-changed"),
122 G_TYPE_VOLUME_MONITOR,
123 G_SIGNAL_RUN_LAST,
124 G_STRUCT_OFFSET (GVolumeMonitorClass, volume_changed),
125 NULL, NULL,
126 NULL,
127 G_TYPE_NONE, 1, G_TYPE_VOLUME);
128
129 /**
130 * GVolumeMonitor::mount-added:
131 * @volume_monitor: The volume monitor emitting the signal.
132 * @mount: a #GMount that was added.
133 *
134 * Emitted when a mount is added.
135 **/
136 signals[MOUNT_ADDED] = g_signal_new (I_("mount-added"),
137 G_TYPE_VOLUME_MONITOR,
138 G_SIGNAL_RUN_LAST,
139 G_STRUCT_OFFSET (GVolumeMonitorClass, mount_added),
140 NULL, NULL,
141 NULL,
142 G_TYPE_NONE, 1, G_TYPE_MOUNT);
143
144 /**
145 * GVolumeMonitor::mount-removed:
146 * @volume_monitor: The volume monitor emitting the signal.
147 * @mount: a #GMount that was removed.
148 *
149 * Emitted when a mount is removed.
150 **/
151 signals[MOUNT_REMOVED] = g_signal_new (I_("mount-removed"),
152 G_TYPE_VOLUME_MONITOR,
153 G_SIGNAL_RUN_LAST,
154 G_STRUCT_OFFSET (GVolumeMonitorClass, mount_removed),
155 NULL, NULL,
156 NULL,
157 G_TYPE_NONE, 1, G_TYPE_MOUNT);
158
159 /**
160 * GVolumeMonitor::mount-pre-unmount:
161 * @volume_monitor: The volume monitor emitting the signal.
162 * @mount: a #GMount that is being unmounted.
163 *
164 * May be emitted when a mount is about to be removed.
165 *
166 * This signal depends on the backend and is only emitted if
167 * GIO was used to unmount.
168 **/
169 signals[MOUNT_PRE_UNMOUNT] = g_signal_new (I_("mount-pre-unmount"),
170 G_TYPE_VOLUME_MONITOR,
171 G_SIGNAL_RUN_LAST,
172 G_STRUCT_OFFSET (GVolumeMonitorClass, mount_pre_unmount),
173 NULL, NULL,
174 NULL,
175 G_TYPE_NONE, 1, G_TYPE_MOUNT);
176
177 /**
178 * GVolumeMonitor::mount-changed:
179 * @volume_monitor: The volume monitor emitting the signal.
180 * @mount: a #GMount that changed.
181 *
182 * Emitted when a mount changes.
183 **/
184 signals[MOUNT_CHANGED] = g_signal_new (I_("mount-changed"),
185 G_TYPE_VOLUME_MONITOR,
186 G_SIGNAL_RUN_LAST,
187 G_STRUCT_OFFSET (GVolumeMonitorClass, mount_changed),
188 NULL, NULL,
189 NULL,
190 G_TYPE_NONE, 1, G_TYPE_MOUNT);
191
192 /**
193 * GVolumeMonitor::drive-connected:
194 * @volume_monitor: The volume monitor emitting the signal.
195 * @drive: a #GDrive that was connected.
196 *
197 * Emitted when a drive is connected to the system.
198 **/
199 signals[DRIVE_CONNECTED] = g_signal_new (I_("drive-connected"),
200 G_TYPE_VOLUME_MONITOR,
201 G_SIGNAL_RUN_LAST,
202 G_STRUCT_OFFSET (GVolumeMonitorClass, drive_connected),
203 NULL, NULL,
204 NULL,
205 G_TYPE_NONE, 1, G_TYPE_DRIVE);
206
207 /**
208 * GVolumeMonitor::drive-disconnected:
209 * @volume_monitor: The volume monitor emitting the signal.
210 * @drive: a #GDrive that was disconnected.
211 *
212 * Emitted when a drive is disconnected from the system.
213 **/
214 signals[DRIVE_DISCONNECTED] = g_signal_new (I_("drive-disconnected"),
215 G_TYPE_VOLUME_MONITOR,
216 G_SIGNAL_RUN_LAST,
217 G_STRUCT_OFFSET (GVolumeMonitorClass, drive_disconnected),
218 NULL, NULL,
219 NULL,
220 G_TYPE_NONE, 1, G_TYPE_DRIVE);
221
222 /**
223 * GVolumeMonitor::drive-changed:
224 * @volume_monitor: The volume monitor emitting the signal.
225 * @drive: the drive that changed
226 *
227 * Emitted when a drive changes.
228 **/
229 signals[DRIVE_CHANGED] = g_signal_new (I_("drive-changed"),
230 G_TYPE_VOLUME_MONITOR,
231 G_SIGNAL_RUN_LAST,
232 G_STRUCT_OFFSET (GVolumeMonitorClass, drive_changed),
233 NULL, NULL,
234 NULL,
235 G_TYPE_NONE, 1, G_TYPE_DRIVE);
236
237 /**
238 * GVolumeMonitor::drive-eject-button:
239 * @volume_monitor: The volume monitor emitting the signal.
240 * @drive: the drive where the eject button was pressed
241 *
242 * Emitted when the eject button is pressed on @drive.
243 *
244 * Since: 2.18
245 **/
246 signals[DRIVE_EJECT_BUTTON] = g_signal_new (I_("drive-eject-button"),
247 G_TYPE_VOLUME_MONITOR,
248 G_SIGNAL_RUN_LAST,
249 G_STRUCT_OFFSET (GVolumeMonitorClass, drive_eject_button),
250 NULL, NULL,
251 NULL,
252 G_TYPE_NONE, 1, G_TYPE_DRIVE);
253
254 /**
255 * GVolumeMonitor::drive-stop-button:
256 * @volume_monitor: The volume monitor emitting the signal.
257 * @drive: the drive where the stop button was pressed
258 *
259 * Emitted when the stop button is pressed on @drive.
260 *
261 * Since: 2.22
262 **/
263 signals[DRIVE_STOP_BUTTON] = g_signal_new (I_("drive-stop-button"),
264 G_TYPE_VOLUME_MONITOR,
265 G_SIGNAL_RUN_LAST,
266 G_STRUCT_OFFSET (GVolumeMonitorClass, drive_stop_button),
267 NULL, NULL,
268 NULL,
269 G_TYPE_NONE, 1, G_TYPE_DRIVE);
270
271 }
272
273 static void
274 g_volume_monitor_init (GVolumeMonitor *monitor)
275 {
276 }
277
278
279 /**
280 * g_volume_monitor_get_connected_drives:
281 * @volume_monitor: a #GVolumeMonitor.
282 *
283 * Gets a list of drives connected to the system.
284 *
285 * The returned list should be freed with g_list_free(), after
286 * its elements have been unreffed with g_object_unref().
287 *
288 * Returns: (element-type GDrive) (transfer full): a #GList of connected #GDrive objects.
289 **/
290 GList *
291 g_volume_monitor_get_connected_drives (GVolumeMonitor *volume_monitor)
292 {
293 GVolumeMonitorClass *class;
294
295 g_return_val_if_fail (G_IS_VOLUME_MONITOR (volume_monitor), NULL);
296
297 class = G_VOLUME_MONITOR_GET_CLASS (volume_monitor);
298
299 return class->get_connected_drives (volume_monitor);
300 }
301
302 /**
303 * g_volume_monitor_get_volumes:
304 * @volume_monitor: a #GVolumeMonitor.
305 *
306 * Gets a list of the volumes on the system.
307 *
308 * The returned list should be freed with g_list_free(), after
309 * its elements have been unreffed with g_object_unref().
310 *
311 * Returns: (element-type GVolume) (transfer full): a #GList of #GVolume objects.
312 **/
313 GList *
314 g_volume_monitor_get_volumes (GVolumeMonitor *volume_monitor)
315 {
316 GVolumeMonitorClass *class;
317
318 g_return_val_if_fail (G_IS_VOLUME_MONITOR (volume_monitor), NULL);
319
320 class = G_VOLUME_MONITOR_GET_CLASS (volume_monitor);
321
322 return class->get_volumes (volume_monitor);
323 }
324
325 /**
326 * g_volume_monitor_get_mounts:
327 * @volume_monitor: a #GVolumeMonitor.
328 *
329 * Gets a list of the mounts on the system.
330 *
331 * The returned list should be freed with g_list_free(), after
332 * its elements have been unreffed with g_object_unref().
333 *
334 * Returns: (element-type GMount) (transfer full): a #GList of #GMount objects.
335 **/
336 GList *
337 g_volume_monitor_get_mounts (GVolumeMonitor *volume_monitor)
338 {
339 GVolumeMonitorClass *class;
340
341 g_return_val_if_fail (G_IS_VOLUME_MONITOR (volume_monitor), NULL);
342
343 class = G_VOLUME_MONITOR_GET_CLASS (volume_monitor);
344
345 return class->get_mounts (volume_monitor);
346 }
347
348 /**
349 * g_volume_monitor_get_volume_for_uuid:
350 * @volume_monitor: a #GVolumeMonitor.
351 * @uuid: the UUID to look for
352 *
353 * Finds a #GVolume object by its UUID (see g_volume_get_uuid())
354 *
355 * Returns: (nullable) (transfer full): a #GVolume or %NULL if no such volume is available.
356 * Free the returned object with g_object_unref().
357 **/
358 GVolume *
359 g_volume_monitor_get_volume_for_uuid (GVolumeMonitor *volume_monitor,
360 const char *uuid)
361 {
362 GVolumeMonitorClass *class;
363
364 g_return_val_if_fail (G_IS_VOLUME_MONITOR (volume_monitor), NULL);
365 g_return_val_if_fail (uuid != NULL, NULL);
366
367 class = G_VOLUME_MONITOR_GET_CLASS (volume_monitor);
368
369 return class->get_volume_for_uuid (volume_monitor, uuid);
370 }
371
372 /**
373 * g_volume_monitor_get_mount_for_uuid:
374 * @volume_monitor: a #GVolumeMonitor.
375 * @uuid: the UUID to look for
376 *
377 * Finds a #GMount object by its UUID (see g_mount_get_uuid())
378 *
379 * Returns: (nullable) (transfer full): a #GMount or %NULL if no such mount is available.
380 * Free the returned object with g_object_unref().
381 **/
382 GMount *
383 g_volume_monitor_get_mount_for_uuid (GVolumeMonitor *volume_monitor,
384 const char *uuid)
385 {
386 GVolumeMonitorClass *class;
387
388 g_return_val_if_fail (G_IS_VOLUME_MONITOR (volume_monitor), NULL);
389 g_return_val_if_fail (uuid != NULL, NULL);
390
391 class = G_VOLUME_MONITOR_GET_CLASS (volume_monitor);
392
393 return class->get_mount_for_uuid (volume_monitor, uuid);
394 }