[brasero] Remove use of HAL from the medium monitor
- From: Philippe Rouquier <philippr src gnome org>
- To: svn-commits-list gnome org
- Subject: [brasero] Remove use of HAL from the medium monitor
- Date: Fri, 10 Jul 2009 14:04:06 +0000 (UTC)
commit 995880a3fac606eb14e829c8b6fc2471a2de507c
Author: Philippe Rouquier <bonfire-app wanadoo fr>
Date: Thu Jul 9 21:13:02 2009 +0200
Remove use of HAL from the medium monitor
Implement INQUIRY (MMC command) to retrieve the drive category
libbrasero-media/Makefile.am | 3 +-
libbrasero-media/brasero-drive.c | 3 +-
libbrasero-media/brasero-medium-monitor.c | 212 +++++++++++------------------
libbrasero-media/scsi-inquiry.c | 109 +++++++++++++++
libbrasero-media/scsi-spc1.h | 4 +
5 files changed, 198 insertions(+), 133 deletions(-)
---
diff --git a/libbrasero-media/Makefile.am b/libbrasero-media/Makefile.am
index c83996e..be5baa5 100644
--- a/libbrasero-media/Makefile.am
+++ b/libbrasero-media/Makefile.am
@@ -128,7 +128,8 @@ libbrasero_media_la_SOURCES = \
brasero-media-private.h \
brasero-medium-selection-priv.h \
brasero-gio-operation.h \
- brasero-gio-operation.c
+ brasero-gio-operation.c \
+ scsi-inquiry.c
# FreeBSD's SCSI CAM interface
if HAVE_CAM_LIB_H
diff --git a/libbrasero-media/brasero-drive.c b/libbrasero-media/brasero-drive.c
index 379937e..4dd7de2 100644
--- a/libbrasero-media/brasero-drive.c
+++ b/libbrasero-media/brasero-drive.c
@@ -479,7 +479,7 @@ brasero_drive_get_device (BraseroDrive *drive)
g_return_val_if_fail (BRASERO_IS_DRIVE (drive), NULL);
priv = BRASERO_DRIVE_PRIVATE (drive);
- return priv->path;
+ return priv->path? priv->path:priv->block_path;
}
/**
@@ -512,6 +512,7 @@ brasero_drive_get_block_device (BraseroDrive *drive)
* to uniquely identify the drive.
*
* Return value: a string holding the HAL udi. Not to be freed
+ * Deprecated since 2.27.3
**/
const gchar *
brasero_drive_get_udi (BraseroDrive *drive)
diff --git a/libbrasero-media/brasero-medium-monitor.c b/libbrasero-media/brasero-medium-monitor.c
index 3cbb16c..9c826e3 100644
--- a/libbrasero-media/brasero-medium-monitor.c
+++ b/libbrasero-media/brasero-medium-monitor.c
@@ -47,9 +47,12 @@
#include "brasero-media-private.h"
+#include "scsi-device.h"
+#include "scsi-utils.h"
+#include "scsi-spc1.h"
+
#include "brasero-drive.h"
#include "brasero-medium.h"
-#include "burn-hal-watch.h"
#include "brasero-medium-monitor.h"
typedef struct _BraseroMediumMonitorPrivate BraseroMediumMonitorPrivate;
@@ -286,49 +289,6 @@ brasero_medium_monitor_get_media (BraseroMediumMonitor *monitor,
return list;
}
-static GDrive *
-brasero_medium_monitor_get_gdrive (BraseroMediumMonitor *monitor,
- const gchar *volume_path)
-{
- BraseroMediumMonitorPrivate *priv;
- GDrive *gdrive = NULL;
- GList *drives;
- GList *iter;
-
- g_return_val_if_fail (volume_path != NULL, NULL);
-
- priv = BRASERO_MEDIUM_MONITOR_PRIVATE (monitor);
-
- /* NOTE: medium-monitor already holds a reference for GVolumeMonitor */
- drives = g_volume_monitor_get_connected_drives (priv->gmonitor);
- for (iter = drives; iter; iter = iter->next) {
- gchar *device_path;
- GDrive *tmp;
-
- tmp = iter->data;
- device_path = g_drive_get_identifier (tmp, G_VOLUME_IDENTIFIER_KIND_UNIX_DEVICE);
- if (!device_path)
- continue;
-
- BRASERO_MEDIA_LOG ("Found drive %s", device_path);
- if (!strcmp (device_path, volume_path)) {
- gdrive = tmp;
- g_free (device_path);
- g_object_ref (gdrive);
- break;
- }
-
- g_free (device_path);
- }
- g_list_foreach (drives, (GFunc) g_object_unref, NULL);
- g_list_free (drives);
-
- if (!gdrive)
- BRASERO_MEDIA_LOG ("No drive found for medium");
-
- return gdrive;
-}
-
static void
brasero_medium_monitor_medium_added_cb (BraseroDrive *drive,
BraseroMedium *medium,
@@ -351,35 +311,50 @@ brasero_medium_monitor_medium_removed_cb (BraseroDrive *drive,
medium);
}
+static gboolean
+brasero_medium_monitor_is_drive (BraseroMediumMonitor *monitor,
+ GDrive *gdrive)
+{
+ BraseroMediumMonitorPrivate *priv;
+ BraseroDeviceHandle *handle;
+ BraseroScsiErrCode code;
+ gboolean result;
+ gchar *device;
+
+ priv = BRASERO_MEDIUM_MONITOR_PRIVATE (monitor);
+
+ device = g_drive_get_identifier (gdrive, G_VOLUME_IDENTIFIER_KIND_UNIX_DEVICE);
+ BRASERO_MEDIA_LOG ("Testing drive %s", device);
+
+ handle = brasero_device_handle_open (device, FALSE, &code);
+ g_free (device);
+
+ if (!handle)
+ return FALSE;
+
+ result = (brasero_spc1_inquiry_is_optical_drive (handle, &code) == BRASERO_SCSI_OK);
+ brasero_device_handle_close (handle);
+
+ BRASERO_MEDIA_LOG ("Drive %s", result? "is optical":"is not optical");
+
+ return result;
+}
+
static void
-brasero_medium_monitor_inserted_cb (BraseroHALWatch *watch,
- const char *udi,
- BraseroMediumMonitor *self)
+brasero_medium_monitor_connected_cb (GVolumeMonitor *monitor,
+ GDrive *gdrive,
+ BraseroMediumMonitor *self)
{
BraseroMediumMonitorPrivate *priv;
BraseroDrive *drive = NULL;
- gchar *device_path;
- LibHalContext *ctx;
- GDrive *gdrive;
- ctx = brasero_hal_watch_get_ctx (watch);
- if (!libhal_device_query_capability (ctx, udi, "storage.cdrom", NULL))
+ if (!brasero_medium_monitor_is_drive (self, gdrive))
return;
BRASERO_MEDIA_LOG ("New drive added");
priv = BRASERO_MEDIUM_MONITOR_PRIVATE (self);
-
- /* Get the gdrive */
- device_path = libhal_device_get_property_string (ctx,
- udi,
- "block.device",
- NULL);
- gdrive = brasero_medium_monitor_get_gdrive (self, device_path);
- g_free (device_path);
-
drive = g_object_new (BRASERO_TYPE_DRIVE,
- "udi", udi,
"gdrive", gdrive,
NULL);
priv->drives = g_slist_prepend (priv->drives, drive);
@@ -409,32 +384,27 @@ brasero_medium_monitor_inserted_cb (BraseroHALWatch *watch,
}
static void
-brasero_medium_monitor_removed_cb (BraseroHALWatch *watch,
- const char *udi,
- BraseroMediumMonitor *self)
+brasero_medium_monitor_disconnected_cb (GVolumeMonitor *monitor,
+ GDrive *gdrive,
+ BraseroMediumMonitor *self)
{
BraseroMediumMonitorPrivate *priv;
- LibHalContext *ctx;
- GSList *iter;
GSList *next;
+ GSList *iter;
- ctx = brasero_hal_watch_get_ctx (watch);
priv = BRASERO_MEDIUM_MONITOR_PRIVATE (self);
BRASERO_MEDIA_LOG ("HAL signal device removed");
for (iter = priv->drives; iter; iter = next) {
- const gchar *device_udi;
+ GDrive *gdrive_iter;
BraseroDrive *drive;
drive = iter->data;
next = iter->next;
- device_udi = brasero_drive_get_udi (drive);
- if (!device_udi)
- continue;
-
- if (!strcmp (device_udi, udi)) {
+ gdrive_iter = brasero_drive_get_gdrive (drive);
+ if (gdrive == gdrive_iter) {
BraseroMedium *medium;
BRASERO_MEDIA_LOG ("Drive removed");
@@ -458,12 +428,9 @@ brasero_medium_monitor_removed_cb (BraseroHALWatch *watch,
static void
brasero_medium_monitor_init (BraseroMediumMonitor *object)
{
- DBusError error;
- int nb_devices, i;
- LibHalContext *ctx;
+ GList *iter;
+ GList *drives;
BraseroDrive *drive;
- char **devices = NULL;
- BraseroHALWatch *watch;
BraseroMediumMonitorPrivate *priv;
priv = BRASERO_MEDIUM_MONITOR_PRIVATE (object);
@@ -473,61 +440,38 @@ brasero_medium_monitor_init (BraseroMediumMonitor *object)
* connect to HAL before us. */
priv->gmonitor = g_volume_monitor_get ();
- watch = brasero_hal_watch_get_default ();
- ctx = brasero_hal_watch_get_ctx (watch);
-
- g_signal_connect (watch,
- "device-added",
- G_CALLBACK (brasero_medium_monitor_inserted_cb),
- object);
- g_signal_connect (watch,
- "device-removed",
- G_CALLBACK (brasero_medium_monitor_removed_cb),
- object);
+ drives = g_volume_monitor_get_connected_drives (priv->gmonitor);
+ for (iter = drives; iter; iter = iter->next) {
+ GDrive *gdrive;
- /* Now we get the list and cache it */
- dbus_error_init (&error);
- BRASERO_MEDIA_LOG ("Polling for drives");
- devices = libhal_find_device_by_capability (ctx,
- "storage.cdrom", &nb_devices,
- &error);
- if (dbus_error_is_set (&error)) {
- BRASERO_MEDIA_LOG ("Hal is not running : %s\n", error.message);
- dbus_error_free (&error);
- return;
+ gdrive = iter->data;
+ if (brasero_medium_monitor_is_drive (object, gdrive)) {
+ drive = g_object_new (BRASERO_TYPE_DRIVE,
+ "gdrive", gdrive,
+ NULL);
+ priv->drives = g_slist_prepend (priv->drives, drive);
+
+ g_signal_connect (drive,
+ "medium-added",
+ G_CALLBACK (brasero_medium_monitor_medium_added_cb),
+ object);
+ g_signal_connect (drive,
+ "medium-removed",
+ G_CALLBACK (brasero_medium_monitor_medium_removed_cb),
+ object);
+ }
}
+ g_list_foreach (drives, (GFunc) g_object_unref, NULL);
+ g_list_free (drives);
- BRASERO_MEDIA_LOG ("Found %d drives", nb_devices);
- for (i = 0; i < nb_devices; i++) {
- GDrive *gdrive;
- gchar *device_path;
-
- /* create the drive */
- BRASERO_MEDIA_LOG ("Probing %s", devices [i]);
-
- device_path = libhal_device_get_property_string (ctx,
- devices [i],
- "block.device",
- NULL);
- gdrive = brasero_medium_monitor_get_gdrive (object, device_path);
- g_free (device_path);
-
- drive = g_object_new (BRASERO_TYPE_DRIVE,
- "udi", devices [i],
- "gdrive", gdrive,
- NULL);
- priv->drives = g_slist_prepend (priv->drives, drive);
-
- g_signal_connect (drive,
- "medium-added",
- G_CALLBACK (brasero_medium_monitor_medium_added_cb),
- object);
- g_signal_connect (drive,
- "medium-removed",
- G_CALLBACK (brasero_medium_monitor_medium_removed_cb),
- object);
- }
- libhal_free_string_array (devices);
+ g_signal_connect (priv->gmonitor,
+ "drive-connected",
+ G_CALLBACK (brasero_medium_monitor_connected_cb),
+ object);
+ g_signal_connect (priv->gmonitor,
+ "drive-disconnected",
+ G_CALLBACK (brasero_medium_monitor_disconnected_cb),
+ object);
/* add fake/file drive */
drive = g_object_new (BRASERO_TYPE_DRIVE, NULL);
@@ -550,6 +494,12 @@ brasero_medium_monitor_finalize (GObject *object)
}
if (priv->gmonitor) {
+ g_signal_handlers_disconnect_by_func (priv->gmonitor,
+ brasero_medium_monitor_connected_cb,
+ object);
+ g_signal_handlers_disconnect_by_func (priv->gmonitor,
+ brasero_medium_monitor_disconnected_cb,
+ object);
g_object_unref (priv->gmonitor);
priv->gmonitor = NULL;
}
diff --git a/libbrasero-media/scsi-inquiry.c b/libbrasero-media/scsi-inquiry.c
new file mode 100644
index 0000000..8a8fb64
--- /dev/null
+++ b/libbrasero-media/scsi-inquiry.c
@@ -0,0 +1,109 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/*
+ * Libbrasero-media
+ * Copyright (C) Philippe Rouquier 2005-2009 <bonfire-app wanadoo fr>
+ *
+ * Libbrasero-media is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * The Libbrasero-media authors hereby grant permission for non-GPL compatible
+ * GStreamer plugins to be used and distributed together with GStreamer
+ * and Libbrasero-media. This permission is above and beyond the permissions granted
+ * by the GPL license by which Libbrasero-media is covered. If you modify this code
+ * you may extend this exception to your version of the code, but you are not
+ * obligated to do so. If you do not wish to do so, delete this exception
+ * statement from your version.
+ *
+ * Libbrasero-media is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to:
+ * The Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "scsi-error.h"
+#include "scsi-utils.h"
+#include "scsi-base.h"
+#include "scsi-command.h"
+#include "scsi-opcodes.h"
+
+#if G_BYTE_ORDER == G_LITTLE_ENDIAN
+
+struct _BraseroInquiryCDB {
+ uchar opcode;
+
+ uchar evpd :1;
+ uchar cmd_dt :1;
+ uchar reserved0 :6;
+
+ uchar op_code;
+
+ uchar reserved1;
+
+ uchar alloc_len;
+
+ uchar ctl;
+};
+
+#else
+
+struct _BraseroInquiryCDB {
+ uchar opcode;
+
+ uchar reserved0 :6;
+ uchar cmd_dt :1;
+ uchar evpd :1;
+
+ uchar op_code;
+
+ uchar reserved1;
+
+ uchar alloc_len;
+
+ uchar ctl;
+};
+
+#endif
+
+typedef struct _BraseroInquiryCDB BraseroInquiryCDB;
+
+BRASERO_SCSI_COMMAND_DEFINE (BraseroInquiryCDB,
+ INQUIRY,
+ BRASERO_SCSI_READ);
+
+BraseroScsiResult
+brasero_spc1_inquiry_is_optical_drive (BraseroDeviceHandle *handle,
+ BraseroScsiErrCode *error)
+{
+ BraseroInquiryCDB *cdb;
+ uchar data [36] = {0, };
+ BraseroScsiResult res;
+
+ cdb = brasero_scsi_command_new (&info, handle);
+ cdb->alloc_len = sizeof (data);
+
+ res = brasero_scsi_command_issue_sync (cdb,
+ data,
+ sizeof (data),
+ error);
+ brasero_scsi_command_free (cdb);
+
+ if (res != BRASERO_SCSI_OK)
+ return res;
+
+ /* NOTE: 0x05 is for CD/DVD players */
+ return (data [0] & 0x1F) == 0x05? BRASERO_SCSI_OK:BRASERO_SCSI_RECOVERABLE;
+}
+
+
diff --git a/libbrasero-media/scsi-spc1.h b/libbrasero-media/scsi-spc1.h
index a12d2d5..6d139ea 100644
--- a/libbrasero-media/scsi-spc1.h
+++ b/libbrasero-media/scsi-spc1.h
@@ -57,6 +57,10 @@ brasero_spc1_mode_select (BraseroDeviceHandle *handle,
int size,
BraseroScsiErrCode *error);
+BraseroScsiResult
+brasero_spc1_inquiry_is_optical_drive (BraseroDeviceHandle *handle,
+ BraseroScsiErrCode *error);
+
G_END_DECLS
#endif /* _BURN_SPC1_H */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]