~mfisch/brasero/update-to-3.8.0

« back to all changes in this revision

Viewing changes to libbrasero-media/brasero-medium-monitor.c

  • Committer: Bazaar Package Importer
  • Author(s): Andreas Moog
  • Date: 2009-07-28 01:12:27 UTC
  • mto: (1.4.1 experimental)
  • mto: This revision was merged to the branch mainline in revision 46.
  • Revision ID: james.westby@ubuntu.com-20090728011227-tiva9yorc5d1r5hs
Tags: upstream-2.27.5
ImportĀ upstreamĀ versionĀ 2.27.5

Show diffs side-by-side

added added

removed removed

Lines of Context:
55
55
        GSList *drives;
56
56
        GVolumeMonitor *gmonitor;
57
57
 
58
 
        GSList *waiting_removal;
59
 
        guint waiting_removal_id;
60
 
 
61
58
        gint probing;
62
59
};
63
60
 
104
101
        BraseroMediumMonitorPrivate *priv;
105
102
 
106
103
        g_return_val_if_fail (monitor != NULL, NULL);
107
 
        g_return_val_if_fail (device != NULL, NULL);
108
104
        g_return_val_if_fail (BRASERO_IS_MEDIUM_MONITOR (monitor), NULL);
109
105
 
110
106
        priv = BRASERO_MEDIUM_MONITOR_PRIVATE (monitor);
237
233
                if (!medium)
238
234
                        continue;
239
235
 
240
 
                if ((type & BRASERO_MEDIA_TYPE_CD) == type
241
 
                && (brasero_medium_get_status (medium) & BRASERO_MEDIUM_CD)) {
242
 
                        /* If used alone, returns all CDs */
243
 
                        list = g_slist_prepend (list, medium);
244
 
                        g_object_ref (medium);
245
 
                        continue;
246
 
                }
247
 
 
248
236
                if ((type & BRASERO_MEDIA_TYPE_ANY_IN_BURNER)
249
237
                &&  (brasero_drive_can_write (drive))) {
250
 
                        if ((type & BRASERO_MEDIA_TYPE_CD)) {
251
 
                                if ((brasero_medium_get_status (medium) & BRASERO_MEDIUM_CD)) {
252
 
                                        list = g_slist_prepend (list, medium);
253
 
                                        g_object_ref (medium);
254
 
                                        continue;
255
 
                                }
256
 
                        }
257
 
                        else {
258
 
                                list = g_slist_prepend (list, medium);
259
 
                                g_object_ref (medium);
260
 
                                continue;
261
 
                        }
 
238
                        list = g_slist_prepend (list, medium);
 
239
                        g_object_ref (medium);
262
240
                        continue;
263
241
                }
264
242
 
265
243
                if ((type & BRASERO_MEDIA_TYPE_AUDIO)
266
244
                && !(brasero_medium_get_status (medium) & BRASERO_MEDIUM_FILE)
267
245
                &&  (brasero_medium_get_status (medium) & BRASERO_MEDIUM_HAS_AUDIO)) {
268
 
                        if ((type & BRASERO_MEDIA_TYPE_CD)) {
269
 
                                if ((brasero_medium_get_status (medium) & BRASERO_MEDIUM_CD)) {
270
 
                                        list = g_slist_prepend (list, medium);
271
 
                                        g_object_ref (medium);
272
 
                                        continue;
273
 
                                }
274
 
                        }
275
 
                        else {
276
 
                                list = g_slist_prepend (list, medium);
277
 
                                g_object_ref (medium);
278
 
                                continue;
279
 
                        }
 
246
                        list = g_slist_prepend (list, medium);
 
247
                        g_object_ref (medium);
280
248
                        continue;
281
249
                }
282
250
 
283
251
                if ((type & BRASERO_MEDIA_TYPE_DATA)
284
252
                && !(brasero_medium_get_status (medium) & BRASERO_MEDIUM_FILE)
285
253
                &&  (brasero_medium_get_status (medium) & BRASERO_MEDIUM_HAS_DATA)) {
286
 
                        if ((type & BRASERO_MEDIA_TYPE_CD)) {
287
 
                                if ((brasero_medium_get_status (medium) & BRASERO_MEDIUM_CD)) {
288
 
                                        list = g_slist_prepend (list, medium);
289
 
                                        g_object_ref (medium);
290
 
                                        continue;
291
 
                                }
292
 
                        }
293
 
                        else {
294
 
                                list = g_slist_prepend (list, medium);
295
 
                                g_object_ref (medium);
296
 
                                continue;
297
 
                        }
 
254
                        list = g_slist_prepend (list, medium);
 
255
                        g_object_ref (medium);
298
256
                        continue;
299
257
                }
