[Goodies-commits] r7677 - xfburn/trunk/xfburn

David Mohr squisher at xfce.org
Sun Jul 5 02:55:15 CEST 2009


Author: squisher
Date: 2009-07-05 00:55:15 +0000 (Sun, 05 Jul 2009)
New Revision: 7677

Added:
   xfburn/trunk/xfburn/xfburn-device.c
   xfburn/trunk/xfburn/xfburn-device.h
Modified:
   xfburn/trunk/xfburn/Makefile.am
   xfburn/trunk/xfburn/xfburn-blank-dialog.c
   xfburn/trunk/xfburn/xfburn-burn-data-composition-base-dialog.c
   xfburn/trunk/xfburn/xfburn-burn-image-dialog.c
   xfburn/trunk/xfburn/xfburn-device-box.c
   xfburn/trunk/xfburn/xfburn-device-box.h
   xfburn/trunk/xfburn/xfburn-device-list.c
   xfburn/trunk/xfburn/xfburn-device-list.h
   xfburn/trunk/xfburn/xfburn-hal-manager.c
   xfburn/trunk/xfburn/xfburn-hal-manager.h
   xfburn/trunk/xfburn/xfburn-main-window.c
   xfburn/trunk/xfburn/xfburn-main.c
   xfburn/trunk/xfburn/xfburn-perform-burn.c
   xfburn/trunk/xfburn/xfburn-preferences-dialog.c
   xfburn/trunk/xfburn/xfburn-utils.c
   xfburn/trunk/xfburn/xfburn-utils.h
Log:
DeviceList and Device are now objects

Modified: xfburn/trunk/xfburn/Makefile.am
===================================================================
--- xfburn/trunk/xfburn/Makefile.am	2009-07-04 22:45:59 UTC (rev 7676)
+++ xfburn/trunk/xfburn/Makefile.am	2009-07-05 00:55:15 UTC (rev 7677)
@@ -30,6 +30,7 @@
 	xfburn-create-iso-progress-dialog.h				\
 	xfburn-hal-manager.h						\
 	xfburn-device-box.h						\
+	xfburn-device.h							\
 	xfburn-device-list.h						\
 	xfburn-progress-dialog.h					\
 	xfburn-main-window.h						\
@@ -69,6 +70,7 @@
 	xfburn-settings.c						\
 	xfburn-hal-manager.c						\
 	xfburn-device-box.c						\
+	xfburn-device.c							\
 	xfburn-device-list.c						\
 	xfburn-progress-dialog.c					\
 	xfburn-main.c							\

Modified: xfburn/trunk/xfburn/xfburn-blank-dialog.c
===================================================================
--- xfburn/trunk/xfburn/xfburn-blank-dialog.c	2009-07-04 22:45:59 UTC (rev 7676)
+++ xfburn/trunk/xfburn/xfburn-blank-dialog.c	2009-07-05 00:55:15 UTC (rev 7677)
@@ -279,9 +279,14 @@
 
 static gboolean is_valid_blank_mode (XfburnDevice *device, XfburnBlankMode mode)
 {
-  int profile_no = xfburn_device_list_get_profile_no ();
-  gboolean erasable = xfburn_device_list_disc_is_erasable ();
-  enum burn_disc_status disc_state = xfburn_device_list_get_disc_status ();
+  int profile_no;
+  gboolean erasable;
+  enum burn_disc_status disc_state;
+
+  XfburnDeviceList *devlist = xfburn_device_list_new ();
+
+  g_object_get (G_OBJECT (xfburn_device_list_get_current_device (devlist)), "profile-no", &profile_no, "erasable", &erasable, "disc-status)", &disc_state, NULL);
+  g_object_unref (devlist);
   
   if (profile_no == 0x13) {
     /* in 0x14 no blanking is needed, we can only deformat */

Modified: xfburn/trunk/xfburn/xfburn-burn-data-composition-base-dialog.c
===================================================================
--- xfburn/trunk/xfburn/xfburn-burn-data-composition-base-dialog.c	2009-07-04 22:45:59 UTC (rev 7676)
+++ xfburn/trunk/xfburn/xfburn-burn-data-composition-base-dialog.c	2009-07-05 00:55:15 UTC (rev 7677)
@@ -67,6 +67,8 @@
   */
 
   gint response;
+
+  XfburnDeviceList *devlist;
 } XfburnBurnDataCompositionBaseDialogPrivate;
 
 enum {
@@ -103,7 +105,7 @@
 */
 static void cb_check_only_iso_toggled (GtkToggleButton * button, XfburnBurnDataCompositionBaseDialog * dialog);
 static void cb_browse_iso (GtkButton * button, XfburnBurnDataCompositionBaseDialog * dialog);
-static void cb_disc_refreshed (GtkWidget *device_box, XfburnDevice *device, XfburnBurnDataCompositionBaseDialog * dialog);
+static void cb_disc_refreshed (XfburnDeviceList *devlist, XfburnDevice *device, XfburnBurnDataCompositionBaseDialog * dialog);
 static void cb_dialog_response (XfburnBurnDataCompositionBaseDialog * dialog, gint response_id,
                                 XfburnBurnDataCompositionBaseDialogPrivate * priv);
 
@@ -184,10 +186,13 @@
 
   /* burning devices list */
   priv->device_box = xfburn_device_box_new (SHOW_CD_WRITERS | SHOW_CDRW_WRITERS | SHOW_MODE_SELECTION | SHOW_SPEED_SELECTION);
-  g_signal_connect (G_OBJECT (priv->device_box), "disc-refreshed", G_CALLBACK (cb_disc_refreshed), obj);
-  g_signal_connect (G_OBJECT (priv->device_box), "device-changed", G_CALLBACK (cb_disc_refreshed), obj);
   gtk_widget_show (priv->device_box);
 
+  priv->devlist = xfburn_device_list_new ();
+  /* FIXME: change name of callback */
+  g_signal_connect (G_OBJECT (priv->devlist), "device-change-end", G_CALLBACK (cb_disc_refreshed), obj);
+  g_signal_connect (G_OBJECT (priv->devlist), "volume-change-end", G_CALLBACK (cb_disc_refreshed), obj);
+
   priv->frame_device = xfce_create_framebox_with_content (_("Burning device"), priv->device_box);
   gtk_widget_show (priv->frame_device);
   gtk_box_pack_start (box, priv->frame_device, FALSE, FALSE, BORDER);
@@ -290,7 +295,7 @@
   gtk_widget_grab_focus (button);
   gtk_widget_grab_default (button);
 
-  cb_disc_refreshed (priv->device_box, xfburn_device_box_get_selected_device (XFBURN_DEVICE_BOX (priv->device_box)), obj);
+  cb_disc_refreshed (priv->devlist, xfburn_device_box_get_selected_device (XFBURN_DEVICE_BOX (priv->device_box)), obj);
   g_signal_connect (G_OBJECT (obj), "response", G_CALLBACK (cb_dialog_response), priv);
 
   return gobj;
@@ -332,6 +337,8 @@
   XfburnBurnDataCompositionBaseDialogPrivate *priv = XFBURN_BURN_DATA_COMPOSITION_BASE_DIALOG_GET_PRIVATE (object);
 
   iso_image_unref (priv->image);
+  
+  g_object_unref (G_OBJECT (priv->devlist));
 
   G_OBJECT_CLASS (parent_class)->finalize (object);
 }
@@ -412,11 +419,13 @@
 }
 
 static void
-cb_disc_refreshed (GtkWidget *device_box, XfburnDevice *device, XfburnBurnDataCompositionBaseDialog * dialog)
+cb_disc_refreshed (XfburnDeviceList *devlist, XfburnDevice *device, XfburnBurnDataCompositionBaseDialog * dialog)
 {
   XfburnBurnDataCompositionBaseDialogPrivate *priv = XFBURN_BURN_DATA_COMPOSITION_BASE_DIALOG_GET_PRIVATE (dialog);
   gboolean valid_disc;
 
+  DBG ("trace");
+
   g_object_get (G_OBJECT (priv->device_box), "valid", &valid_disc, NULL);
 
   /*

Modified: xfburn/trunk/xfburn/xfburn-burn-image-dialog.c
===================================================================
--- xfburn/trunk/xfburn/xfburn-burn-image-dialog.c	2009-07-04 22:45:59 UTC (rev 7676)
+++ xfburn/trunk/xfburn/xfburn-burn-image-dialog.c	2009-07-05 00:55:15 UTC (rev 7677)
@@ -74,8 +74,8 @@
 static void xfburn_burn_image_dialog_init (XfburnBurnImageDialog * sp);
 
 void burn_image_dialog_error (XfburnBurnImageDialog * dialog, const gchar * msg_error);
-static void cb_device_changed (XfburnDeviceBox *box, XfburnDevice *device, XfburnBurnImageDialog * dialog);
-static void cb_disc_refreshed (XfburnDeviceBox *box, XfburnDevice *device, XfburnBurnImageDialog * dialog);
+static void cb_device_change_end (XfburnDeviceList *devlist, XfburnDevice *device, XfburnBurnImageDialog * dialog);
+static void cb_volume_change_end (XfburnDeviceList *devlist, XfburnDevice *device, XfburnBurnImageDialog * dialog);
 static void cb_dialog_response (XfburnBurnImageDialog * dialog, gint response_id, gpointer user_data);
 
 static void update_image_label (GtkFileChooser *chooser, XfburnBurnImageDialog * dialog);
@@ -131,6 +131,7 @@
   GtkWidget *frame;
   GtkWidget *vbox;
   GtkWidget *button;
+  XfburnDeviceList *devlist;
   XfburnDevice *device;
 
   gtk_window_set_title (GTK_WINDOW (obj), _("Burn image"));
@@ -208,15 +209,20 @@
   gtk_widget_grab_focus (priv->burn_button);
   gtk_widget_grab_default (priv->burn_button);
 
-  g_signal_connect (G_OBJECT (priv->device_box), "device-changed", G_CALLBACK (cb_device_changed), obj);
-  g_signal_connect (G_OBJECT (priv->device_box), "disc-refreshed", G_CALLBACK (cb_disc_refreshed), obj);
+  devlist = xfburn_device_list_new ();
+
+  g_signal_connect (G_OBJECT (devlist), "device-change-end", G_CALLBACK (cb_device_change_end), obj);
+  g_signal_connect (G_OBJECT (devlist), "volume-change-end", G_CALLBACK (cb_volume_change_end), obj);
   g_signal_connect (G_OBJECT (obj), "response", G_CALLBACK (cb_dialog_response), obj);
-  cb_disc_refreshed (XFBURN_DEVICE_BOX (priv->device_box), xfburn_device_box_get_selected_device (XFBURN_DEVICE_BOX (priv->device_box)), obj);
+  device = xfburn_device_list_get_current_device (devlist);
 
-  device = xfburn_device_box_get_selected_device (XFBURN_DEVICE_BOX (priv->device_box));
+  cb_volume_change_end (devlist, device, obj);
+
   if (device)
-    gtk_widget_set_sensitive (priv->check_dummy, device->dummy_write);
+    gtk_widget_set_sensitive (priv->check_dummy, xfburn_device_can_dummy_write (device));
 
+  g_object_unref (G_OBJECT (devlist));
+
 }
 
 /*************/
@@ -377,15 +383,15 @@
 }
 
 static void
-cb_device_changed (XfburnDeviceBox *box, XfburnDevice *device, XfburnBurnImageDialog * dialog) 
+cb_device_change_end (XfburnDeviceList *devlist, XfburnDevice *device, XfburnBurnImageDialog * dialog)
 {
   XfburnBurnImageDialogPrivate *priv = XFBURN_BURN_IMAGE_DIALOG_GET_PRIVATE (dialog);
 
-  gtk_widget_set_sensitive (priv->check_dummy, device->dummy_write);
+  gtk_widget_set_sensitive (priv->check_dummy, xfburn_device_can_dummy_write (device));
 }
 
 static void
-cb_disc_refreshed (XfburnDeviceBox *box, XfburnDevice *device, XfburnBurnImageDialog * dialog) 
+cb_volume_change_end (XfburnDeviceList *devlist, XfburnDevice *device, XfburnBurnImageDialog * dialog)
 {
   check_burn_button (dialog);
 }

Modified: xfburn/trunk/xfburn/xfburn-device-box.c
===================================================================
--- xfburn/trunk/xfburn/xfburn-device-box.c	2009-07-04 22:45:59 UTC (rev 7676)
+++ xfburn/trunk/xfburn/xfburn-device-box.c	2009-07-05 00:55:15 UTC (rev 7677)
@@ -31,7 +31,6 @@
 
 #include "xfburn-device-list.h"
 #include "xfburn-device-box.h"
-#include "xfburn-hal-manager.h"
 #include "xfburn-settings.h"
 #include "xfburn-utils.h"
 #include "xfburn-blank-dialog.h"
@@ -39,29 +38,16 @@
 #define XFBURN_DEVICE_BOX_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), XFBURN_TYPE_DEVICE_BOX, XfburnDeviceBoxPrivate))
 
 enum {
-  DEVICE_CHANGED,
-  DISC_REFRESHED,
-  LAST_SIGNAL,
-};
-
-enum {
   PROP_0,
   PROP_SHOW_WRITERS_ONLY,
   PROP_SHOW_SPEED_SELECTION,
   PROP_SHOW_MODE_SELECTION,
-  PROP_DISC_STATUS,
   PROP_VALID,
   PROP_BLANK_MODE,
   PROP_ACCEPT_ONLY_CD,
 };
 
 enum {
-  DEVICE_NAME_COLUMN,
-  DEVICE_POINTER_COLUMN,
-  DEVICE_N_COLUMNS,
-};
-
-enum {
   SPEED_TEXT_COLUMN,
   SPEED_VALUE_COLUMN,
   SPEED_N_COLUMNS,
@@ -82,7 +68,6 @@
   gboolean valid_disc;
   gboolean blank_mode;
   
-  GtkWidget *combo_device;
 
   GtkWidget *hbox_refresh;
   GtkWidget *disc_label;
@@ -94,41 +79,41 @@
   gchar *status_text;
 
   GtkWidget *hbox_mode_selection;
+  GtkWidget *combo_device;
   GtkWidget *combo_mode;
 
   gboolean have_asked_for_blanking;
   gboolean accept_only_cd;
-
-#ifdef HAVE_HAL
-  gulong volume_changed_handlerid;
-#endif
+  
+  XfburnDeviceList *devlist;
 } XfburnDeviceBoxPrivate;
 
 /* prototypes */
 static void xfburn_device_box_class_init (XfburnDeviceBoxClass *);
-static void xfburn_device_box_init (XfburnDeviceBox *);
+static GObject * xfburn_device_box_constructor (GType type, guint n_construct_properties, GObjectConstructParam *construct_properties);
 static void xfburn_device_box_finalize (GObject * object);
 static void xfburn_device_box_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec);
 static void xfburn_device_box_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec);
 
 static guint ask_for_blanking (XfburnDeviceBoxPrivate *priv);
 static void status_label_update (XfburnDeviceBoxPrivate *priv);
