+2007-12-19 David Zeuthen <davidz@redhat.com>
+
+ Introduce g_volume_monitor_adopt_orphan_mount() function. Also
+ add signals 'disconnected' and 'eject-button' on GDrive. Add
+ signal 'removed' on GVolume and 'unmounted' on GMount.
+
+ * gdrive.c: (g_drive_base_init):
+ * gdrive.h:
+ * gfile.c: (g_file_mount_mountable),
+ (g_file_mount_enclosing_volume):
+ * gio.symbols:
+ * gioerror.h:
+ * gmount.c: (g_mount_base_init):
+ * gmount.h:
+ * gunionvolumemonitor.c: (g_volume_monitor_adopt_orphan_mount):
+ * gunixvolumemonitor.c: (update_volumes), (update_mounts):
+ * gvolume.c: (g_volume_base_init), (g_volume_mount):
+ * gvolume.h:
+ * gvolumemonitor.h:
+
2007-12-17 Matthias Clasen <mclasen@redhat.com>
* *.c: Fix up includes in the section docs.
{
/**
* GDrive::changed:
- * @volume: a #GVolume.
+ * @drive: a #GDrive.
*
* Emitted when the drive's state has changed.
- *
**/
g_signal_new (I_("changed"),
G_TYPE_DRIVE,
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE, 0);
+ /**
+ * GDrive::disconnected:
+ * @drive: a #GDrive.
+ *
+ * This signal is emitted when the #GDrive have been
+ * disconnected. If the recipient is holding references to the
+ * object they should release them so the object can be
+ * finalized.
+ **/
+ g_signal_new (I_("disconnected"),
+ G_TYPE_DRIVE,
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (GDriveIface, disconnected),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ /**
+ * GDrive::eject-button:
+ * @drive: a #GDrive.
+ *
+ * Emitted when the physical eject button (if any) of a drive have been pressed.
+ *
+ **/
+ g_signal_new (I_("eject-button"),
+ G_TYPE_DRIVE,
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (GDriveIface, eject_button),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
initialized = TRUE;
}
}
* GDriveIface:
* @g_iface: The parent interface.
* @changed: Signal emitted when the drive is changed.
+ * @disconnected: The removed signal that is emitted when the #GDrive have been disconnected. If the recipient is holding references to the object they should release them so the object can be finalized.
+ * @eject_button: Signal emitted when the physical eject button (if any) of a drive have been pressed.
* @get_name: Returns the name for the given #GDrive.
* @get_icon: Returns a #GIcon for the given #GDrive.
* @has_volumes: Returns %TRUE if the #GDrive has mountable volumes.
/* signals */
void (*changed) (GDrive *drive);
+ void (*disconnected) (GDrive *drive);
+ void (*eject_button) (GDrive *drive);
/* Virtual Table */
char * (*get_name) (GDrive *drive);
/**
* g_file_mount_mountable:
* @file: input #GFile.
- * @mount_operation: a #GMountOperation, or %NULL.
+ * @mount_operation: a #GMountOperation, or %NULL to avoid user interaction.
* @cancellable: optional #GCancellable object, %NULL to ignore.
* @callback: a #GAsyncReadyCallback to call when the request is satisfied
* @user_data: the data to pass to callback function
GFileIface *iface;
g_return_if_fail (G_IS_FILE (file));
- g_return_if_fail (G_IS_MOUNT_OPERATION (mount_operation));
iface = G_FILE_GET_IFACE (file);
/**
* g_file_mount_enclosing_volume:
* @location: input #GFile.
- * @mount_operation: a #GMountOperation.
+ * @mount_operation: a #GMountOperation or %NULL to avoid user interaction.
* @cancellable: optional #GCancellable object, %NULL to ignore.
* @callback: a #GAsyncReadyCallback to call when the request is satisfied
* @user_data: the data to pass to callback function
GFileIface *iface;
g_return_if_fail (G_IS_FILE (location));
- g_return_if_fail (G_IS_MOUNT_OPERATION (mount_operation));
iface = G_FILE_GET_IFACE (location);
#endif
#if IN_FILE(__G_UNION_VOLUME_MONITOR_C__)
g_volume_monitor_get
+g_volume_monitor_adopt_orphan_mount
#endif
#endif
* @G_IO_ERROR_WOULD_BLOCK: Operation would block.
* @G_IO_ERROR_HOST_NOT_FOUND: Host couldn't be found (remote operations).
* @G_IO_ERROR_WOULD_MERGE: Operation would merge files.
+ * @G_IO_ERROR_FAILED_HANDLED: Operation failed and a helper program has already interacted with the user. Do not display any error dialog.
*
* Error codes returned by GIO functions.
*
G_IO_ERROR_BUSY,
G_IO_ERROR_WOULD_BLOCK,
G_IO_ERROR_HOST_NOT_FOUND,
- G_IO_ERROR_WOULD_MERGE
+ G_IO_ERROR_WOULD_MERGE,
+ G_IO_ERROR_FAILED_HANDLED
} GIOErrorEnum;
GIOErrorEnum g_io_error_from_errno (gint err_no);
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE, 0);
+ /**
+ * GMount::unmounted:
+ *
+ * This signal is emitted when the #GMount have been
+ * unmounted. If the recipient is holding references to the
+ * object they should release them so the object can be
+ * finalized.
+ **/
+ g_signal_new (I_("unmounted"),
+ G_TYPE_MOUNT,
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (GMountIface, unmounted),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
initialized = TRUE;
}
}
* GMountIface:
* @g_iface: The parent interface.
* @changed: Changed signal that is emitted when the mount's state has changed.
+ * @unmounted: The unmounted signal that is emitted when the #GMount have been unmounted. If the recipient is holding references to the object they should release them so the object can be finalized.
* @get_root: Gets a #GFile to the root directory of the #GMount.
* @get_name: Gets a string containing the name of the #GMount.
* @get_icon: Gets a #GIcon for the #GMount.
/* signals */
void (*changed) (GMount *mount);
+ void (*unmounted) (GMount *mount);
/* Virtual Table */
return mount;
}
+/**
+ * g_volume_monitor_adopt_orphan_mount:
+ * @mount: a #GMount object to find a parent for
+ *
+ * This function should be called by any #GVolumeMonitor
+ * implementation when a new #GMount object is created that is not
+ * associated with a #GVolume object. It must be called just before
+ * emitting the @mount_added signal.
+ *
+ * If the return value is not %NULL, the caller must associate the
+ * returned #GVolume object with the #GMount. This involves returning
+ * it in it's g_mount_get_volume() implementation. The caller must
+ * also listen for the "removed" signal on the returned object
+ * and give up it's reference when handling that signal
+ *
+ * Similary, if implementing g_volume_monitor_adopt_orphan_mount(),
+ * the implementor must take a reference to @mount and return it in
+ * it's g_volume_get_mount() implemented. Also, the implementor must
+ * listen for the "unmounted" signal on @mount and give up it's
+ * reference upon handling that signal.
+ *
+ * There are two main use cases for this function.
+ *
+ * One is when implementing a user space file system driver that reads
+ * blocks of a block device that is already represented by the native
+ * volume monitor (for example a CD Audio file system driver). Such
+ * a driver will generate it's own #GMount object that needs to be
+ * assoicated with the #GVolume object that represents the volume.
+ *
+ * The other is for implementing a #GVolumeMonitor whose sole purpose
+ * is to return #GVolume objects representing entries in the users
+ * "favorite servers" list or similar.
+ *
+ * Returns: the #GVolume object that is the parent for @mount or %NULL
+ * if no wants to adopt the #GMount.
+ */
+GVolume *
+g_volume_monitor_adopt_orphan_mount (GMount *mount)
+{
+ GVolumeMonitor *child_monitor;
+ GVolumeMonitorClass *child_monitor_class;
+ GVolume *volume;
+ GList *l;
+
+ g_return_val_if_fail (mount != NULL, NULL);
+
+ if (the_volume_monitor == NULL)
+ return NULL;
+
+ volume = NULL;
+
+ /* TODO: nasty locking issues because current VM's don't emit signals in idle */
+
+ //G_LOCK (the_volume_monitor);
+
+ for (l = the_volume_monitor->monitors; l != NULL; l = l->next)
+ {
+ child_monitor = l->data;
+ child_monitor_class = G_VOLUME_MONITOR_GET_CLASS (child_monitor);
+
+ if (child_monitor_class->adopt_orphan_mount != NULL)
+ {
+ volume = child_monitor_class->adopt_orphan_mount (mount);
+ if (volume != NULL)
+ break;
+ }
+ }
+
+ //G_UNLOCK (the_volume_monitor);
+
+ return volume;
+}
+
+
#define __G_UNION_VOLUME_MONITOR_C__
#include "gioaliasdef.c"
_g_unix_volume_disconnected (volume);
monitor->volumes = g_list_remove (monitor->volumes, volume);
g_signal_emit_by_name (monitor, "volume_removed", volume);
+ g_signal_emit_by_name (volume, "removed");
g_object_unref (volume);
}
}
_g_unix_mount_unmounted (mount);
monitor->mounts = g_list_remove (monitor->mounts, mount);
g_signal_emit_by_name (monitor, "mount_removed", mount);
+ g_signal_emit_by_name (mount, "unmounted");
g_object_unref (mount);
}
}
* Mounting a #GVolume instance is an asynchronous operation. For more
* information about asynchronous operations, see #GAsyncReady and
* #GSimpleAsyncReady. To mount a #GVolume, first call
- * g_volume_mount() with (at least) the #GVolume instane, a
- * #GMountOperation object and a #GAsyncReadyCallback. The callback
- * will be fired when the operation has resolved (either with success
- * or failure), and a #GAsyncReady structure will be passed to the
- * callback. That callback should then call g_volume_mount_finish()
- * with the #GVolume instance and the #GAsyncReady data to see if the
- * operation was completed successfully. If an @error is present when
- * g_volume_mount_finish() is called, then it will be filled with any
- * error information.
+ * g_volume_mount() with (at least) the #GVolume instance, optionally
+ * a #GMountOperation object and a #GAsyncReadyCallback.
+ *
+ * Typically, one will only want to pass %NULL for the
+ * #GMountOperation if automounting all volumes when a desktop session
+ * starts since it's not desirable to put up a lot of dialogs asking
+ * for credentials.
+ *
+ * The callback will be fired when the operation has resolved (either
+ * with success or failure), and a #GAsyncReady structure will be
+ * passed to the callback. That callback should then call
+ * g_volume_mount_finish() with the #GVolume instance and the
+ * #GAsyncReady data to see if the operation was completed
+ * successfully. If an @error is present when g_volume_mount_finish()
+ * is called, then it will be filled with any error information.
**/
static void g_volume_base_init (gpointer g_class);
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE, 0);
+ /**
+ * GVolume::removed:
+ *
+ * This signal is emitted when the #GVolume have been removed. If
+ * the recipient is holding references to the object they should
+ * release them so the object can be finalized.
+ **/
+ g_signal_new (I_("removed"),
+ G_TYPE_VOLUME,
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (GVolumeIface, removed),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
initialized = TRUE;
}
}
/**
* g_volume_mount:
* @volume: a #GVolume.
- * @mount_operation: a #GMountOperation.
+ * @mount_operation: a #GMountOperation or %NULL to avoid user interaction.
* @cancellable: optional #GCancellable object, %NULL to ignore.
* @callback: a #GAsyncReadyCallback.
* @user_data: a #gpointer.
GVolumeIface *iface;
g_return_if_fail (G_IS_VOLUME (volume));
- g_return_if_fail (G_IS_MOUNT_OPERATION (mount_operation));
iface = G_VOLUME_GET_IFACE (volume);
* GVolumeIface:
* @g_iface: The parent interface.
* @changed: Changed signal that is emitted when the volume's state has changed.
+ * @removed: The removed signal that is emitted when the #GVolume have been removed. If the recipient is holding references to the object they should release them so the object can be finalized.
* @get_name: Gets a string containing the name of the #GVolume.
* @get_icon: Gets a #GIcon for the #GVolume.
* @get_uuid: Gets the UUID for the #GVolume. The reference is typically based on the file system UUID for the mount in question and should be considered an opaque string. Returns %NULL if there is no UUID available.
/* signals */
void (*changed) (GVolume *volume);
+ void (*removed) (GVolume *volume);
/* Virtual Table */
GMount * (*get_mount_for_uuid) (GVolumeMonitor *volume_monitor,
const char *uuid);
+
+ GVolume * (*adopt_orphan_mount) (GMount *mount);
+
/*< private >*/
/* Padding for future expansion */
void (*_g_reserved1) (void);
GMount * g_volume_monitor_get_mount_for_uuid (GVolumeMonitor *volume_monitor,
const char *uuid);
+GVolume * g_volume_monitor_adopt_orphan_mount (GMount *mount);
+
G_END_DECLS
#endif /* __G_VOLUME_MONITOR_H__ */