300
258
 
301
259
                if (type & BRASERO_MEDIA_TYPE_WRITABLE) {
302
260
                        if (brasero_medium_can_be_written (medium)) {
303
 
                                if ((type & BRASERO_MEDIA_TYPE_CD)) {
304
 
                                        if ((brasero_medium_get_status (medium) & BRASERO_MEDIUM_CD)) {
305
 
                                                list = g_slist_prepend (list, medium);
306
 
                                                g_object_ref (medium);
307
 
                                                continue;
308
 
                                        }
309
 
                                }
310
 
                                else {
311
 
                                        list = g_slist_prepend (list, medium);
312
 
                                        g_object_ref (medium);
313
 
                                        continue;
314
 
                                }
 
261
                                list = g_slist_prepend (list, medium);
 
262
                                g_object_ref (medium);
 
263
                                continue;
315
264
                        }
316
265
                }
317
266
 
318
267
                if (type & BRASERO_MEDIA_TYPE_REWRITABLE) {
319
268
                        if (brasero_medium_can_be_rewritten (medium)) {
320
 
                                if ((type & BRASERO_MEDIA_TYPE_CD)) {
321
 
                                        if ((brasero_medium_get_status (medium) & BRASERO_MEDIUM_CD)) {
322
 
                                                list = g_slist_prepend (list, medium);
323
 
                                                g_object_ref (medium);
324
 
                                                continue;
325
 
                                        }
326
 
                                }
327
 
                                else {
328
 
                                        list = g_slist_prepend (list, medium);
329
 
                                        g_object_ref (medium);
330
 
                                        continue;
331
 
                                }
 
269
                                list = g_slist_prepend (list, medium);
 
270
                                g_object_ref (medium);
332
271
                                continue;
333
272
                        }
334
273
                }
335
274
 