-static void update_status_label_visibility ();
-static XfburnDevice * get_selected_device (XfburnDeviceBoxPrivate *priv);
-static void cb_speed_refresh_clicked (GtkButton *button, XfburnDeviceBox *box);
 static gboolean check_disc_validity (XfburnDeviceBoxPrivate *priv);
-static void cb_combo_device_changed (GtkComboBox *combo, XfburnDeviceBox *box);
-#ifdef HAVE_HAL
-static void cb_volumes_changed (XfburnHalManager *halman, XfburnDeviceBox *box);
-#endif
+static void refresh_drive_info (XfburnDeviceBox *box, XfburnDevice *device);
 
+static void fill_combo_speed (XfburnDeviceBox *box, XfburnDevice *device);
+static void fill_combo_mode (XfburnDeviceBox *box, XfburnDevice *device);
+
+static void cb_device_change_start (XfburnDeviceList *devlist, XfburnDeviceBox *box);
+static void cb_device_change_end (XfburnDeviceList *devlist, XfburnDevice *device, XfburnDeviceBox *box);
+static void cb_volume_change_start (XfburnDeviceList *devlist, XfburnDevice *device, XfburnDeviceBox *box);
+static void cb_volume_change_end (XfburnDeviceList *devlist, XfburnDevice *device, XfburnDeviceBox *box);
+
 /* globals */
 static GtkVBoxClass *parent_class = NULL;
 
 /*************************/
 /* XfburnDeviceBox class */
 /*************************/
-static guint signals[LAST_SIGNAL];
 
 GType
 xfburn_device_box_get_type (void)
@@ -146,7 +131,7 @@
         NULL,
         sizeof (XfburnDeviceBox),
         0,
-        (GInstanceInitFunc) xfburn_device_box_init,
+        NULL,
         NULL
       };
 
@@ -165,20 +150,12 @@
 
   parent_class = g_type_class_peek_parent (klass);
   
-  object_class->finalize = xfburn_device_box_finalize;
+  object_class->constructor  = xfburn_device_box_constructor;
+  object_class->finalize     = xfburn_device_box_finalize;
   object_class->set_property = xfburn_device_box_set_property;
   object_class->get_property = xfburn_device_box_get_property;
   
-  signals[DEVICE_CHANGED] = g_signal_new ("device-changed", XFBURN_TYPE_DEVICE_BOX, G_SIGNAL_ACTION,
-                                          G_STRUCT_OFFSET (XfburnDeviceBoxClass, device_changed),
-                                          NULL, NULL, g_cclosure_marshal_VOID__STRING,
-                                          G_TYPE_NONE, 1, G_TYPE_STRING);
-  signals[DISC_REFRESHED] = g_signal_new ("disc-refreshed", XFBURN_TYPE_DEVICE_BOX, G_SIGNAL_ACTION,
-                                          G_STRUCT_OFFSET (XfburnDeviceBoxClass, disc_refreshed),
-                                          NULL, NULL, g_cclosure_marshal_VOID__STRING,
-                                          G_TYPE_NONE, 1, G_TYPE_STRING);
     
-    
   g_object_class_install_property (object_class, PROP_SHOW_WRITERS_ONLY, 
                                    g_param_spec_boolean ("show-writers-only", _("Show writers only"),
                                                         _("Show writers only"), FALSE, G_PARAM_READWRITE));
@@ -190,10 +167,6 @@
                                    g_param_spec_boolean ("show-mode-selection", _("Show mode selection"),
                                                         _("Show mode selection combo"), 
                                                         FALSE, G_PARAM_READWRITE));
-  g_object_class_install_property (object_class, PROP_DISC_STATUS,
-                                   g_param_spec_int ("disc-status", _("Disc status"),
-                                                      _("The status of the disc in the drive"), 
-                                                      0, BURN_DISC_UNSUITABLE, 0, G_PARAM_READABLE));
   g_object_class_install_property (object_class, PROP_VALID, 
                                    g_param_spec_boolean ("valid", _("Is it a valid combination"),
                                                         _("Is the combination of hardware and disc valid to burn the composition?"), 
@@ -208,42 +181,33 @@
                                                         FALSE, G_PARAM_READWRITE));
 }
 
-static void
-xfburn_device_box_init (XfburnDeviceBox * box)
+static GObject * 
+xfburn_device_box_constructor (GType type, guint n_construct_properties, GObjectConstructParam *construct_properties)
 {
-  XfburnDeviceBoxPrivate *priv = XFBURN_DEVICE_BOX_GET_PRIVATE (box);
+  GObject *gobj;
+  XfburnDeviceBox *box;
+  XfburnDeviceBoxPrivate *priv;
 
-  GtkWidget *label, *img, *button;
-  GList *device = NULL;
+  GtkWidget *label;
+  //GtkWidget *hbox;
   GtkListStore *store = NULL;
   GtkCellRenderer *cell;
-  //GtkWidget *hbox;
-  gboolean have_device;
+  XfburnDeviceList *devlist;
+  gint n_burners;
   
-  /* devices */
-  store = gtk_list_store_new (DEVICE_N_COLUMNS, G_TYPE_STRING, G_TYPE_POINTER);
-  priv->combo_device = gtk_combo_box_new_with_model (GTK_TREE_MODEL (store));
-  g_object_unref (store);
+  gobj = G_OBJECT_CLASS (parent_class)->constructor (type, n_construct_properties, construct_properties);
+  box = XFBURN_DEVICE_BOX (gobj);
+  priv = XFBURN_DEVICE_BOX_GET_PRIVATE (box);
 
-  cell = gtk_cell_renderer_text_new ();
-  gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (priv->combo_device), cell, TRUE);
-  gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (priv->combo_device), cell, "text", DEVICE_NAME_COLUMN, NULL);
-  gtk_widget_show (priv->combo_device);
-  gtk_box_pack_start (GTK_BOX (box), priv->combo_device, FALSE, FALSE, BORDER);
+  priv->devlist = devlist = xfburn_device_list_new ();
+  g_signal_connect (G_OBJECT (devlist), "device-change-start", G_CALLBACK (cb_device_change_start), box);
+  g_signal_connect (G_OBJECT (devlist), "device-change-end", G_CALLBACK (cb_device_change_end), box);
+  g_signal_connect (G_OBJECT (devlist), "volume-change-start", G_CALLBACK (cb_volume_change_start), box);
+  g_signal_connect (G_OBJECT (devlist), "volume-change-end", G_CALLBACK (cb_volume_change_end), box);
 
-  device = xfburn_device_list_get_list ();
-  have_device = (device != NULL);
-
-  while (device) {
-    XfburnDevice *device_data = (XfburnDevice *) device->data;
-    GtkTreeIter iter;
-
-    gtk_list_store_append (store, &iter);
-    gtk_list_store_set (store, &iter, DEVICE_NAME_COLUMN, device_data->name, DEVICE_POINTER_COLUMN, device_data, -1);
-
-    device = g_list_next (device);
-  }
-  gtk_widget_set_sensitive (priv->combo_device, have_device);
+  /* devices */
+  priv->combo_device = xfburn_device_list_get_device_combo (devlist);
+  gtk_box_pack_start (GTK_BOX (box), priv->combo_device, FALSE, FALSE, BORDER);
   
   /*
   hbox = gtk_hbox_new (FALSE, 0);
@@ -261,17 +225,8 @@
   gtk_box_pack_start (GTK_BOX (priv->hbox_refresh), priv->disc_label, TRUE, TRUE, BORDER);
 
   /* refresh */
-  img = gtk_image_new_from_stock (GTK_STOCK_REFRESH, GTK_ICON_SIZE_SMALL_TOOLBAR);
-  gtk_widget_show (img);
-  button = gtk_button_new ();
-  gtk_container_add (GTK_CONTAINER (button), img);
-  gtk_widget_show (button);
-  //gtk_box_pack_start (GTK_BOX (priv->hbox_speed_selection), button, FALSE, FALSE, 0);
-  gtk_box_pack_start (GTK_BOX (priv->hbox_refresh), button, FALSE, FALSE, BORDER);
-  gtk_widget_set_sensitive (button, have_device);
+  gtk_box_pack_start (GTK_BOX (priv->hbox_refresh), xfburn_device_list_get_refresh_button (devlist), FALSE, FALSE, BORDER);
 
-  g_signal_connect (G_OBJECT (button), "clicked", G_CALLBACK (cb_speed_refresh_clicked), box);
-
   /* speed */
   priv->hbox_speed_selection = gtk_hbox_new (FALSE, 0);
   gtk_widget_show (priv->hbox_speed_selection);
@@ -309,7 +264,8 @@
   gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (priv->combo_mode), cell, "text", MODE_TEXT_COLUMN, NULL);
   gtk_widget_show (priv->combo_mode);
   gtk_box_pack_start (GTK_BOX (priv->hbox_mode_selection), priv->combo_mode, TRUE, TRUE, BORDER);
-  gtk_widget_set_sensitive (priv->combo_mode, have_device);
+  g_object_get (G_OBJECT (devlist), "num-burners", &n_burners, NULL);
+  gtk_widget_set_sensitive (priv->combo_mode, n_burners > 0);
 
   /* status label */
   priv->status_label = gtk_label_new ("");
@@ -317,26 +273,19 @@
   gtk_widget_show (priv->status_label);
   gtk_box_pack_start (GTK_BOX (box), priv->status_label, FALSE, FALSE, 0);
 
-  gtk_combo_box_set_active (GTK_COMBO_BOX (priv->combo_device), 0);
-  g_signal_connect (G_OBJECT (priv->combo_device), "changed", G_CALLBACK (cb_combo_device_changed), box);
+  priv->have_asked_for_blanking = FALSE;
 
-#ifdef HAVE_HAL
-  priv->volume_changed_handlerid = g_signal_connect (G_OBJECT (xfburn_hal_manager_get_instance ()), "volume-changed", G_CALLBACK (cb_volumes_changed), box);
-#endif
+  refresh_drive_info (box, xfburn_device_list_get_current_device (priv->devlist));
 
-  priv->have_asked_for_blanking = FALSE;
+  return gobj;
 }
 
 static void
 xfburn_device_box_finalize (GObject * object)
 {
-#ifdef HAVE_HAL
   XfburnDeviceBoxPrivate *priv = XFBURN_DEVICE_BOX_GET_PRIVATE (object);
 
-  //g_object_unref (priv->hal_manager);
-  g_signal_handler_disconnect (xfburn_hal_manager_get_instance (), priv->volume_changed_handlerid);
-#endif
-
+  g_object_unref (G_OBJECT (priv->devlist));
   G_OBJECT_CLASS (parent_class)->finalize (object);
 }
 
@@ -355,9 +304,6 @@
     case PROP_SHOW_MODE_SELECTION:
       g_value_set_boolean (value, priv->show_mode_selection);
       break;
-    case PROP_DISC_STATUS:
-      g_value_set_int (value, xfburn_device_list_get_disc_status());
-      break;
     case PROP_VALID:
       g_value_set_boolean (value, priv->valid_disc);
       break;
@@ -384,19 +330,19 @@
       break;
     case PROP_SHOW_SPEED_SELECTION:
       priv->show_speed_selection = g_value_get_boolean (value);
-      if (priv->show_speed_selection)
+      if (priv->show_speed_selection) {
         gtk_widget_show (priv->hbox_speed_selection);
-      else
+        fill_combo_speed (XFBURN_DEVICE_BOX (object), xfburn_device_list_get_current_device (priv->devlist));
+      } else
         gtk_widget_hide (priv->hbox_speed_selection);
-      update_status_label_visibility (priv);
       break;
     case PROP_SHOW_MODE_SELECTION:
       priv->show_mode_selection = g_value_get_boolean (value);
-      if (priv->show_mode_selection)
+      if (priv->show_mode_selection) {
         gtk_widget_show (priv->hbox_mode_selection);
-      else
+        fill_combo_mode (XFBURN_DEVICE_BOX (object), xfburn_device_list_get_current_device (priv->devlist));
+      } else
         gtk_widget_hide (priv->hbox_mode_selection);
-      update_status_label_visibility (priv);
       break;
     case PROP_BLANK_MODE:
       priv->blank_mode = g_value_get_boolean (value);
@@ -415,18 +361,6 @@
 /*************/
 
 static void