336
275
                if (type & BRASERO_MEDIA_TYPE_FILE) {
 
276
                        BraseroDrive *drive;
 
277
 
337
278
                        /* make sure the drive is indeed a fake one
338
279
                         * since it can happen that some medium did
339
280
                         * not properly carry out their initialization 
340
281
                         * and are flagged as BRASERO_MEDIUM_FILE
341
282
                         * whereas they are not */
 
283
                        drive = brasero_medium_get_drive (medium);
342
284
                        if (brasero_drive_is_fake (drive)) {
343
285
                                list = g_slist_prepend (list, medium);
344
286
                                g_object_ref (medium);
373
315
 
374
316
static gboolean
375
317
brasero_medium_monitor_is_drive (BraseroMediumMonitor *monitor,
376
 
                                 const gchar *device)
 
318
                                 GDrive *gdrive)
377
319
{
378
320
        BraseroMediumMonitorPrivate *priv;
379
321
        BraseroDeviceHandle *handle;
380
322
        BraseroScsiErrCode code;
381
323
        gboolean result;
 
324
        gchar *device;
382
325
 
383
326
        priv = BRASERO_MEDIUM_MONITOR_PRIVATE (monitor);
384
327
 
 
328
        device = g_drive_get_identifier (gdrive, G_VOLUME_IDENTIFIER_KIND_UNIX_DEVICE);
385
329
        BRASERO_MEDIA_LOG ("Testing drive %s", device);
386
330
 
387
331
        handle = brasero_device_handle_open (device, FALSE, &code);
 
332
        g_free (device);
 
333
 
388
334
        if (!handle)
389
335
                return FALSE;
390
336
 
397
343
}
398
344
 
399
345
static void
400
 
brasero_medium_monitor_device_added (BraseroMediumMonitor *self,
401
 
                                     const gchar *device,
402
 
                                     GDrive *gdrive)
 
346
brasero_medium_monitor_connected_cb (GVolumeMonitor *monitor,
 
347
                                     GDrive *gdrive,
 
348
                                     BraseroMediumMonitor *self)
403
349
{
404
350
        BraseroMediumMonitorPrivate *priv;
405
351
        BraseroDrive *drive = NULL;
406
352
 
407
 
        priv = BRASERO_MEDIUM_MONITOR_PRIVATE (self);
408
 
 
409
 
        /* See if the drive is waiting removal.
410
 
         * This is necessary as GIO behaves strangely sometimes
411
 
         * since it sends the "disconnected" signal when a medium
412
 
         * is removed soon followed by a "connected" signal */
413
 
        drive = brasero_medium_monitor_get_drive (self, device);
414
 
        if (drive) {
415
 
                /* Just in case that drive was waiting removal */
416
 
                priv->waiting_removal = g_slist_remove (priv->waiting_removal, drive);
417
 
 
418
 
                BRASERO_MEDIA_LOG ("Added signal was emitted but the drive is in the removal list. Updating GDrive associated object.");
419
 
                g_object_set (drive,
420
 
                              "gdrive", gdrive,
421
 
                              NULL);
422
 
 
423
 
                g_object_unref (drive);
424
 
                return;
425
 
        }
426
 
 
427
 
        /* Make sure it's an optical drive */
428
 
        if (!brasero_medium_monitor_is_drive (self, device))
 
353
        if (!brasero_medium_monitor_is_drive (self, gdrive))
429
354
                return;
430
355
 
431
356
        BRASERO_MEDIA_LOG ("New drive added");
432
357
 
 
358
        priv = BRASERO_MEDIUM_MONITOR_PRIVATE (self);
433
359
        drive = g_object_new (BRASERO_TYPE_DRIVE,
434
 
                              "device", device,
435
360
                              "gdrive", gdrive,
436
361
                              NULL);
437
362
        priv->drives = g_slist_prepend (priv->drives, drive);
461
386
}
462
387
 
463
388
static void
464
 
brasero_medium_monitor_connected_cb (GVolumeMonitor *monitor,
465
 
                                     GDrive *gdrive,
466
 
                                     BraseroMediumMonitor *self)
467
 
{
468
 
        gchar *device;
469
 
 
470
 
        BRASERO_MEDIA_LOG ("GDrive addition signal");
471
 
 
472
 
        device = g_drive_get_identifier (gdrive, G_VOLUME_IDENTIFIER_KIND_UNIX_DEVICE);
473
 
        brasero_medium_monitor_device_added (self, device, gdrive);
474
 
        g_free (device);
475
 
}
476
 
 
477
 
static void
478
 
brasero_medium_monitor_volume_added_cb (GVolumeMonitor *monitor,
479
 
                                        GVolume *gvolume,
480
 
                                        BraseroMediumMonitor *self)
481
 
{
482
 
        gchar *device;
483
 
        GDrive *gdrive;
484
 
 
485
 
        BRASERO_MEDIA_LOG ("GVolume addition signal");
486
 
 
487
 
        /* No need to signal that addition if the GVolume
488
 
         * object has an associated GDrive as this is just
489
 
         * meant to trap blank discs which have no GDrive
490
 
         * associated but a GVolume. */
491
 
        gdrive = g_volume_get_drive (gvolume);
492
 
        if (gdrive) {
493
 
                g_object_unref (gdrive);
494
 
                return;
495
 
        }
496
 
 
497
 
        device = g_volume_get_identifier (gvolume, G_VOLUME_IDENTIFIER_KIND_UNIX_DEVICE);
498
 
        if  (!device)
499
 
                return;
500
 
 
501
 
        brasero_medium_monitor_device_added (self, device, NULL);
502
 
        g_free (device);
503
 
}
504
 
 
505
 
static gboolean
506
 
brasero_medium_monitor_disconnected_real (gpointer data)
507
 
{
508
 
        BraseroMediumMonitor *self = BRASERO_MEDIUM_MONITOR (data);
509
 
        BraseroMediumMonitorPrivate *priv;
510
 
        BraseroMedium *medium;
511
 
        BraseroDrive *drive;
512
 
 
513
 
        priv = BRASERO_MEDIUM_MONITOR_PRIVATE (self);
514
 
 
515
 
        if (!priv->waiting_removal) {
516
 
                priv->waiting_removal_id = 0;
517
 
                return FALSE;
518
 
        }
519
 
 
520
 
        drive = priv->waiting_removal->data;
521
 
        priv->waiting_removal = g_slist_remove (priv->waiting_removal, drive);
522
 
 
523
 
        BRASERO_MEDIA_LOG ("Drive removed");
524
 
        medium = brasero_drive_get_medium (drive);
525
 
 
526
 
        /* disconnect the signal handlers to avoid having the "medium-removed" fired twice */
527
 
        g_signal_handlers_disconnect_by_func (drive,
528
 
                                              brasero_medium_monitor_medium_added_cb,
529
 
                                              self);
530
 
        g_signal_handlers_disconnect_by_func (drive,
531
 
                                              brasero_medium_monitor_medium_removed_cb,
532
 
                                              self);
533
 
 
534
 
        if (medium)
535
 
                g_signal_emit (self,
536
 
                               medium_monitor_signals [MEDIUM_REMOVED],
537
 
                               0,
538
 
                               medium);
539
 
 
540
 
        priv->drives = g_slist_remove (priv->drives, drive);
541
 
        g_signal_emit (self,
542
 
                       medium_monitor_signals [DRIVE_REMOVED],
543
 
                       0,
544
 
                       drive);
545
 
        g_object_unref (drive);
546
 
 
547
 
        /* in case there are more */
548
 
        return TRUE;
549
 
}
550
 
 
551
 
static void
552
 
brasero_medium_monitor_device_removed (BraseroMediumMonitor *self,
553
 
                                       const gchar *device,
554
 
                                       GDrive *gdrive)
555
 
{
556
 
        BraseroMediumMonitorPrivate *priv;
557
 
        GDrive *associated_gdrive;
558
 
        BraseroDrive *drive;
559
 
 
560
 
        priv = BRASERO_MEDIUM_MONITOR_PRIVATE (self);
561
 
 
562
 
        /* Make sure it's one already detected */
563
 
        /* GIO behaves strangely: every time a medium 
564
 
         * is removed from a drive it emits the disconnected
565
 
         * signal (which IMO it shouldn't) soon followed by
566
 
         * a connected signal.
567
 
         * So delay the removal by one or two seconds. */
568
 
 
569
 
        drive = brasero_medium_monitor_get_drive (self, device);
570
 
        if (!drive)
571
 
                return;
572
 
 
573
 
        if (G_UNLIKELY (g_slist_find (priv->waiting_removal, drive) != NULL)) {
574
 
                g_object_unref (drive);
575
 
                return;
576
 
        }
577
 
 
578
 
        associated_gdrive = brasero_drive_get_gdrive (drive);
579
 
        if (associated_gdrive == gdrive) {
580
 
                BRASERO_MEDIA_LOG ("Found device to remove");
581
 
                priv->waiting_removal = g_slist_append (priv->waiting_removal, drive);
582
 
 
583
 
                if (!priv->waiting_removal_id)
584
 
                        priv->waiting_removal_id = g_timeout_add_seconds (2,
585
 
                                                                          brasero_medium_monitor_disconnected_real, 
586
 
                                                                          self);
587
 
        }
588
 
        else if (associated_gdrive) {
589
 
                /* do nothing and wait for a "drive-disconnected" signal */
590
 
                g_object_unref (associated_gdrive);
591
 
        }
592
 
 
593
 
        g_object_unref (drive);
594
 
}
595
 
 
596
 
static void
597
 
brasero_medium_monitor_volume_removed_cb (GVolumeMonitor *monitor,
598
 
                                          GVolume *gvolume,
599
 
                                          BraseroMediumMonitor *self)
600
 
{
601
 
        gchar *device;
602
 
        GDrive *gdrive;
603
 
 
604
 
        BRASERO_MEDIA_LOG ("Volume removal signal");
605
 
 
606
 
        /* No need to signal that removal if the GVolume
607
 
         * object has an associated GDrive as this is just
608
 
         * meant to trap blank discs which have no GDrive
609
 
         * associated but a GVolume. */
610
 
        gdrive = g_volume_get_drive (gvolume);
611
 
        if (gdrive) {
612
 
                g_object_unref (gdrive);
613
 
                return;
614
 
        }
615
 
 
616
 
        device = g_volume_get_identifier (gvolume, G_VOLUME_IDENTIFIER_KIND_UNIX_DEVICE);
617
 
        if (!device)
618
 
                return;
619
 
 
620
 
        brasero_medium_monitor_device_removed (self, device, NULL);
621
 
        g_free (device);
622
 
}
623
 
 
624
 
static void
625
389
brasero_medium_monitor_disconnected_cb (GVolumeMonitor *monitor,
626
390
                                        GDrive *gdrive,
627
391
                                        BraseroMediumMonitor *self)
628
392
{
629
 
        gchar *device;
630
 
 
631
 
        BRASERO_MEDIA_LOG ("Drive removal signal");
632
 
 
633
 
        device = g_drive_get_identifier (gdrive, G_VOLUME_IDENTIFIER_KIND_UNIX_DEVICE);
634
 
        brasero_medium_monitor_device_removed (self, device, gdrive);
635
 
        g_free (device);
 
393
        BraseroMediumMonitorPrivate *priv;
 
394
        GSList *next;
 
395
        GSList *iter;
 
396
 
 
397
        priv = BRASERO_MEDIUM_MONITOR_PRIVATE (self);
 
398
 
 
399
        BRASERO_MEDIA_LOG ("Device removed");
 
400
 
 
401
        for (iter = priv->drives; iter; iter = next) {
 
402
                GDrive *gdrive_iter;
 
403
                BraseroDrive *drive;
 
404
 
 
405
                drive = iter->data;
 
406
                next = iter->next;
 
407
 
 
408
                gdrive_iter = brasero_drive_get_gdrive (drive);
 
409
                if (gdrive == gdrive_iter) {
 
410
                        BraseroMedium *medium;
 
411
 
 
412
                        BRASERO_MEDIA_LOG ("Drive removed");
 
413
                        medium = brasero_drive_get_medium (drive);
 
414
                        if (medium)
 
415
                                g_signal_emit (self,
 
416
                                               medium_monitor_signals [MEDIUM_REMOVED],
 
417
                                               0,
 
418
                                               medium);
 
419
 
 
420
                        priv->drives = g_slist_remove (priv->drives, drive);
 
421
                        g_signal_emit (self,
 
422
                                       medium_monitor_signals [DRIVE_REMOVED],
 
423
                                       0,
 
424
                                       drive);
 
425
                        g_object_unref (drive);
 
426
                }
 
427
        }
636
428
}
637
429
 
638
430
static void
640
432
{
641
433
        GList *iter;
642
434
        GList *drives;
643
 
        GList *volumes;
644
435
        BraseroDrive *drive;
645
436
        BraseroMediumMonitorPrivate *priv;
646
437
 
648
439
 
649
440
        BRASERO_MEDIA_LOG ("Probing drives and media");
650
441
 
 
442
        /* This must done early on. GVolumeMonitor when it relies on HAL (like
 
443
         * us) must be able to update its list of volumes before us so it must
 
444
         * connect to HAL before us. */
651
445
        priv->gmonitor = g_volume_monitor_get ();
652
446
 
653
447
        drives = g_volume_monitor_get_connected_drives (priv->gmonitor);
655
449
 
656
450
        for (iter = drives; iter; iter = iter->next) {
657
451
                GDrive *gdrive;
658
 
                gchar *device;
659
452
 
660
453
                gdrive = iter->data;
661
 
 
662
 
                device = g_drive_get_identifier (gdrive, G_VOLUME_IDENTIFIER_KIND_UNIX_DEVICE);
663
 
                if (brasero_medium_monitor_is_drive (object, device)) {
 
454
                if (brasero_medium_monitor_is_drive (object, gdrive)) {
664
455
                        drive = g_object_new (BRASERO_TYPE_DRIVE,
665
 
                                              "device", device,
666
456
                                              "gdrive", gdrive,
667
457
                                              NULL);
668
 
 
669
458
                        priv->drives = g_slist_prepend (priv->drives, drive);
670
459
 
671
460
                        g_signal_connect (drive,
677
466
                                          G_CALLBACK (brasero_medium_monitor_medium_removed_cb),
678
467
                                          object);
679
468
                }
680
 
                g_free (device);
681
469
        }
682
470
        g_list_foreach (drives, (GFunc) g_object_unref, NULL);
683
471
        g_list_free (drives);
684
472
 
685
 
        volumes = g_volume_monitor_get_volumes (priv->gmonitor);
686
 
        BRASERO_MEDIA_LOG ("Found %d volumes", g_list_length (volumes));
687
 
 
688
 
        for (iter = volumes; iter; iter = iter->next) {
689
 
                GVolume *gvolume;
690
 
                gchar *device;
691
 
 
692
 
                gvolume = iter->data;
693
 
                device = g_volume_get_identifier (gvolume, G_VOLUME_IDENTIFIER_KIND_UNIX_DEVICE);
694
 
                if (!device)
695
 
                        continue;
696
 
 
697
 
                /* make sure it isn't already in our list */
698
 
                drive = brasero_medium_monitor_get_drive (object, device);
699
 
                if (drive) {
700
 
                        g_free (device);
701
 
                        g_object_unref (drive);
702
 
                        continue;
703
 
                }
704
 
 
705
 
                if (brasero_medium_monitor_is_drive (object, device)) {
706
 
                        drive = g_object_new (BRASERO_TYPE_DRIVE,
707
 
                                              "device", device,
708
 
                                              "gdrive", NULL,
709
 
                                              NULL);
710
 
                        priv->drives = g_slist_prepend (priv->drives, drive);
711
 
 
712
 
                        g_signal_connect (drive,
713
 
                                          "medium-added",
714
 
                                          G_CALLBACK (brasero_medium_monitor_medium_added_cb),
715
 
                                          object);
716
 
                        g_signal_connect (drive,
717
 
                                          "medium-removed",
718
 
                                          G_CALLBACK (brasero_medium_monitor_medium_removed_cb),
719
 
                                          object);
720
 
                }
721
 
 
722
 
                g_free (device);
723
 
        }
724
 
        g_list_foreach (volumes, (GFunc) g_object_unref, NULL);
725
 
        g_list_free (volumes);
726
 
 
727
 
        g_signal_connect (priv->gmonitor,
728
 
                          "volume-added",
729
 
                          G_CALLBACK (brasero_medium_monitor_volume_added_cb),
730
 
                          object);
731
 
        g_signal_connect (priv->gmonitor,
732
 
                          "volume-removed",
733
 
                          G_CALLBACK (brasero_medium_monitor_volume_removed_cb),
734
 
                          object);
735
473
        g_signal_connect (priv->gmonitor,
736
474
                          "drive-connected",
737
475
                          G_CALLBACK (brasero_medium_monitor_connected_cb),
742
480
                          object);
743
481
 
744
482
        /* add fake/file drive */
745
 
        drive = g_object_new (BRASERO_TYPE_DRIVE,
746
 
                              "device", NULL,
747
 
                              NULL);
 
483
        drive = g_object_new (BRASERO_TYPE_DRIVE, NULL);
748
484
        priv->drives = g_slist_prepend (priv->drives, drive);
749
485
 
750
486
        return;
757
493
 
758
494
        priv = BRASERO_MEDIUM_MONITOR_PRIVATE (object);
759
495
 
760
 
        if (priv->waiting_removal_id) {
761
 
                g_source_remove (priv->waiting_removal_id);
762
 
                priv->waiting_removal_id = 0;
763
 
        }
764
 
 
765
 
        if (priv->waiting_removal) {
766
 
                g_slist_free (priv->waiting_removal);
767
 
                priv->waiting_removal = NULL;
768
 
        }
769
 
 
770
496
        if (priv->drives) {
771
497
                g_slist_foreach (priv->drives, (GFunc) g_object_unref, NULL);
772
498
                g_slist_free (priv->drives);
775
501
 
776
502
        if (priv->gmonitor) {
777
503
                g_signal_handlers_disconnect_by_func (priv->gmonitor,
778
 
                                                      brasero_medium_monitor_volume_added_cb,
779
 
                                                      object);
780
 
                g_signal_handlers_disconnect_by_func (priv->gmonitor,
781
 
                                                      brasero_medium_monitor_volume_removed_cb,
782
 
                                                      object);
783
 
                g_signal_handlers_disconnect_by_func (priv->gmonitor,
784
504
                                                      brasero_medium_monitor_connected_cb,
785
505
                                                      object);
786
506
                g_signal_handlers_disconnect_by_func (priv->gmonitor,