-update_status_label_visibility (XfburnDeviceBoxPrivate *priv)
-{
-  /*
-  if (priv->show_mode_selection || priv->show_speed_selection)
-    gtk_widget_show (priv->status_label);
-  else
-    gtk_widget_hide (priv->status_label);
-  */
-
-}
-
-static void
 empty_speed_list_dialog ()
 {
   GtkDialog *dialog;
@@ -476,11 +410,16 @@
 {
   XfburnDeviceBoxPrivate *priv = XFBURN_DEVICE_BOX_GET_PRIVATE (box);
   GtkTreeModel *model = gtk_combo_box_get_model (GTK_COMBO_BOX (priv->combo_speed));
-  GSList *el = device->supported_cdr_speeds;
-  int profile_no = xfburn_device_list_get_profile_no ();
+  GSList *el;
+  int profile_no;
   int factor;
   GtkTreeIter iter_max;
 
+  g_object_get (G_OBJECT (xfburn_device_list_get_current_device (priv->devlist)),
+                "profile-no", &profile_no,
+                "supported-speeds", &el,
+                NULL);
+
   gtk_list_store_clear (GTK_LIST_STORE (model));
 
   if (el == NULL) {
@@ -575,12 +514,20 @@
 static gboolean
 check_disc_validity (XfburnDeviceBoxPrivate *priv)
 {
-  enum burn_disc_status disc_status = xfburn_device_list_get_disc_status ();
-  int profile_no = xfburn_device_list_get_profile_no ();
-  gboolean is_erasable = xfburn_device_list_disc_is_erasable ();
-  XfburnDevice *device = get_selected_device (priv);
+  enum burn_disc_status disc_status;
+  int profile_no;
+  gchar *profile_name;
+  gboolean is_erasable;
+  XfburnDevice *device;
+
+  g_object_get (G_OBJECT (priv->devlist), "current-device", &device, NULL);
+
+  g_object_get (G_OBJECT (device), "disc-status", &disc_status, "profile-no", &profile_no, 
+                                   "erasable", &is_erasable, "profile-name", &profile_name,
+                                   NULL);
   
-  gtk_label_set_text (GTK_LABEL (priv->disc_label), xfburn_device_list_get_profile_name ());
+  gtk_label_set_text (GTK_LABEL (priv->disc_label), profile_name);
+  g_free (profile_name);
 
   if (!priv->blank_mode) {
     /* for burning */
@@ -591,14 +538,14 @@
         priv->valid_disc = TRUE;
         break;
       case XFBURN_PROFILE_CDR:
-        priv->valid_disc = device->cdr;
+        g_object_get (G_OBJECT (device), "cdr", &priv->valid_disc, NULL);
         break;
       case XFBURN_PROFILE_CDRW:
-        priv->valid_disc = device->cdrw;
+        g_object_get (G_OBJECT (device), "cdrw", &priv->valid_disc, NULL);
         break;
       case XFBURN_PROFILE_DVDRAM:
         if (!priv->accept_only_cd)
-          priv->valid_disc = device->dvdram;
+          g_object_get (G_OBJECT (device), "dvdram", &priv->valid_disc, NULL);
         break;
       case XFBURN_PROFILE_DVD_MINUS_R:
       case XFBURN_PROFILE_DVD_MINUS_RW_OVERWRITE:
@@ -608,7 +555,7 @@
       case XFBURN_PROFILE_DVD_PLUS_R_DL:
       case XFBURN_PROFILE_DVD_PLUS_RW:
         if (!priv->accept_only_cd)
-          priv->valid_disc = device->dvdr;
+          g_object_get (G_OBJECT (device), "dvdr", &priv->valid_disc, NULL);
         break;
       default:
         g_warning ("Unknown disc profile 0x%x!", profile_no);
@@ -706,14 +653,18 @@
   XfburnDeviceBoxPrivate *priv = XFBURN_DEVICE_BOX_GET_PRIVATE (box);
   GtkTreeModel *model = gtk_combo_box_get_model (GTK_COMBO_BOX (priv->combo_mode));
   GtkTreeIter iter;
+  gint block_types;
 
   gtk_list_store_clear (GTK_LIST_STORE (model));
 
-  if (device->tao_block_types) {
+  g_object_get (G_OBJECT (device), "tao-block-types", &block_types, NULL);
+  if (block_types) {
     gtk_list_store_append (GTK_LIST_STORE (model), &iter);
     gtk_list_store_set (GTK_LIST_STORE (model), &iter, MODE_TEXT_COLUMN, "TAO", MODE_VALUE_COLUMN, WRITE_MODE_TAO, -1);
   }
-  if (device->sao_block_types & BURN_BLOCK_SAO) {
+
+  g_object_get (G_OBJECT (device), "sao-block-types", &block_types, NULL);
+  if (block_types & BURN_BLOCK_SAO) {
     gtk_list_store_append (GTK_LIST_STORE (model), &iter);
     gtk_list_store_set (GTK_LIST_STORE (model), &iter, MODE_TEXT_COLUMN, "SAO", MODE_VALUE_COLUMN, WRITE_MODE_SAO, -1);
   }
@@ -741,89 +692,61 @@
   gtk_combo_box_set_active (GTK_COMBO_BOX (priv->combo_mode), 0);
 }
 
-static XfburnDevice *
-get_selected_device (XfburnDeviceBoxPrivate *priv)
+static void
+cb_device_change_start (XfburnDeviceList *devlist, XfburnDeviceBox *box)
 {
-
-  GtkTreeModel *model;
-  GtkTreeIter iter;
-  XfburnDevice * device = NULL;
-  gboolean ret;
-
-  model = gtk_combo_box_get_model (GTK_COMBO_BOX (priv->combo_device));
-  ret = gtk_combo_box_get_active_iter (GTK_COMBO_BOX (priv->combo_device), &iter);
-  if (ret)
-    gtk_tree_model_get (model, &iter, DEVICE_POINTER_COLUMN, &device, -1);
-
-  return device;
+  if (GTK_WIDGET_REALIZED (box))
+    xfburn_busy_cursor (GTK_WIDGET (box));
 }
 
-static XfburnDevice *
-refresh_drive_info (XfburnDeviceBox *box)
+static void
+cb_device_change_end (XfburnDeviceList *devlist, XfburnDevice *device, XfburnDeviceBox *box)
 {
-  XfburnDeviceBoxPrivate *priv = XFBURN_DEVICE_BOX_GET_PRIVATE (box);
-  XfburnDevice *device = NULL;
-  
-  device = xfburn_device_box_get_selected_device (box);
-  if (G_UNLIKELY (device == NULL))
-    return NULL;
+  /* FIXME: adjust selected device?  */
 
-  if (!xfburn_device_refresh_info (device, priv->show_speed_selection))
-    return NULL;
+  cb_volume_change_end (devlist, device, box);
 
-  if (priv->show_speed_selection)
-    fill_combo_speed (box, device);
-
-  if (priv->show_mode_selection)
-    fill_combo_mode (box,device);
-
-  if (!check_disc_validity (priv))
-    return NULL;
-
-  return device;
+  /* not going back to a regular cursor, that'll happen in cb_volume_change_end */
 }
 
 static void
-cb_speed_refresh_clicked (GtkButton *button, XfburnDeviceBox *box)
+cb_volume_change_start (XfburnDeviceList *devlist, XfburnDevice *device, XfburnDeviceBox *box)
 {
-  XfburnDeviceBoxPrivate *priv = XFBURN_DEVICE_BOX_GET_PRIVATE (box);
-  XfburnDevice *device;
-  
-  xfburn_busy_cursor (priv->combo_device);
-
-  device = refresh_drive_info (box);
-
-  xfburn_default_cursor (priv->combo_device);
-
-  if (device == NULL)
-    return;
-
-  g_signal_emit (G_OBJECT (box), signals[DISC_REFRESHED], 0, device);
+  if (GTK_WIDGET_REALIZED (box))
+    xfburn_busy_cursor (GTK_WIDGET (box));
 }
 
 static void
-cb_combo_device_changed (GtkComboBox *combo, XfburnDeviceBox *box)
+cb_volume_change_end (XfburnDeviceList *devlist, XfburnDevice *device, XfburnDeviceBox *box)
 {
-  //XfburnDeviceBoxPrivate *priv = XFBURN_DEVICE_BOX_GET_PRIVATE (box);
-  XfburnDevice *device;
-  
-  if (GTK_WIDGET_REALIZED (box))
-    xfburn_busy_cursor (GTK_WIDGET (box));
+  g_return_if_fail (XFBURN_IS_DEVICE_LIST (devlist));
+  g_return_if_fail (XFBURN_IS_DEVICE (device));
+  g_return_if_fail (XFBURN_IS_DEVICE_BOX (box));
 
-  device = refresh_drive_info (box);
+  refresh_drive_info (box, device);
 
   if (GTK_WIDGET_REALIZED (box))
     xfburn_default_cursor (GTK_WIDGET (box));
+}
 
-  if (device == NULL)
-    return;
+static void 
+refresh_drive_info (XfburnDeviceBox *box, XfburnDevice *device)
+{
+  XfburnDeviceBoxPrivate *priv = XFBURN_DEVICE_BOX_GET_PRIVATE (box);
 
-  g_signal_emit (G_OBJECT (box), signals[DEVICE_CHANGED], 0, device);
+  if (priv->show_speed_selection)
+    fill_combo_speed (box, device);
+
+  if (priv->show_mode_selection)
+    fill_combo_mode (box, device);
+
+  /* FIXME: where to put this? */
+  check_disc_validity (priv);
 }
 
-#ifdef HAVE_HAL
+/*
 static void
-cb_volumes_changed (XfburnHalManager *halman, XfburnDeviceBox *box)
+cb_volumes_changed (XfburnHalManager *halman, XfburnDeviceList *devlist)
 {
   gboolean visible;
 
@@ -834,17 +757,8 @@
     cb_speed_refresh_clicked (NULL, box);
   }
 }
-#endif
+*/
 
-static void
-refresh (GtkWidget *widget)
-{
-  XfburnDeviceBox *box = XFBURN_DEVICE_BOX (widget);
-  XfburnDeviceBoxPrivate *priv = XFBURN_DEVICE_BOX_GET_PRIVATE (box);
-
-  cb_combo_device_changed (GTK_COMBO_BOX (priv->combo_device), box);
-}
-
 /******************/
 /* public methods */
 /******************/
@@ -861,36 +775,9 @@
 		      "accept-only-cd", ((flags & ACCEPT_ONLY_CD) != 0),
                       NULL);
   
-  refresh (obj);
-
   return obj;
 }
 
-gchar *
-xfburn_device_box_get_selected (XfburnDeviceBox *box)
-{
-  XfburnDeviceBoxPrivate *priv = XFBURN_DEVICE_BOX_GET_PRIVATE (box);
-  GtkTreeModel *model;
-  GtkTreeIter iter;
-  gchar *name = NULL;
-  gboolean ret;
-
-  model = gtk_combo_box_get_model (GTK_COMBO_BOX (priv->combo_device));
-  ret = gtk_combo_box_get_active_iter (GTK_COMBO_BOX (priv->combo_device), &iter);
-  if (ret)
-    gtk_tree_model_get (model, &iter, DEVICE_NAME_COLUMN, &name, -1);
-
-  return name;
-}
-
-XfburnDevice *
-xfburn_device_box_get_selected_device (XfburnDeviceBox *box)
-{
-  XfburnDeviceBoxPrivate *priv = XFBURN_DEVICE_BOX_GET_PRIVATE (box);
-
-  return get_selected_device (priv);
-}
-
 gint
 xfburn_device_box_get_speed (XfburnDeviceBox *box)
 {
@@ -941,3 +828,12 @@
 
   return mode;
 }
+
+
+XfburnDevice *
+xfburn_device_box_get_selected_device (XfburnDeviceBox *box)
+{
+  XfburnDeviceBoxPrivate *priv = XFBURN_DEVICE_BOX_GET_PRIVATE (box);
+
+  return xfburn_device_list_get_current_device (priv->devlist);
+}

Modified: xfburn/trunk/xfburn/xfburn-device-box.h
===================================================================
--- xfburn/trunk/xfburn/xfburn-device-box.h	2009-07-04 22:45:59 UTC (rev 7676)
+++ xfburn/trunk/xfburn/xfburn-device-box.h	2009-07-05 00:55:15 UTC (rev 7677)
@@ -45,9 +45,6 @@
 typedef struct
 {
   GtkVBoxClass parent_class;
-  
-  void (*device_changed) (XfburnDeviceBox *box, XfburnDevice *device);
-  void (*disc_refreshed) (XfburnDeviceBox *box, XfburnDevice *device);
 } XfburnDeviceBoxClass;
 
 typedef enum
@@ -79,7 +76,6 @@
 
 GtkWidget *xfburn_device_box_new (XfburnDeviceBoxFlags);
 
-gchar *xfburn_device_box_get_selected (XfburnDeviceBox *box);
 XfburnDevice *xfburn_device_box_get_selected_device (XfburnDeviceBox *box);
 
 gint xfburn_device_box_get_speed (XfburnDeviceBox *box);

Modified: xfburn/trunk/xfburn/xfburn-device-list.c
===================================================================
--- xfburn/trunk/xfburn/xfburn-device-list.c	2009-07-04 22:45:59 UTC (rev 7676)
+++ xfburn/trunk/xfburn/xfburn-device-list.c	2009-07-05 00:55:15 UTC (rev 7677)
@@ -35,424 +35,515 @@
 
 #include "xfburn-global.h"
 #include "xfburn-hal-manager.h"
+#include "xfburn-utils.h"
 
 #include "xfburn-device-list.h"
 
-static GList *devices = NULL;
-static enum burn_disc_status disc_status;
-static int profile_no = 0;
-static char profile_name[80];
-static int is_erasable = 0;
-static char * libburn_msg_prefix = "libburn-";
+/*- private prototypes -*/
 
-#define DEVICE_INFO_PRINTF "%s can burn: %d [cdr: %d, cdrw: %d, dvdr: %d, dvdram: %d]", device->name, XFBURN_DEVICE_LIST_CAN_BURN_CONDITION(device), device->cdr, device->cdrw, device->dvdr, device->dvdram
+typedef struct _XfburnDeviceListPrivate XfburnDeviceListPrivate;
 
-/*************/
-/* internals */
-/*************/
+struct _XfburnDeviceListPrivate {
+  GList *devices;
+  guint num_drives;
+  guint num_burners;
+  XfburnDevice *curr_device;
+
+#ifdef HAVE_HAL
+  gulong volume_changed_handlerid;
+#endif
+};
+
+void get_libburn_device_list (XfburnDeviceList *devlist);
+static void cb_combo_device_changed (GtkComboBox *combo, XfburnDeviceList *devlist);
+static void cb_refresh_clicked (GtkButton *button, XfburnDeviceList *devlist);
+#ifdef HAVE_HAL
+static void cb_volumes_changed (XfburnHalManager *halman, XfburnDeviceList *devlist);
+#endif
+static XfburnDevice * get_selected_device (GtkComboBox *combo_device);
+static void refresh (XfburnDeviceList *devlist);
+
+/*- globals -*/
+static GObjectClass *parent_class = NULL;
+
+enum {
+  PROP_0,
+  PROP_NUM_DRIVES,
+  PROP_NUM_BURNERS,
+  PROP_DEVICES,
+  PROP_CURRENT_DEVICE,
+};
+
+enum {
+  DEVICE_CHANGE_START,
+  DEVICE_CHANGE_END,
+  VOLUME_CHANGE_START,
+  VOLUME_CHANGE_END,
+  LAST_SIGNAL,
+};
+
+enum {
+  DEVICE_NAME_COLUMN,
+  DEVICE_POINTER_COLUMN,
+  DEVICE_N_COLUMNS,
+};
+
+static guint signals[LAST_SIGNAL];
+
+
+/*****************/
+/*- class setup -*/
+/*****************/
+
+G_DEFINE_TYPE (XfburnDeviceList, xfburn_device_list, G_TYPE_OBJECT)
+
+#define GET_PRIVATE(o) \
+  (G_TYPE_INSTANCE_GET_PRIVATE ((o), XFBURN_TYPE_DEVICE_LIST, XfburnDeviceListPrivate))
+
 static void
-device_content_free (XfburnDevice * device, gpointer user_data)
+xfburn_device_list_get_property (GObject *object, guint property_id,
+                              GValue *value, GParamSpec *pspec)
 {
-  g_free (device->name);
+  XfburnDeviceListPrivate *priv = GET_PRIVATE (XFBURN_DEVICE_LIST (object));
 
-  g_slist_free (device->supported_cdr_speeds);
+  switch (property_id) {
+    case PROP_NUM_DRIVES:
+      g_value_set_int (value, priv->num_drives);
+      break;
+    case PROP_NUM_BURNERS:
+      g_value_set_int (value, priv->num_burners);
+      break;
+    case PROP_DEVICES:
+      g_value_set_pointer (value, priv->devices);
+      break;
+    case PROP_CURRENT_DEVICE:
+      g_value_set_object (value, priv->curr_device);
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+  }
 }
 
-static gboolean
-no_speed_duplicate (GSList *speed_list, gint speed)
+static void
+xfburn_device_list_set_property (GObject *object, guint property_id,
+                              const GValue *value, GParamSpec *pspec)
 {
-  GSList *el = speed_list;
+  XfburnDeviceListPrivate *priv = GET_PRIVATE (XFBURN_DEVICE_LIST (object));
 
-  while (el) {
-    gint el_speed = GPOINTER_TO_INT (el->data);
+  switch (property_id) {
+    case PROP_NUM_DRIVES:
+      /* FIXME: should this be there? */
+      priv->num_drives = g_value_get_int (value);
+      break;
+    case PROP_NUM_BURNERS:
+      /* FIXME: should this be there? */
+      priv->num_burners = g_value_get_int (value);
+      break;
+    case PROP_DEVICES:
+      /* FIXME: should this be there? */
+      priv->devices = g_value_get_pointer (value);
+      break;
+    case PROP_CURRENT_DEVICE:
+      priv->curr_device = g_value_get_object (value);
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+  }
+}
 
-    if (el_speed == speed)
-      return FALSE;
+/* implement a singleton pattern */
+static GObject*
+xfburn_device_list_constructor (GType type, guint n_construct_params, GObjectConstructParam *construct_params)
+{
+  GObject *object;
+  static XfburnDeviceList *global = NULL;
 
-    el = g_slist_next (el);
+  if (!global) {
+    object = G_OBJECT_CLASS (parent_class)->constructor (type, n_construct_params, construct_params);
+
+    global = XFBURN_DEVICE_LIST (object);
+  } else {
+    object = g_object_ref (G_OBJECT (global));
   }
 
-  return TRUE;
+  return object;
 }
 
-/* sort the speed list in ascending order */
-static gint
-cmp_ints (gconstpointer a, gconstpointer b)
+static void
+xfburn_device_list_finalize (GObject *object)
 {
-  return GPOINTER_TO_INT(a) - GPOINTER_TO_INT(b);
+  XfburnDeviceList *devlist = XFBURN_DEVICE_LIST (object);
+  XfburnDeviceListPrivate *priv = GET_PRIVATE (devlist);
+
+  g_list_foreach (priv->devices, (GFunc) g_object_unref, NULL);
+  g_list_free (priv->devices);
+
+  G_OBJECT_CLASS (parent_class)->finalize (object);
 }
 
 static void
-refresh_disc (XfburnDevice * device, struct burn_drive_info *drive_info)
+xfburn_device_list_class_init (XfburnDeviceListClass *klass)
 {
-  gint ret;
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
 
-  /* check if there is a disc in the drive */
-  while ((disc_status = burn_disc_get_status (drive_info->drive)) == BURN_DISC_UNREADY)
-    usleep(100001);
+  parent_class = g_type_class_peek_parent (klass);
+  g_type_class_add_private (klass, sizeof (XfburnDeviceListPrivate));
 
-  DBG ("disc_status = %d", disc_status);
+  object_class->get_property = xfburn_device_list_get_property;
+  object_class->set_property = xfburn_device_list_set_property;
+  object_class->constructor  = xfburn_device_list_constructor;
+  object_class->finalize     = xfburn_device_list_finalize;
 
-  if ((ret = burn_disc_get_profile(drive_info->drive, &profile_no, profile_name)) != 1) {
-    g_warning ("no profile could be retrieved");
-  }
-  is_erasable = burn_disc_erasable (drive_info->drive);
-  DBG ("profile_no = 0x%x (%s), %s erasable", profile_no, profile_name, (is_erasable ? "" : "NOT"));
+  signals[DEVICE_CHANGE_START] = g_signal_new ("device-change-start", XFBURN_TYPE_DEVICE_LIST, G_SIGNAL_ACTION,
+                                          0,
+                                          NULL, NULL, g_cclosure_marshal_VOID__VOID,
+                                          G_TYPE_NONE, 1, G_TYPE_STRING);
+  signals[DEVICE_CHANGE_END] = g_signal_new ("device-change-end", XFBURN_TYPE_DEVICE_LIST, G_SIGNAL_ACTION,
+                                          G_STRUCT_OFFSET (XfburnDeviceListClass, device_changed),
+                                          NULL, NULL, g_cclosure_marshal_VOID__OBJECT,
+                                          G_TYPE_NONE, 1, XFBURN_TYPE_DEVICE);
+  signals[VOLUME_CHANGE_START] = g_signal_new ("volume-change-start", XFBURN_TYPE_DEVICE_LIST, G_SIGNAL_ACTION,
+                                          0,
+                                          NULL, NULL, g_cclosure_marshal_VOID__OBJECT,
+                                          G_TYPE_NONE, 1, XFBURN_TYPE_DEVICE);
+  signals[VOLUME_CHANGE_END] = g_signal_new ("volume-change-end", XFBURN_TYPE_DEVICE_LIST, G_SIGNAL_ACTION,
+                                          G_STRUCT_OFFSET (XfburnDeviceListClass, volume_changed),
+                                          NULL, NULL, g_cclosure_marshal_VOID__OBJECT,
+                                          G_TYPE_NONE, 1, XFBURN_TYPE_DEVICE);
+    
+  g_object_class_install_property (object_class, PROP_NUM_BURNERS, 
+                                   g_param_spec_int ("num-burners", _("Number of burners in the system"),
+                                                     _("Number of burners in the system"), 0, G_MAXINT, 0, G_PARAM_READABLE));
+  g_object_class_install_property (object_class, PROP_NUM_DRIVES, 
+                                   g_param_spec_int ("num-drives", _("Number of drives in the system"),
+                                                     _("Number of drives in the system (readers and writers)"), 0, G_MAXINT, 0, G_PARAM_READABLE));
+  g_object_class_install_property (object_class, PROP_DEVICES, 
+                                   g_param_spec_pointer ("devices", _("List of devices"),
+                                                         _("List of devices"), G_PARAM_READABLE));
+  g_object_class_install_property (object_class, PROP_CURRENT_DEVICE, 
+                                   g_param_spec_object ("current-device", _("Currently selected device"),
+                                                        _("Currently selected device"), XFBURN_TYPE_DEVICE, G_PARAM_READWRITE));
+
+  //klass->device_changed = cb_device_changed;
+  //klass->volume_changed = cb_volume_changed
 }
 
+#if 0
 static void
-refresh_speed_list (XfburnDevice * device, struct burn_drive_info *drive_info)
+xfburn_device_list_init (XfburnDeviceList *self)
 {
-  struct burn_speed_descriptor *speed_list = NULL;
-  gint ret;
+  XfburnDeviceListPrivate *priv = GET_PRIVATE (self);
 
-  /* fill new list */
-  ret = burn_drive_get_speedlist (drive_info->drive, &speed_list);
-  /* speed_list = NULL; DEBUG */ 
+#ifdef HAVE_HAL
+  XfburnHalManager *halman = xfburn_hal_manager_get_global ();
+#endif
 
-  if (ret > 0 && speed_list != NULL) {
-    struct burn_speed_descriptor *el = speed_list;
+  DBG ("Constructing device list");
+  xfburn_console_libburn_messages ();
 
-    while (el) {
-      gint speed = el->write_speed;
-      
-      /* FIXME: why do we need no_speed_duplicate? */
-      if (speed > 0 && no_speed_duplicate (device->supported_cdr_speeds, speed)) {
-          device->supported_cdr_speeds = g_slist_prepend (device->supported_cdr_speeds, GINT_TO_POINTER (speed));
-      } 
+#ifdef HAVE_HAL
+  /* FIXME: hal_manager currently only returns burners, not readers */
+  priv->num_drives = priv->num_burners = xfburn_hal_manager_get_devices (halman, &priv->devices);
+  if (priv->num_burners < 1) {
+    /* if some error occurred while checking hal properties,
+       or hal for some reason did not find a device, then just
+       fall back on libburn */
+    g_message ("HAL said there are %d burners, checking libburn if it can detect any", priv->num_burners);
 
-      el = el->next;
-    }
+    get_libburn_device_list (self);
+  }
 
-    burn_drive_free_speedlist (&speed_list); 
-    device->supported_cdr_speeds = g_slist_sort (device->supported_cdr_speeds, &cmp_ints);
-  } else if (ret == 0 || speed_list == NULL) {
-    g_warning ("reported speed list is empty for device:");
-    g_warning (DEVICE_INFO_PRINTF);
-  } else {
-    /* ret < 0 */
-    g_error ("severe error while retrieving speed list");
-  }
+  priv->volume_changed_handlerid = g_signal_connect (G_OBJECT (xfburn_hal_manager_get_global ()), "volume-changed", G_CALLBACK (cb_volumes_changed), self);
+
+#else
+  get_libburn_device_list (self);
+#endif
 }
+#endif
 
-void
-fillin_libburn_device_info (XfburnDevice *device, struct burn_drive_info *drives)
+static void
+xfburn_device_list_init (XfburnDeviceList *self)
 {
-  device->accessible = TRUE;
+  XfburnDeviceListPrivate *priv = GET_PRIVATE (self);
 
-  device->cdr = drives->write_cdr;
-  device->cdrw = drives->write_cdrw;
+#ifdef HAVE_HAL
+  XfburnHalManager *halman = xfburn_hal_manager_get_global ();
+#endif
 
-  device->dvdr = drives->write_dvdr;
-  device->dvdram = drives->write_dvdram;
-  
-  device->buffer_size = drives->buffer_size;
-  device->dummy_write = drives->write_simulate;
+  DBG ("Constructing device list");
+  xfburn_console_libburn_messages ();
 
-  /* write modes */
-  device->tao_block_types = drives->tao_block_types;
-  device->sao_block_types = drives->sao_block_types;
-  device->raw_block_types = drives->raw_block_types;
-  device->packet_block_types = drives->packet_block_types;
+#ifdef HAVE_HAL
+  /* FIXME: hal_manager currently only returns burners, not readers */
+  priv->num_drives = priv->num_burners = xfburn_hal_manager_get_devices (halman, &priv->devices);
+  if (priv->num_burners < 1) {
+    /* if some error occurred while checking hal properties,
+       or hal for some reason did not find a device, then just
+       fall back on libburn */
+    g_message ("HAL said there are %d burners, checking libburn if it can detect any", priv->num_burners);
 
-  DBG (DEVICE_INFO_PRINTF);
+    get_libburn_device_list (self);
+  }
+  priv->volume_changed_handlerid = g_signal_connect (G_OBJECT (xfburn_hal_manager_get_global ()), "volume-changed", G_CALLBACK (cb_volumes_changed), self);
+
+#else
+  get_libburn_device_list (self);
+#endif
+
+  if (priv->num_burners > 0) {
+    priv->curr_device = XFBURN_DEVICE (priv->devices->data);
+    xfburn_device_refresh_info (priv->curr_device, TRUE);
+  }
 }
 
-gint
-get_libburn_device_list ()
+
+/***************/
+/*- internals -*/
+/***************/
+
+void
+get_libburn_device_list (XfburnDeviceList *devlist)
 {
+  XfburnDeviceListPrivate *priv = GET_PRIVATE (devlist);
+
   struct burn_drive_info *drives;
   guint i;
   gint ret; 
-  gboolean can_burn;
-  guint n_drives = 0;
-  guint n_burners = 0;
 
-  *profile_name = '\0';
-
-  while ((ret = burn_drive_scan (&drives, &n_drives)) == 0)
+  while ((ret = burn_drive_scan (&drives, &(priv->num_drives))) == 0)
     usleep (1002);
 
   if (ret < 0)
     g_warning ("An error occurred while scanning for available drives");
 
-  if (n_drives < 1) {
+  if (priv->num_drives < 1) {
     g_warning ("No drives were found! If this is in error, check the permissions");
   }
 
-  for (i = 0; i < n_drives; i++) {
-    XfburnDevice *device = g_new0 (XfburnDevice, 1);
+  for (i = 0; i < priv->num_drives; i++) {
+    XfburnDevice *device = xfburn_device_new ();
+    const gchar *name;
+    char addr[BURN_DRIVE_ADR_LEN];;
     gint ret = 0;
     
-    device->name = g_strconcat (drives[i].vendor, " ", drives[i].product, NULL);
+    name = xfburn_device_set_name (device, drives[i].vendor, drives[i].product);
 
-    fillin_libburn_device_info (device, &drives[i]);
+    xfburn_device_fillin_libburn_info (device, &drives[i]);
 
-    can_burn = XFBURN_DEVICE_LIST_CAN_BURN_CONDITION(device);
     
-    ret = burn_drive_get_adr (&(drives[i]), device->addr);
+    ret = burn_drive_d_get_adr (drives[i].drive, addr);
     if (ret <= 0)
-      g_error ("Unable to get drive %s address (ret=%d). Please report this problem to libburn-hackers at pykix.org", device->name, ret);
+      g_error ("Unable to get drive %s address (ret=%d). Please report this problem to libburn-hackers at pykix.org", name, ret);
     //DBG ("device->addr = %s", device->addr);
 
-    if (can_burn) {
-      devices = g_list_append (devices, device);
-      n_burners++;
+    g_object_set (device, "address", addr, NULL);
+
+    if (xfburn_device_can_burn (device)) {
+      priv->devices = g_list_append (priv->devices, device);
+      priv->num_burners++;
     } else {
-      g_message ("Ignoring reader '%s' at '%s'", device->name, device->addr);
-      g_free (device);
+      g_message ("Ignoring reader '%s' at '%s'", name, addr);
+      g_object_unref (device);
     }
   }
 
   burn_drive_info_free (drives);
 
-  if (n_drives > 0 && n_burners < 1)
-    g_warning ("There are %d drives in your system, but none are capable of burning", n_drives);
-  
-  return n_burners;
+  if (priv->num_drives > 0 && priv->num_burners < 1)
+    g_warning ("There are %d drives in your system, but none are capable of burning", priv->num_drives);
 }
 
-/**************/
-/* public API */
-/**************/
-GList *
-xfburn_device_list_get_list ()
+static XfburnDevice *
+get_selected_device (GtkComboBox *combo_device)
 {
-  return devices;
+  GtkTreeModel *model;
+  GtkTreeIter iter;
+  XfburnDevice * device = NULL;
+  gboolean ret;
+
+  model = gtk_combo_box_get_model (GTK_COMBO_BOX (combo_device));
+  ret = gtk_combo_box_get_active_iter (GTK_COMBO_BOX (combo_device), &iter);
+  if (ret)
+    gtk_tree_model_get (model, &iter, DEVICE_POINTER_COLUMN, &device, -1);
+
+  return device;
 }
 
-enum burn_disc_status
-xfburn_device_list_get_disc_status ()
+static void
+cb_combo_device_changed (GtkComboBox *combo, XfburnDeviceList *devlist)
 {
-  return disc_status;
-}
+  XfburnDeviceListPrivate *priv = GET_PRIVATE (devlist);
+  XfburnDevice *device;
 
-int
-xfburn_device_list_get_profile_no ()
-{
-  return profile_no;
+  DBG ("trace");
+  
+  g_signal_emit (G_OBJECT (devlist), signals[DEVICE_CHANGE_START], 0);
+  device = get_selected_device (combo);
+
+  if (device == NULL)
+    return;
+
+  priv->curr_device = device;
+  xfburn_device_refresh_info (device, TRUE);
+  g_signal_emit (G_OBJECT (devlist), signals[DEVICE_CHANGE_END], 0, device);
 }
 
-const char *
-xfburn_device_list_get_profile_name ()
+#ifdef HAVE_HAL
+static void
+cb_volumes_changed (XfburnHalManager *halman, XfburnDeviceList *devlist)
 {
-  return profile_name;
+  DBG ("Hal volume changed");
+  refresh (devlist);
 }
+#endif
 
-gboolean
-xfburn_device_list_disc_is_erasable ()
+static void
+cb_refresh_clicked (GtkButton *button, XfburnDeviceList *devlist)
 {
-  return is_erasable != 0;
+  DBG ("trace");
+  refresh (devlist);
 }
 
-gboolean
-xfburn_device_refresh_info (XfburnDevice * device, gboolean get_speed_info)
+static void
+refresh (XfburnDeviceList *devlist)
 {
-  struct burn_drive_info *drive_info = NULL;
-  gboolean ret;
-#ifdef HAVE_HAL
-  XfburnHalManager *halman = xfburn_hal_manager_get_instance ();
-#endif
+  XfburnDeviceListPrivate *priv = GET_PRIVATE (devlist);
 
-  if (G_UNLIKELY (device == NULL)) {
-    g_warning ("Hmm, why can we refresh when there is no drive?");
-    return FALSE;
-  }
-
-  /* reset other internal structures */
-  profile_no = 0;
-  *profile_name = '\0';
-  is_erasable = 0;
-
-  /* empty previous speed list */
-  g_slist_free (device->supported_cdr_speeds);
-  device->supported_cdr_speeds = NULL;
-
-  if (!device->accessible) {
-#ifdef HAVE_HAL 
-    if (!xfburn_hal_manager_check_ask_umount (halman, device))
-      return FALSE;
-#else
-    return FALSE;
-#endif
-  }
-
-  if (!xfburn_device_grab (device, &drive_info)) {
-    ret = FALSE;
-    g_warning ("Couldn't grab drive in order to update speed list.");
-    disc_status = BURN_DISC_UNGRABBED;
-  } else {
-    if (!device->accessible)
-      fillin_libburn_device_info (device, drive_info);
-    ret = TRUE;
-    refresh_disc (device, drive_info);
-    if (get_speed_info)
-      refresh_speed_list (device, drive_info);
-
-    xfburn_device_release (drive_info, 0);
-  }
-
-  return ret;
+  g_signal_emit (G_OBJECT (devlist), signals[VOLUME_CHANGE_START], 0, priv->curr_device);
+  usleep (1000001);
+  xfburn_device_refresh_info (priv->curr_device, TRUE);
+  g_signal_emit (G_OBJECT (devlist), signals[VOLUME_CHANGE_END], 0, priv->curr_device);
 }
 
-gint
-xfburn_device_list_init ()
-{
-#ifdef HAVE_HAL
-  XfburnHalManager *halman = xfburn_hal_manager_get_instance ();
-#endif
-  int n_drives;
 
-  xfburn_device_list_console_messages ();
 
-  if (devices) {
-    g_list_foreach (devices, (GFunc) device_content_free, NULL);
-    g_list_free (devices);
-    devices = NULL;
-  }
 
-#ifdef HAVE_HAL
-  n_drives = xfburn_hal_manager_get_devices (halman, &devices);
-  if (n_drives < 1) {
-    /* if some error occurred while checking hal properties,
-       or hal for some reason did not find a device, then just
-       fall back on libburn */
-    g_message ("HAL said there are %d burners, checking libburn if it can detect any", n_drives);
+/**************/
+/* public API */
+/**************/
 
-    n_drives = get_libburn_device_list ();
-  }
-#else
-  n_drives = get_libburn_device_list ();
-#endif
 
-  return n_drives;
-}
-
-gboolean
-xfburn_device_grab (XfburnDevice * device, struct burn_drive_info **drive_info)
+XfburnDevice *
+xfburn_device_list_lookup_by_name (XfburnDeviceList *devlist, const gchar * name)
 {
-  int ret = 0;
-  gchar drive_addr[BURN_DRIVE_ADR_LEN];
-  int i;
-  const int max_checks = 4;
+  XfburnDeviceListPrivate *priv = GET_PRIVATE (devlist);
+  GList *device;
 
-  ret = burn_drive_convert_fs_adr (device->addr, drive_addr);
-  if (ret <= 0) {
-    g_error ("Device address does not lead to a CD burner '%s' (ret=%d).", device->addr, ret);
-    return FALSE;
-  }
+  device = priv->devices;
 
-  /* we need to try to grab several times, because
-   * the drive might be busy detecting the disc */
-  for (i=1; i<=max_checks; i++) {
-    ret = burn_drive_scan_and_grab (drive_info, drive_addr, 0);
-    //DBG ("grab (%s)-> %d", drive_addr, ret);
-    if (ret > 0)
-      break;
-    else if  (i < max_checks)
-      usleep(i*100001);
-  }
+  while (device) {
+    XfburnDevice *device_data = XFBURN_DEVICE (device->data);
+    gchar *devname;
 
-  if (ret <= 0) {
-    g_warning ("Unable to grab the drive at path '%s' (ret=%d).", device->addr, ret);
-    return FALSE;
-  }
+    g_object_get (device, "name", &devname, NULL);
 
-  return TRUE;
-}
+    if (g_ascii_strcasecmp (devname, name) == 0) {
+      g_free (devname);
+      return device_data;
+    }
 
-gboolean 
-xfburn_device_release (struct burn_drive_info *drive_info, gboolean eject)
-{
-  int ret;
+    g_free (devname);
 
-  burn_drive_release (drive_info->drive, eject);
-
-  ret = burn_drive_info_forget (drive_info, 0);
-
-  if (G_LIKELY (ret == 1))
-    return TRUE;
-  else if (ret == 2) {
-    DBG ("drive_info already forgotten");
-    return TRUE;
-  } else if (ret == 0) {
-    DBG ("could not forget drive_info");
-    return FALSE;
-  } else if (ret < 0) {
-    DBG ("some other failure while forgetting drive_info");
-    return FALSE;
+    device = g_list_next (device);
   }
 
-  /* we should never reach this */
-  return FALSE;
+  return NULL;
 }
 
-void
-xfburn_device_free (XfburnDevice * device)
+GtkWidget *
+xfburn_device_list_get_device_combo (XfburnDeviceList *devlist)
 {
-  device_content_free (device, NULL);
-  g_free (device);
-}
+  XfburnDeviceListPrivate *priv = GET_PRIVATE (devlist);
 
+  GtkWidget *combo_device;
+  GList *device = NULL;
+  GtkListStore *store = NULL;
+  GtkCellRenderer *cell;
 
-XfburnDevice *
-xfburn_device_lookup_by_name (const gchar * name)
-{
-  GList *device;
+  store = gtk_list_store_new (DEVICE_N_COLUMNS, G_TYPE_STRING, G_TYPE_POINTER);
+  combo_device = gtk_combo_box_new_with_model (GTK_TREE_MODEL (store));
+  g_object_unref (store);
 
-  device = devices;
+  cell = gtk_cell_renderer_text_new ();
+  gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combo_device), cell, TRUE);
+  gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (combo_device), cell, "text", DEVICE_NAME_COLUMN, NULL);
+  gtk_widget_show (combo_device);
 
+  device = priv->devices;
   while (device) {
     XfburnDevice *device_data = (XfburnDevice *) device->data;
+    GtkTreeIter iter;
+    const gchar *name;
 
-    if (g_ascii_strcasecmp (device_data->name, name) == 0)
-      return device_data;
+    g_object_get (G_OBJECT (device_data), "name", &name, NULL);
 
+    gtk_list_store_append (store, &iter);
+    gtk_list_store_set (store, &iter, DEVICE_NAME_COLUMN, name, DEVICE_POINTER_COLUMN, device_data, -1);
+
     device = g_list_next (device);
   }
+  /* FIXME: this might have to change once reading devices need to get selected as well */
+  gtk_widget_set_sensitive (combo_device, priv->num_drives > 0);
 
-  return NULL;
+  gtk_combo_box_set_active (GTK_COMBO_BOX (combo_device), 0);
+
+  g_signal_connect (G_OBJECT (combo_device), "changed", G_CALLBACK (cb_combo_device_changed), devlist);
+
+  return combo_device;
 }
 
-void
-xfburn_device_list_free ()
+GtkWidget *
+xfburn_device_list_get_refresh_button (XfburnDeviceList *devlist)
 {
-  g_list_foreach (devices, (GFunc) xfburn_device_free, NULL);
-  g_list_free (devices);
-  
-  devices = NULL;
+  XfburnDeviceListPrivate *priv = GET_PRIVATE (devlist);
+  GtkWidget *img, *button;
+
+  img = gtk_image_new_from_stock (GTK_STOCK_REFRESH, GTK_ICON_SIZE_SMALL_TOOLBAR);
+  gtk_widget_show (img);
+  button = gtk_button_new ();
+  gtk_container_add (GTK_CONTAINER (button), img);
+  gtk_widget_show (button);
+  gtk_widget_set_sensitive (button, priv->num_burners > 0);
+
+  g_signal_connect (G_OBJECT (button), "clicked", G_CALLBACK (cb_refresh_clicked), devlist);
+
+  return button;
 }
 
-void
-xfburn_device_list_capture_messages ()
+/*
+gchar *
+xfburn_device_list_get_selected (XfburnDeviceList *devlist)
 {
-  int ret;
+  XfburnDeviceListPrivate *priv = GET_PRIVATE (devlist);
+  GtkTreeModel *model;
+  GtkTreeIter iter;
+  gchar *name = NULL;
+  gboolean ret;
 
-#ifdef DEBUG_LIBBURN 
-  ret = burn_msgs_set_severities ("NEVER", "DEBUG", libburn_msg_prefix);
-#else
-  ret = burn_msgs_set_severities ("ALL", "NEVER", libburn_msg_prefix);
-#endif
+  model = gtk_combo_box_get_model (GTK_COMBO_BOX (priv->combo_device));
+  ret = gtk_combo_box_get_active_iter (GTK_COMBO_BOX (priv->combo_device), &iter);
+  if (ret)
+    gtk_tree_model_get (model, &iter, DEVICE_NAME_COLUMN, &name, -1);
 
-  if (ret <= 0)
-    g_warning ("Failed to set libburn message severities, burn errors might not get detected");
+  return name;
 }
+*/
 
-void
-xfburn_device_list_console_messages ()
+/* Note that the device is NOT ref'ed, so if the caller wants to hold on to a copy,
+   g_object_ref () has to be called manually, or just use the property "current-device" */
+XfburnDevice *
+xfburn_device_list_get_current_device (XfburnDeviceList *devlist)
 {
-  int ret;
+  XfburnDeviceListPrivate *priv = GET_PRIVATE (devlist);
 
-#ifdef DEBUG_LIBBURN 
-  ret = burn_msgs_set_severities ("NEVER", "DEBUG", libburn_msg_prefix);
-#else
-  ret = burn_msgs_set_severities ("NEVER", "FATAL", libburn_msg_prefix);
-#endif
+  return priv->curr_device;
+}
 
-  if (ret <= 0)
-    g_warning ("Failed to set libburn message severities");
- 
+
+XfburnDeviceList*
+xfburn_device_list_new (void)
+{
+  return g_object_new (XFBURN_TYPE_DEVICE_LIST, NULL);
 }
 
 
-

Modified: xfburn/trunk/xfburn/xfburn-device-list.h
===================================================================
--- xfburn/trunk/xfburn/xfburn-device-list.h	2009-07-04 22:45:59 UTC (rev 7676)
+++ xfburn/trunk/xfburn/xfburn-device-list.h	2009-07-05 00:55:15 UTC (rev 7677)
@@ -24,8 +24,42 @@
 #include <config.h>
 #endif
 
+#include <glib-object.h>
 #include <libburn.h>
 
+#include "xfburn-device.h"
+
+G_BEGIN_DECLS
+
+#define XFBURN_TYPE_DEVICE_LIST xfburn_device_list_get_type()
+
+#define XFBURN_DEVICE_LIST(obj) \
+    (G_TYPE_CHECK_INSTANCE_CAST ((obj), XFBURN_TYPE_DEVICE_LIST, XfburnDeviceList))
+
+#define XFBURN_DEVICE_LIST_CLASS(klass) \
+    (G_TYPE_CHECK_CLASS_CAST ((klass), XFBURN_TYPE_DEVICE_LIST, XfburnDeviceListClass))
+
+#define XFBURN_IS_DEVICE_LIST(obj) \
+    (G_TYPE_CHECK_INSTANCE_TYPE ((obj), XFBURN_TYPE_DEVICE_LIST))
+
+#define XFBURN_IS_DEVICE_LIST_CLASS(klass) \
+    (G_TYPE_CHECK_CLASS_TYPE ((klass), XFBURN_TYPE_DEVICE_LIST))
+
+#define XFBURN_DEVICE_LIST_GET_CLASS(obj) \
+    (G_TYPE_INSTANCE_GET_CLASS ((obj), XFBURN_TYPE_DEVICE_LIST, XfburnDeviceListClass))
+
+typedef struct {
+  GObject parent;
+} XfburnDeviceList;
+
+typedef struct {
+  GObjectClass parent_class;
+  
+  void (*device_changed) (XfburnDeviceList *devlist, XfburnDevice *device);
+  void (*volume_changed) (XfburnDeviceList *devlist, XfburnDevice *device);
+} XfburnDeviceListClass;
+
+
 /* what kind of recordable discs are there */
 /* usused so far */
 enum XfburnDiscTypes {
@@ -54,46 +88,14 @@
   XFBURN_PROFILE_BD_RE = 0x43,
 };
 
-typedef struct
-{
-  gchar *name;
-  gchar addr[BURN_DRIVE_ADR_LEN];
-  gboolean accessible;
+GType xfburn_device_list_get_type (void);
 
-  gint buffer_size;
-  gboolean dummy_write;
-  
-  gboolean cdr;
-  gboolean cdrw;
-  GSList *supported_cdr_speeds;
+XfburnDeviceList* xfburn_device_list_new (void);
 
-  gint tao_block_types;
-  gint sao_block_types;
-  gint raw_block_types;
-  gint packet_block_types;
+XfburnDevice * xfburn_device_list_lookup_by_name (XfburnDeviceList *devlist, const gchar * name);
+gchar * xfburn_device_list_get_selected (XfburnDeviceList *devlist);
+GtkWidget * xfburn_device_list_get_refresh_button (XfburnDeviceList *devlist);
+GtkWidget * xfburn_device_list_get_device_combo (XfburnDeviceList *devlist);
+XfburnDevice * xfburn_device_list_get_current_device (XfburnDeviceList *devlist);
 
-  gboolean dvdr;
-  gboolean dvdram;
-
-} XfburnDevice;
-
-#define XFBURN_DEVICE_LIST_CAN_BURN_CONDITION(dev) ((dev)->cdr || (dev)->cdrw || (dev)->dvdr || (dev)->dvdram)
-
-gint xfburn_device_list_init ();
-XfburnDevice * xfburn_device_lookup_by_name (const gchar * name);
-GList * xfburn_device_list_get_list ();
-enum burn_disc_status xfburn_device_list_get_disc_status ();
-int xfburn_device_list_get_profile_no ();
-const char * xfburn_device_list_get_profile_name ();
-gboolean xfburn_device_list_disc_is_erasable ();
-void xfburn_device_list_free ();
-
-gboolean xfburn_device_refresh_info (XfburnDevice * device, gboolean get_speed_info);
-gboolean xfburn_device_grab (XfburnDevice * device, struct burn_drive_info **drive_info);
-gboolean xfburn_device_release (struct burn_drive_info *drive_info, gboolean eject);
-void xfburn_device_free (XfburnDevice * device);
-
-void xfburn_device_list_capture_messages ();
-void xfburn_device_list_console_messages ();
-
 #endif /* __XFBURN_DEVICE_LIST_H__ */

Added: xfburn/trunk/xfburn/xfburn-device.c
===================================================================
--- xfburn/trunk/xfburn/xfburn-device.c	                        (rev 0)
+++ xfburn/trunk/xfburn/xfburn-device.c	2009-07-05 00:55:15 UTC (rev 7677)
@@ -0,0 +1,578 @@
+/*
+ *  Copyright (C) 2009 David Mohr <david at mcbf.net>
+ *  
+ *  This program 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.
+ *  
+ *  This program 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *  
+ */
+
+#ifdef	HAVE_CONFIG_H
+#include <config.h>
+#endif /* !HAVE_CONFIG_H */
+
+#include <libxfce4util/libxfce4util.h>
+#include <unistd.h>
+
+#include "xfburn-device.h"
+#include "xfburn-hal-manager.h"
+
+/*- globals -*/
+
+enum {
+  PROP_0,
+  PROP_NAME,
+  PROP_ADDRESS,
+  PROP_ACCESSIBLE,
+  PROP_SUPPORTED_SPEEDS,
+  PROP_DISC_STATUS,
+  PROP_PROFILE_NO,
+  PROP_PROFILE_NAME,
+  PROP_ERASABLE,
+  PROP_CDR,
+  PROP_CDRW,
+  PROP_DVDR,
+  PROP_DVDPLUSR,
+  PROP_DVDRAM,
+  PROP_TAO_BLOCK_TYPES,
+  PROP_SAO_BLOCK_TYPES,
+  PROP_RAW_BLOCK_TYPES,
+  PROP_PACKET_BLOCK_TYPES,
+};
+
+/*- private prototypes -*/
+
+#define CAN_BURN(priv) ((priv)->cdr || (priv)->cdrw || (priv)->dvdr || (priv)->dvdram)
+#define DEVICE_INFO_PRINTF(device) "%s can burn: %d [cdr: %d, cdrw: %d, dvdr: %d, dvdram: %d]", (device)->name, CAN_BURN (device), (device)->cdr, (device)->cdrw, (device)->dvdr, (device)->dvdram
+
+
+/*****************/
+/*- class setup -*/
+/*****************/
+
+G_DEFINE_TYPE (XfburnDevice, xfburn_device, G_TYPE_OBJECT)
+
+#define GET_PRIVATE(o) \
+  (G_TYPE_INSTANCE_GET_PRIVATE ((o), XFBURN_TYPE_DEVICE, XfburnDevicePrivate))
+
+typedef struct _XfburnDevicePrivate XfburnDevicePrivate;
+
+struct _XfburnDevicePrivate {
+  gchar *name;
+  gchar *addr;
+  gboolean accessible;
+
+  gint buffer_size;
+  gboolean dummy_write;
+  
+  gboolean cdr;
+  gboolean cdrw;
+  gboolean dvdr;
+  gboolean dvdplusr;
+  gboolean dvdram;
+
+  GSList *supported_speeds;
+
+  gint tao_block_types;
+  gint sao_block_types;
+  gint raw_block_types;
+  gint packet_block_types;
+
+  enum burn_disc_status disc_status;
+  int profile_no;
+  char profile_name[80];
+  int is_erasable;
+};
+
+static void
+xfburn_device_get_property (GObject *object, guint property_id,
+                              GValue *value, GParamSpec *pspec)
+{
+  XfburnDevicePrivate *priv = GET_PRIVATE (XFBURN_DEVICE (object));
+
+  switch (property_id) {
+    case PROP_NAME:
+      g_value_set_string (value, priv->name);
+      break;
+    case PROP_ADDRESS:
+      g_value_set_string (value, priv->addr);
+      break;
+    case PROP_ACCESSIBLE:
+      g_value_set_boolean (value, priv->accessible);
+      break;
+    case PROP_SUPPORTED_SPEEDS:
+      g_value_set_pointer (value, priv->supported_speeds);
+      break;
+    case PROP_DISC_STATUS:
+      g_value_set_int (value, priv->disc_status);
+      break;
+    case PROP_PROFILE_NO:
+      g_value_set_int (value, priv->profile_no);
+      break;
+    case PROP_PROFILE_NAME:
+      g_value_set_string (value, priv->profile_name);
+      break;
+    case PROP_ERASABLE:
+      g_value_set_boolean (value, priv->is_erasable);
+      break;
+    case PROP_CDR:
+      g_value_set_boolean (value, priv->cdr);
+      break;
+    case PROP_CDRW:
+      g_value_set_boolean (value, priv->cdrw);
+      break;
+    case PROP_DVDR:
+      g_value_set_boolean (value, priv->dvdr);
+      break;
+    case PROP_DVDPLUSR:
+      g_value_set_boolean (value, priv->dvdplusr);
+      break;
+    case PROP_DVDRAM:
+      g_value_set_boolean (value, priv->dvdram);
+      break;
+    case PROP_TAO_BLOCK_TYPES:
+      g_value_set_int (value, priv->tao_block_types);
+      break;
+    case PROP_SAO_BLOCK_TYPES:
+      g_value_set_int (value, priv->sao_block_types);
+      break;
+    case PROP_RAW_BLOCK_TYPES:
+      g_value_set_int (value, priv->raw_block_types);
+      break;
+    case PROP_PACKET_BLOCK_TYPES:
+      g_value_set_int (value, priv->packet_block_types);
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+  }
+}
+
+static void
+xfburn_device_set_property (GObject *object, guint property_id,
+                              const GValue *value, GParamSpec *pspec)
+{
+  XfburnDevicePrivate *priv = GET_PRIVATE (XFBURN_DEVICE (object));
+
+  switch (property_id) {
+    case PROP_NAME:
+      priv->name = g_value_dup_string (value);
+      break;
+    case PROP_ADDRESS:
+      priv->addr = g_value_dup_string (value);
+      break;
+    case PROP_ACCESSIBLE:
+      priv->accessible = g_value_get_boolean (value);
+      break;
+    case PROP_SUPPORTED_SPEEDS:
+      priv->supported_speeds = g_value_get_pointer (value);
+      break;
+    case PROP_DISC_STATUS:
+      priv->disc_status = g_value_get_int (value);
+      break;
+    case PROP_PROFILE_NO:
+      priv->profile_no = g_value_get_int (value);
+      break;
+    case PROP_PROFILE_NAME:
+      strncpy (priv->profile_name, g_value_get_string(value), 80);
+      break;
+    case PROP_ERASABLE:
+      priv->is_erasable = g_value_get_boolean (value);
+      break;
+    case PROP_CDR:
+      priv->cdr = g_value_get_boolean (value);
+      break;
+    case PROP_CDRW:
+      priv->cdrw = g_value_get_boolean (value);
+      break;
+    case PROP_DVDR:
+      priv->dvdr = g_value_get_boolean (value);
+      break;
+    case PROP_DVDPLUSR:
+      priv->dvdplusr = g_value_get_boolean (value);
+      break;
+    case PROP_DVDRAM:
+      priv->dvdram = g_value_get_boolean (value);
+      break;
+    case PROP_TAO_BLOCK_TYPES:
+      priv->tao_block_types = g_value_get_int (value);
+      break;
+    case PROP_SAO_BLOCK_TYPES:
+      priv->sao_block_types = g_value_get_int (value);
+      break;
+    case PROP_RAW_BLOCK_TYPES:
+      priv->raw_block_types = g_value_get_int (value);
+      break;
+    case PROP_PACKET_BLOCK_TYPES:
+      priv->packet_block_types = g_value_get_int (value);
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+  }
+}
+
+static void
+xfburn_device_finalize (GObject *object)
+{
+  XfburnDevice *dev = XFBURN_DEVICE (object);
+  XfburnDevicePrivate *priv = GET_PRIVATE (dev);
+
+  g_free (priv->name);
+
+  g_slist_free (priv->supported_speeds);
+
+  G_OBJECT_CLASS (xfburn_device_parent_class)->finalize (object);
+}
+
+static void
+xfburn_device_class_init (XfburnDeviceClass *klass)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+  g_type_class_add_private (klass, sizeof (XfburnDevicePrivate));
+
+  object_class->get_property = xfburn_device_get_property;
+  object_class->set_property = xfburn_device_set_property;
+  object_class->finalize = xfburn_device_finalize;
+
+  g_object_class_install_property (object_class, PROP_NAME, 
+                                   g_param_spec_string ("name", _("Display name"),
+                                                        _("Display name"), NULL, G_PARAM_READABLE));
+  g_object_class_install_property (object_class, PROP_ADDRESS, 
+                                   g_param_spec_string ("address", _("Device address"),
+                                                        _("Device address"), "", G_PARAM_READWRITE));
+  g_object_class_install_property (object_class, PROP_ACCESSIBLE, 
+                                   g_param_spec_string ("accessible", _("Is the device accessible"),
+                                                        _("Is the device accessible"), FALSE, G_PARAM_READABLE));
+  g_object_class_install_property (object_class, PROP_SUPPORTED_SPEEDS, 
+                                   g_param_spec_pointer ("supported-speeds", _("Burn speeds supported by the device"),
+                                                        _("Burn speeds supported by the device"), G_PARAM_READABLE));
+  g_object_class_install_property (object_class, PROP_DISC_STATUS, 
+                                   g_param_spec_int ("disc-status", _("Disc status"),
+                                                     _("Disc status"), 0, 6, 0, G_PARAM_READABLE));
+  g_object_class_install_property (object_class, PROP_PROFILE_NO, 
+                                   g_param_spec_int ("profile-no", _("Profile no. as reported by libburn"),
+                                                     _("Profile no. as reported by libburn"), 0, 0xffff, 0, G_PARAM_READABLE));
+  g_object_class_install_property (object_class, PROP_PROFILE_NAME, 
+                                   g_param_spec_string ("profile-name", _("Profile name as reported by libburn"),
+                                                        _("Profile name as reported by libburn"), "", G_PARAM_READABLE));
+  g_object_class_install_property (object_class, PROP_ERASABLE, 
+                                   g_param_spec_boolean ("erasable", _("Is the disc erasable"),
+                                                        _("Is the disc erasable"), FALSE, G_PARAM_READABLE));
+  g_object_class_install_property (object_class, PROP_CDR, 
+                                   g_param_spec_boolean ("cdr", _("Can burn CDR"),
+                                                        _("Can burn CDR"), FALSE, G_PARAM_READWRITE));
+  g_object_class_install_property (object_class, PROP_CDRW, 
+                                   g_param_spec_boolean ("cdrw", _("Can burn CDRW"),
+                                                        _("Can burn CDRW"), FALSE, G_PARAM_READWRITE));
+  g_object_class_install_property (object_class, PROP_DVDR, 
+                                   g_param_spec_boolean ("dvdr", _("Can burn DVDR"),
+                                                        _("Can burn DVDR"), FALSE, G_PARAM_READWRITE));
+  g_object_class_install_property (object_class, PROP_DVDPLUSR, 
+                                   g_param_spec_boolean ("dvdplusr", _("Can burn DVDPLUSR"),
+                                                        _("Can burn DVDPLUSR"), FALSE, G_PARAM_READWRITE));
+  g_object_class_install_property (object_class, PROP_DVDRAM, 
+                                   g_param_spec_boolean ("dvdram", _("Can burn DVDRAM"),
+                                                        _("Can burn DVDRAM"), FALSE, G_PARAM_READWRITE));
+  g_object_class_install_property (object_class, PROP_TAO_BLOCK_TYPES, 
+                                   g_param_spec_int ("tao-block-types", _("libburn TAO block types"),
+                                                     _("libburn TAO block types"), 0, G_MAXINT, 0, G_PARAM_READABLE));
+  g_object_class_install_property (object_class, PROP_SAO_BLOCK_TYPES, 
+                                   g_param_spec_int ("sao-block-types", _("libburn SAO block types"),
+                                                     _("libburn SAO block types"), 0, G_MAXINT, 0, G_PARAM_READABLE));
+  g_object_class_install_property (object_class, PROP_RAW_BLOCK_TYPES, 
+                                   g_param_spec_int ("raw-block-types", _("libburn RAW block types"),
+                                                     _("libburn RAW block types"), 0, G_MAXINT, 0, G_PARAM_READABLE));
+  g_object_class_install_property (object_class, PROP_PACKET_BLOCK_TYPES, 
+                                   g_param_spec_int ("packet-block-types", _("libburn PACKET block types"),
+                                                     _("libburn PACKET block types"), 0, G_MAXINT, 0, G_PARAM_READABLE));
+}
+
+static void
+xfburn_device_init (XfburnDevice *self)
+{
+  /* FIXME: initialize profile_name, or is that handled by the property? */
+}
+
+
+/***************/
+/*- internals -*/
+/***************/
+
+static gboolean
+no_speed_duplicate (GSList *speed_list, gint speed)
+{
+  GSList *el = speed_list;
+
+  while (el) {
+    gint el_speed = GPOINTER_TO_INT (el->data);
+
+    if (el_speed == speed)
+      return FALSE;
+
+    el = g_slist_next (el);
+  }
+
+  return TRUE;
+}
+
+/* sort the speed list in ascending order */
+static gint
+cmp_ints (gconstpointer a, gconstpointer b)
+{
+  return GPOINTER_TO_INT(a) - GPOINTER_TO_INT(b);
+}
+
+static void
+refresh_disc (XfburnDevice * device, struct burn_drive_info *drive_info)
+{
+  XfburnDevicePrivate *priv = GET_PRIVATE (device);
+  gint ret;
+
+  /* check if there is a disc in the drive */
+  while ((priv->disc_status = burn_disc_get_status (drive_info->drive)) == BURN_DISC_UNREADY)
+    usleep(100001);
+
+  DBG ("disc_status = %d", priv->disc_status);
+
+  if ((ret = burn_disc_get_profile(drive_info->drive, &(priv->profile_no), priv->profile_name)) != 1) {
+    g_warning ("no profile could be retrieved");
+  }
+  priv->is_erasable = burn_disc_erasable (drive_info->drive);
+  DBG ("profile_no = 0x%x (%s), %s erasable", priv->profile_no, priv->profile_name, (priv->is_erasable ? "" : "NOT"));
+
+#if 0 /* this doesn't seem to work */
+  if (burn_disc_read_atip (drive_info->drive) == 1) {
+    int start, end;
+
+    if (burn_drive_get_start_end_lba (drive_info->drive, &start, &end, 0) == 1) {
+      DBG ("lba start = %d, end = %d", start, end);
+    } else
+      DBG ("Getting start/end lba failed");
+  } else
+    DBG ("Reading ATIP failed");
+#endif
+}
+
+static void
+refresh_speed_list (XfburnDevice * device, struct burn_drive_info *drive_info)
+{
+  XfburnDevicePrivate *priv = GET_PRIVATE (device);
+
+  struct burn_speed_descriptor *speed_list = NULL;
+  gint ret;
+
+  /* fill new list */
+  ret = burn_drive_get_speedlist (drive_info->drive, &speed_list);
+  /* speed_list = NULL; DEBUG */ 
+
+  if (ret > 0 && speed_list != NULL) {
+    struct burn_speed_descriptor *el = speed_list;
+
+    while (el) {
+      gint speed = el->write_speed;
+      
+      /* FIXME: why do we need no_speed_duplicate? */
+      if (speed > 0 && no_speed_duplicate (priv->supported_speeds, speed)) {
+          priv->supported_speeds = g_slist_prepend (priv->supported_speeds, GINT_TO_POINTER (speed));
+      } 
+
+      el = el->next;
+    }
+
+    burn_drive_free_speedlist (&speed_list); 
+    priv->supported_speeds = g_slist_sort (priv->supported_speeds, &cmp_ints);
+  } else if (ret == 0 || speed_list == NULL) {
+    g_warning ("reported speed list is empty for device:");
+    // FIXME
+    //g_warning (DEVICE_INFO_PRINTF (priv));
+    g_warning ("%s can burn: %d [cdr: %d, cdrw: %d, dvdr: %d, dvdram: %d]", (priv)->name, ((priv)->cdr || (priv)->cdrw || (priv)->dvdr || (priv)->dvdram), (priv)->cdr, (priv)->cdrw, (priv)->dvdr, (priv)->dvdram);
+  } else {
+    /* ret < 0 */
+    g_error ("severe error while retrieving speed list");
+  }
+}
+
+/*******************/
+/*- public methods-*/
+/*******************/
+
+void
+xfburn_device_fillin_libburn_info (XfburnDevice *device, struct burn_drive_info *drive)
+{
+  XfburnDevicePrivate *priv = GET_PRIVATE (device);
+
+  priv->accessible = TRUE;
+
+  priv->cdr = drive->write_cdr;
+  priv->cdrw = drive->write_cdrw;
+
+  priv->dvdr = drive->write_dvdr;
+  priv->dvdram = drive->write_dvdram;
+  
+  priv->buffer_size = drive->buffer_size;
+  priv->dummy_write = drive->write_simulate;
+
+  /* write modes */
+  priv->tao_block_types = drive->tao_block_types;
+  priv->sao_block_types = drive->sao_block_types;
+  priv->raw_block_types = drive->raw_block_types;
+  priv->packet_block_types = drive->packet_block_types;
+
+  DBG (DEVICE_INFO_PRINTF (priv));
+}
+
+gboolean
+xfburn_device_grab (XfburnDevice * device, struct burn_drive_info **drive_info)
+{
+  XfburnDevicePrivate *priv = GET_PRIVATE (device);
+  int ret = 0;
+  gchar drive_addr[BURN_DRIVE_ADR_LEN];
+  int i;
+  const int max_checks = 4;
+
+  ret = burn_drive_convert_fs_adr (priv->addr, drive_addr);
+  if (ret <= 0) {
+    g_error ("Device address does not lead to a burner '%s' (ret=%d).", priv->addr, ret);
+    return FALSE;
+  }
+
+  /* we need to try to grab several times, because
+   * the drive might be busy detecting the disc */
+  for (i=1; i<=max_checks; i++) {
+    ret = burn_drive_scan_and_grab (drive_info, drive_addr, 0);
+    //DBG ("grab (%s)-> %d", drive_addr, ret);
+    if (ret > 0)
+      break;
+    else if  (i < max_checks)
+      usleep(i*100001);
+  }
+
+  if (ret <= 0) {
+    g_warning ("Unable to grab the drive at path '%s' (ret=%d).", priv->addr, ret);
+    return FALSE;
+  }
+
+  return TRUE;
+}
+
+gboolean
+xfburn_device_refresh_info (XfburnDevice * device, gboolean get_speed_info)
+{
+  XfburnDevicePrivate *priv = GET_PRIVATE (device);
+
+  struct burn_drive_info *drive_info = NULL;
+  gboolean ret;
+#ifdef HAVE_HAL
+  XfburnHalManager *halman = xfburn_hal_manager_get_global ();
+#endif
+
+  if (G_UNLIKELY (device == NULL)) {
+    g_warning ("Hmm, why can we refresh when there is no drive?");
+    return FALSE;
+  }
+
+  /* reset other internal structures */
+  priv->profile_no = 0;
+  *(priv->profile_name) = '\0';
+  priv->is_erasable = 0;
+
+  /* empty previous speed list */
+  g_slist_free (priv->supported_speeds);
+  priv->supported_speeds = NULL;
+
+  if (!priv->accessible) {
+#ifdef HAVE_HAL 
+    if (!xfburn_hal_manager_check_ask_umount (halman, device))
+      return FALSE;
+#else
+    return FALSE;
+#endif
+  }
+
+  if (!xfburn_device_grab (device, &drive_info)) {
+    ret = FALSE;
+    g_warning ("Couldn't grab drive in order to update speed list.");
+    priv->disc_status = BURN_DISC_UNGRABBED;
+  } else {
+    if (!priv->accessible)
+      xfburn_device_fillin_libburn_info (device, drive_info);
+    ret = TRUE;
+    refresh_disc (device, drive_info);
+    if (get_speed_info)
+      refresh_speed_list (device, drive_info);
+
+    xfburn_device_release (drive_info, 0);
+  }
+
+  return ret;
+}
+
+gboolean 
+xfburn_device_release (struct burn_drive_info *drive_info, gboolean eject)
+{
+  int ret;
+
+  burn_drive_release (drive_info->drive, eject);
+
+  ret = burn_drive_info_forget (drive_info, 0);
+
+  if (G_LIKELY (ret == 1))
+    return TRUE;
+  else if (ret == 2) {
+    DBG ("drive_info already forgotten");
+    return TRUE;
+  } else if (ret == 0) {
+    DBG ("could not forget drive_info");
+    return FALSE;
+  } else if (ret < 0) {
+    DBG ("some other failure while forgetting drive_info");
+    return FALSE;
+  }
+
+  /* we should never reach this */
+  return FALSE;
+}
+
+const gchar *
+xfburn_device_set_name (XfburnDevice *device, const gchar *vendor, const gchar *product)
+{
+  XfburnDevicePrivate *priv = GET_PRIVATE (device);
+
+  priv->name = g_strconcat (vendor, " ", product, NULL);
+
+  return priv->name;
+}
+
+gboolean
+xfburn_device_can_burn (XfburnDevice *device)
+{
+  XfburnDevicePrivate *priv = GET_PRIVATE (device);
+
+  return CAN_BURN (priv);
+}
+
+gboolean 
+xfburn_device_can_dummy_write (XfburnDevice *device)
+{
+  XfburnDevicePrivate *priv = GET_PRIVATE (device);
+
+  return priv->dummy_write;
+}
+
+XfburnDevice*
+xfburn_device_new (void)
+{
+  return g_object_new (XFBURN_TYPE_DEVICE, NULL);
+}
+
+


Property changes on: xfburn/trunk/xfburn/xfburn-device.c
___________________________________________________________________
Added: svn:keywords
   + Id
Added: svn:eol-style
   + native

Added: xfburn/trunk/xfburn/xfburn-device.h
===================================================================
--- xfburn/trunk/xfburn/xfburn-device.h	                        (rev 0)
+++ xfburn/trunk/xfburn/xfburn-device.h	2009-07-05 00:55:15 UTC (rev 7677)
@@ -0,0 +1,68 @@
+/*
+ *  Copyright (C) 2009 David Mohr <david at mcbf.net>
+ *  
+ *  This program 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.
+ *  
+ *  This program 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *  
+ */
+
+#ifndef __XFBURN_DEVICE__
+#define __XFBURN_DEVICE__
+
+#include <glib-object.h>
+#include <libburn.h>
+
+G_BEGIN_DECLS
+
+#define XFBURN_TYPE_DEVICE xfburn_device_get_type()
+
+#define XFBURN_DEVICE(obj) \
+  (G_TYPE_CHECK_INSTANCE_CAST ((obj), XFBURN_TYPE_DEVICE, XfburnDevice))
+
+#define XFBURN_DEVICE_CLASS(klass) \
+  (G_TYPE_CHECK_CLASS_CAST ((klass), XFBURN_TYPE_DEVICE, XfburnDeviceClass))
+
+#define XFBURN_IS_DEVICE(obj) \
+  (G_TYPE_CHECK_INSTANCE_TYPE ((obj), XFBURN_TYPE_DEVICE))
+
+#define XFBURN_IS_DEVICE_CLASS(klass) \
+  (G_TYPE_CHECK_CLASS_TYPE ((klass), XFBURN_TYPE_DEVICE))
+
+#define XFBURN_DEVICE_GET_CLASS(obj) \
+  (G_TYPE_INSTANCE_GET_CLASS ((obj), XFBURN_TYPE_DEVICE, XfburnDeviceClass))
+
+typedef struct {
+  GObject parent;
+} XfburnDevice;
+
+typedef struct {
+  GObjectClass parent_class;
+} XfburnDeviceClass;
+
+GType xfburn_device_get_type (void);
+
+XfburnDevice* xfburn_device_new (void);
+
+void xfburn_device_fillin_libburn_info (XfburnDevice *device, struct burn_drive_info *drive);
+gboolean xfburn_device_refresh_info (XfburnDevice * device, gboolean get_speed_info);
+gboolean xfburn_device_grab (XfburnDevice * device, struct burn_drive_info **drive_info);
+gboolean xfburn_device_release (struct burn_drive_info *drive_info, gboolean eject);
+const gchar * xfburn_device_set_name (XfburnDevice *device, const gchar *vendor, const gchar *product);
+gboolean xfburn_device_can_burn (XfburnDevice *device);
+gboolean xfburn_device_can_dummy_write (XfburnDevice *device);
+
+G_END_DECLS
+
+#endif /* __XFBURN_DEVICE__ */
+


Property changes on: xfburn/trunk/xfburn/xfburn-device.h
___________________________________________________________________
Added: svn:keywords
   + Id
Added: svn:eol-style
   + native

Modified: xfburn/trunk/xfburn/xfburn-hal-manager.c
===================================================================
--- xfburn/trunk/xfburn/xfburn-hal-manager.c	2009-07-04 22:45:59 UTC (rev 7676)
+++ xfburn/trunk/xfburn/xfburn-hal-manager.c	2009-07-05 00:55:15 UTC (rev 7677)
@@ -278,14 +278,19 @@
   priv = XFBURN_HAL_MANAGER_GET_PRIVATE (halman);
 
   if (priv->error) {
+    gchar *error_msg, *ret;
+
+    error_msg = g_strdup (priv->error);
     xfburn_hal_manager_shutdown ();
-    return g_strdup_printf ("Failed to initialize %s!", priv->error);
+    ret = g_strdup_printf ("Failed to initialize %s!", error_msg);
+    g_free (error_msg);
+    return ret;
   } else
     return NULL;
 }
 
 XfburnHalManager *
-xfburn_hal_manager_get_instance ()
+xfburn_hal_manager_get_global ()
 {
   if (G_UNLIKELY (halman == NULL))
     g_error ("There is no instance of a hal manager!");
@@ -367,10 +372,14 @@
     libhal_free_string_array (cap_list);
 
     if (optical_drive) {
-      XfburnDevice *device = g_new0 (XfburnDevice, 1);
-      char *str, *str_vendor;
-      gboolean dvdr = FALSE;
+      XfburnDevice *device;
+      char *str, *str_vendor; 
+      const gchar *name;
+      gchar *addr = NULL;
+      gboolean dvdr = FALSE, dvdplusr = FALSE;
 
+      device = xfburn_device_new ();
+
       /*
       libhal_device_print (priv->hal_context, *devices, &error);
       printf ("\n");
@@ -382,93 +391,89 @@
       }
       */
 
-      device->accessible = FALSE;
+      /* xfburn_device sets accessible = false by default */
 
       str_vendor = libhal_device_get_property_string (priv->hal_context, *devices, "storage.vendor", &error);
       if (dbus_error_is_set (&error)) {
         g_warning ("Error getting HAL property for %s: %s", *devices, error.message);
         dbus_error_free (&error);
-        g_free (device);
-        continue;
+        goto not_a_device;
       }
 
       str = libhal_device_get_property_string (priv->hal_context, *devices, "storage.model", &error);
       if (dbus_error_is_set (&error)) {
         g_warning ("Error getting HAL property for %s: %s", *devices, error.message);
         dbus_error_free (&error);
-        g_free (device);
-        continue;
+        goto not_a_device;
       }
 
-      device->name = g_strconcat (str_vendor, " ", str, NULL);
+      name = xfburn_device_set_name (device, str_vendor, str);
       libhal_free_string (str_vendor);
       libhal_free_string (str);
 
-      str = libhal_device_get_property_string (priv->hal_context, *devices, "block.device", &error);
+      addr = libhal_device_get_property_string (priv->hal_context, *devices, "block.device", &error);
       if (dbus_error_is_set (&error)) {
         g_warning ("Error getting HAL property for %s: %s", *devices, error.message);
         dbus_error_free (&error);
-        g_free (device);
-        continue;
+        goto not_a_device;
       }
 
 #ifdef DEBUG_NULL_DEVICE
-      g_strlcpy (device->addr, "stdio:/dev/null", BURN_DRIVE_ADR_LEN);
+      g_object_set (G_OBJECT (device), "address", "stdio:/dev/null", NULL);
 #else
-      g_strlcpy (device->addr, str, BURN_DRIVE_ADR_LEN);
+      g_object_set (G_OBJECT (device), "address", addr, NULL);
 #endif
-      libhal_free_string (str);
 
-      device->cdr = libhal_device_get_property_bool (priv->hal_context, *devices, "storage.cdrom.cdr", &error);
+      g_object_set (G_OBJECT (device), "cdr", libhal_device_get_property_bool (priv->hal_context, *devices, "storage.cdrom.cdr", &error), NULL);
       if (dbus_error_is_set (&error)) {
         g_warning ("Error getting HAL property for %s: %s", *devices, error.message);
         dbus_error_free (&error);
-        g_free (device);
-        continue;
+        goto not_a_device;
       }
 
-      device->cdrw = libhal_device_get_property_bool (priv->hal_context, *devices, "storage.cdrom.cdrw", &error);
+      g_object_set (G_OBJECT (device), "cdrw", libhal_device_get_property_bool (priv->hal_context, *devices, "storage.cdrom.cdrw", &error), NULL);
       if (dbus_error_is_set (&error)) {
         g_warning ("Error getting HAL property for %s: %s", *devices, error.message);
         dbus_error_free (&error);
-        g_free (device);
-        continue;
+        goto not_a_device;
       }
 
-      device->dvdr = libhal_device_get_property_bool (priv->hal_context, *devices, "storage.cdrom.dvdr", &error);
+      dvdr = libhal_device_get_property_bool (priv->hal_context, *devices, "storage.cdrom.dvdr", &error);
       if (dbus_error_is_set (&error)) {
         g_warning ("Error getting HAL property for %s: %s", *devices, error.message);
         dbus_error_free (&error);
-        g_free (device);
-        continue;
+        goto not_a_device;
       }
 
-      dvdr = libhal_device_get_property_bool (priv->hal_context, *devices, "storage.cdrom.dvdplusr", &error);
+      dvdplusr = libhal_device_get_property_bool (priv->hal_context, *devices, "storage.cdrom.dvdplusr", &error);
       if (dbus_error_is_set (&error)) {
         g_warning ("Error getting HAL property for %s: %s", *devices, error.message);
         dbus_error_free (&error);
-        g_free (device);
-        continue;
+        goto not_a_device;
       }
-      device->dvdr |= dvdr;
+      g_object_set (G_OBJECT (device), "dvdr", dvdr | dvdplusr, NULL);
 
-      device->dvdram = libhal_device_get_property_bool (priv->hal_context, *devices, "storage.cdrom.dvdram", &error);
+      g_object_set (G_OBJECT (device), "dvdram", libhal_device_get_property_bool (priv->hal_context, *devices, "storage.cdrom.dvdram", &error), NULL);
       if (dbus_error_is_set (&error)) {
         g_warning ("Error getting HAL property for %s: %s", *devices, error.message);
         dbus_error_free (&error);
-        g_free (device);
-        continue;
+        goto not_a_device;
       }
 
-      if (!XFBURN_DEVICE_LIST_CAN_BURN_CONDITION (device)) {
-        g_message ("Ignoring reader '%s' at '%s'", device->name, device->addr);
-        g_free (device);
-        continue;
+      if (!xfburn_device_can_burn (device)) {
+        g_message ("Ignoring reader '%s' at '%s'", name, addr);
+        goto not_a_device;
       }
 
-      DBG ("Found writer '%s' at '%s'", device->name, device->addr);
+      DBG ("Found writer '%s' at '%s'", name, addr);
       *device_list = g_list_append (*device_list, device);
       n_devices++;
+      goto is_a_device;
+
+not_a_device:
+        g_object_unref (device);
+is_a_device:
+      libhal_free_string (addr);
     }
   }
 
@@ -489,8 +494,10 @@
   ThunarVfsPath *th_path;
 #endif
   gboolean unmounted = FALSE;
+  gchar *addr;
   
-  vol = libhal_volume_from_device_file (priv->hal_context, device->addr);
+  g_object_get (G_OBJECT (device), "address", &addr, NULL);
+  vol = libhal_volume_from_device_file (priv->hal_context, addr);
   if (vol == NULL) {
     /* if we can't get a volume, then we're assuming that there is no disc in the drive */
     return TRUE;
@@ -501,7 +508,7 @@
 
 #ifdef HAVE_THUNAR_VFS
   mp = libhal_volume_get_mount_point (vol);
-  DBG ("%s is mounted at %s", device->addr, mp);
+  DBG ("%s is mounted at %s", addr, mp);
 
 
   th_path = thunar_vfs_path_new (mp, NULL);

Modified: xfburn/trunk/xfburn/xfburn-hal-manager.h
===================================================================
--- xfburn/trunk/xfburn/xfburn-hal-manager.h	2009-07-04 22:45:59 UTC (rev 7676)
+++ xfburn/trunk/xfburn/xfburn-hal-manager.h	2009-07-05 00:55:15 UTC (rev 7677)
@@ -56,7 +56,7 @@
 GType xfburn_hal_manager_get_type ();
 //GObject *xfburn_hal_manager_new (); /* use _create_global / _get_instance instead */
 gchar *xfburn_hal_manager_create_global ();
-XfburnHalManager * xfburn_hal_manager_get_instance ();
+XfburnHalManager * xfburn_hal_manager_get_global ();
 void xfburn_hal_manager_shutdown ();
 void xfburn_hal_manager_send_volume_changed ();
 int xfburn_hal_manager_get_devices (XfburnHalManager *halman, GList **devices);

Modified: xfburn/trunk/xfburn/xfburn-main-window.c
===================================================================
--- xfburn/trunk/xfburn/xfburn-main-window.c	2009-07-04 22:45:59 UTC (rev 7676)
+++ xfburn/trunk/xfburn/xfburn-main-window.c	2009-07-05 00:55:15 UTC (rev 7677)
@@ -626,6 +626,7 @@
     XfburnMainWindowPrivate *priv;
     GtkAction *action;
     GList *device = NULL;
+    XfburnDeviceList *devlist;
     
     instance = win = XFBURN_MAIN_WINDOW (obj);
     priv = XFBURN_MAIN_WINDOW_GET_PRIVATE (win);
@@ -639,14 +640,21 @@
     gtk_action_set_sensitive (GTK_ACTION (action), FALSE);*/
 
     /* disable action that cannot be used due to device */
-    device = xfburn_device_list_get_list ();
 
+    devlist = xfburn_device_list_new ();
+    g_object_get (G_OBJECT (devlist), "devices", &device, NULL);
+    g_object_unref (devlist);
+
+    /* FIXME: this is really outdated behavior. Needs to get rewritten */
     while (device != NULL) {
       XfburnDevice *device_info = (XfburnDevice *) device->data;
+      gboolean cdr, cdrw;
 
-      if (device_info->cdr)
+      g_object_get (G_OBJECT (device_info), "cdr", &cdr, "cdrw", &cdrw, NULL);
+
+      if (cdr)
 	priv->support_cdr = TRUE;
-      if (device_info->cdrw)
+      if (cdrw)
 	priv->support_cdrw = TRUE;
 
       device = g_list_next (device);

Modified: xfburn/trunk/xfburn/xfburn-main.c
===================================================================
--- xfburn/trunk/xfburn/xfburn-main.c	2009-07-04 22:45:59 UTC (rev 7676)
+++ xfburn/trunk/xfburn/xfburn-main.c	2009-07-05 00:55:15 UTC (rev 7677)
@@ -185,12 +185,13 @@
 main (int argc, char **argv)
 {
   GtkWidget *mainwin;
-  gint n_drives;
+  gint n_burners;
   GError *error = NULL;
 #ifdef HAVE_HAL
   gchar *error_msg;
 #endif
   XfburnTranscoder *transcoder;
+  XfburnDeviceList *devlist;
 
 #if DEBUG > 0
   /* I have to disable this until GtkTreeView gets fixed,
@@ -293,16 +294,19 @@
 #endif
 
   xfburn_stock_init ();
-  n_drives = xfburn_device_list_init ();
+  devlist = xfburn_device_list_new ();
+  g_object_get (devlist, "num-burners", &n_burners, NULL);
 
-  if (n_drives < 1) {
+  if (n_burners < 1) {
     GtkMessageDialog *dialog = (GtkMessageDialog *) gtk_message_dialog_new (NULL,
                                     GTK_DIALOG_DESTROY_WITH_PARENT,
                                     GTK_MESSAGE_WARNING,
                                     GTK_BUTTONS_CLOSE,
-                                    ((const gchar *) _("No drives are currently available")));
+                                    ((const gchar *) _("No burners are currently available")));
     gtk_message_dialog_format_secondary_text (dialog,
-                                    _("Possibly the disc(s) are in use, and cannot get accessed.\n\nPlease unmount and restart the application.\n\nIf no disc is in the drive, check that you have read and write access to the drive with the current user."));
+                                    _("Possibly the disc(s) are in use, and cannot get accessed.\n\n"
+                                      "Please unmount and restart the application.\n\n"
+                                      "If no disc is in the drive, check that you have read and write access to the drive with the current user."));
     gtk_dialog_run (GTK_DIALOG (dialog));
     gtk_widget_destroy (GTK_WIDGET (dialog));
   }
@@ -402,6 +406,7 @@
 
   /*----------shutdown--------------------------------------------------*/
 
+  g_object_unref (devlist);
   g_object_unref (transcoder);
 
 #ifdef HAVE_HAL
@@ -415,8 +420,6 @@
   xfburn_settings_flush ();
   xfburn_settings_free ();
   
-  xfburn_device_list_free ();
-
   burn_finish ();
 
   gdk_threads_leave ();

Modified: xfburn/trunk/xfburn/xfburn-perform-burn.c
===================================================================
--- xfburn/trunk/xfburn/xfburn-perform-burn.c	2009-07-04 22:45:59 UTC (rev 7676)
+++ xfburn/trunk/xfburn/xfburn-perform-burn.c	2009-07-05 00:55:15 UTC (rev 7677)
@@ -28,6 +28,7 @@
 
 #include "xfburn-perform-burn.h"
 #include "xfburn-progress-dialog.h"
+#include "xfburn-utils.h"
 
 /*************/
 /* internals */
@@ -119,7 +120,7 @@
   }
 
   /* set us up to receive libburn errors */
-  xfburn_device_list_capture_messages ();
+  xfburn_capture_libburn_messages ();
 
   /* Install the default libburn abort signal handler.
    * Hopefully this means the drive won't be left in a burning state if we catch a signal */
@@ -294,7 +295,7 @@
   if (ret < 0)
     g_warning ("Fatal error while trying to retrieve libburn message!");
 
-  xfburn_device_list_console_messages ();
+  xfburn_console_libburn_messages ();
 
   percent = (gdouble) progress.buffer_min_fill / (gdouble) progress.buffer_capacity;
   xfburn_progress_dialog_set_buffer_bar_min_fill (XFBURN_PROGRESS_DIALOG (dialog_progress), percent);

Modified: xfburn/trunk/xfburn/xfburn-preferences-dialog.c
===================================================================
--- xfburn/trunk/xfburn/xfburn-preferences-dialog.c	2009-07-04 22:45:59 UTC (rev 7676)
+++ xfburn/trunk/xfburn/xfburn-preferences-dialog.c	2009-07-05 00:55:15 UTC (rev 7677)
@@ -403,26 +403,41 @@
   XfburnPreferencesDialogPrivate *priv = XFBURN_PREFERENCES_DIALOG_GET_PRIVATE (dialog);
   GtkTreeModel *model;
   GList *device;
+  XfburnDeviceList *devlist;
 
   model = gtk_tree_view_get_model (GTK_TREE_VIEW (priv->treeview_devices));
 
   gtk_list_store_clear (GTK_LIST_STORE (model));
 
-  device = xfburn_device_list_get_list ();
+  devlist = xfburn_device_list_new ();
+  g_object_get (G_OBJECT (devlist), "devices", &device, NULL);
+  g_object_unref (devlist);
+
   while (device) {
     GtkTreeIter iter;
     XfburnDevice *device_data;
+    gchar *name, *addr;
+    gboolean cdr, cdrw, dvdr, dvdram;
 
     device_data = (XfburnDevice *) device->data;
 
+    g_object_get (G_OBJECT (device_data), "name", &name, "address", &addr,
+                  "cdr", &cdr, "cdrw", &cdrw, "dvdr", &dvdr, "dvdram", &dvdram,
+                  NULL);
+
     gtk_list_store_append (GTK_LIST_STORE (model), &iter);
     gtk_list_store_set (GTK_LIST_STORE (model), &iter,
-                        DEVICE_LIST_COLUMN_NAME, device_data->name,
-                        DEVICE_LIST_COLUMN_NODE, device_data->addr,
-                        DEVICE_LIST_COLUMN_CDR, device_data->cdr,
-                        DEVICE_LIST_COLUMN_CDRW, device_data->cdrw,
-                        DEVICE_LIST_COLUMN_DVDR, device_data->dvdr, DEVICE_LIST_COLUMN_DVDRAM, device_data->dvdram, -1);
+                        DEVICE_LIST_COLUMN_NAME, name,
+                        DEVICE_LIST_COLUMN_NODE, addr,
+                        DEVICE_LIST_COLUMN_CDR, cdr,
+                        DEVICE_LIST_COLUMN_CDRW, cdrw,
+                        DEVICE_LIST_COLUMN_DVDR, dvdr, 
+                        DEVICE_LIST_COLUMN_DVDRAM, dvdram, 
+                        -1);
 
+    g_free (name);
+    g_free (addr);
+
     device = g_list_next (device);
   }
 }
@@ -438,7 +453,6 @@
 static void
 scan_button_clicked_cb (GtkWidget * button, gpointer user_data)
 {
-  xfburn_device_list_init ();
   refresh_devices_list (user_data);
 }
 

Modified: xfburn/trunk/xfburn/xfburn-utils.c
===================================================================
--- xfburn/trunk/xfburn/xfburn-utils.c	2009-07-04 22:45:59 UTC (rev 7676)
+++ xfburn/trunk/xfburn/xfburn-utils.c	2009-07-05 00:55:15 UTC (rev 7677)
@@ -27,6 +27,7 @@
 
 #include <gtk/gtk.h>
 #include <libxfce4util/libxfce4util.h>
+#include <libburn.h>
 
 #include <unistd.h>
 #include <sys/types.h>
@@ -142,6 +143,9 @@
   gtk_widget_destroy (dialog);
 }
 
+/**********************/
+/* Simple GUI helpers */
+/**********************/
 
 gboolean
 xfburn_ask_yes_no (GtkMessageType type, const gchar *primary_text, const gchar *secondary_text)
@@ -169,3 +173,42 @@
 
   return ok;
 }
+
+
+/*******************/
+/* libburn helpers */
+/*******************/
+
+static char * libburn_msg_prefix = "libburn-";
+
+void
+xfburn_capture_libburn_messages ()
+{
+  int ret;
+
+#ifdef DEBUG_LIBBURN 
+  ret = burn_msgs_set_severities ("NEVER", "DEBUG", libburn_msg_prefix);
+#else
+  ret = burn_msgs_set_severities ("ALL", "NEVER", libburn_msg_prefix);
+#endif
+
+  if (ret <= 0)
+    g_warning ("Failed to set libburn message severities, burn errors might not get detected");
+}
+
+void
+xfburn_console_libburn_messages ()
+{
+  int ret;
+
+#ifdef DEBUG_LIBBURN 
+  ret = burn_msgs_set_severities ("NEVER", "DEBUG", libburn_msg_prefix);
+#else
+  ret = burn_msgs_set_severities ("NEVER", "FATAL", libburn_msg_prefix);
+#endif
+
+  if (ret <= 0)
+    g_warning ("Failed to set libburn message severities");
+ 
+}
+

Modified: xfburn/trunk/xfburn/xfburn-utils.h
===================================================================
--- xfburn/trunk/xfburn/xfburn-utils.h	2009-07-04 22:45:59 UTC (rev 7676)
+++ xfburn/trunk/xfburn/xfburn-utils.h	2009-07-05 00:55:15 UTC (rev 7677)
@@ -37,4 +37,8 @@
 void xfburn_browse_for_file (GtkEntry *entry, GtkWindow *parent);
 
 gboolean xfburn_ask_yes_no (GtkMessageType type, const gchar *primary_text, const gchar *secondary_text);
+
+void xfburn_capture_libburn_messages ();
+void xfburn_console_libburn_messages ();
+
 #endif




More information about the Goodies-commits mailing list