Ticket #601: hotplug_hdd_v2.diff

File hotplug_hdd_v2.diff, 27.3 KB (added by Aaron McCarthy <mccarthy.aaron@…>, 15 years ago)
  • libs/libmyth/mythmedia.cpp

     
    1717
    1818// end for testing
    1919
     20static const QString PATHTO_PMOUNT("/usr/bin/pmount");
     21static const QString PATHTO_PUMOUNT("/usr/bin/pumount");
    2022static const QString PATHTO_MOUNT("/bin/mount");
    2123static const QString PATHTO_UNMOUNT("/bin/umount");
    2224static const QString PATHTO_MOUNTS("/proc/mounts");
     
    2527{
    2628    "MEDIASTAT_ERROR",
    2729    "MEDIASTAT_UNKNOWN",
     30    "MEDIASTAT_UNPLUGGED",
    2831    "MEDIASTAT_OPEN",
    2932    "MEDIASTAT_USEABLE",
    3033    "MEDIASTAT_NOTMOUNTED",
     
    5760    m_Locked = false;
    5861    m_DeviceHandle = -1;
    5962    m_SuperMount = SuperMount;
    60     m_Status = (isMounted(true)) ? MEDIASTAT_MOUNTED : MEDIASTAT_NOTMOUNTED;
     63    m_Status = MEDIASTAT_UNKNOWN;
     64    m_MediaType = MEDIATYPE_UNKNOWN;
    6165}
    6266
    6367bool MythMediaDevice::openDevice()
     
    98102    if (!m_SuperMount)
    99103    {
    100104        // Build a command line for mount/unmount and execute it...  Is there a better way to do this?
    101         MountCommand = QString("%1 %2")
    102             .arg((DoMount) ? PATHTO_MOUNT : PATHTO_UNMOUNT)
    103             .arg(m_DevicePath);
     105        if (QFile(PATHTO_PMOUNT).exists() && QFile(PATHTO_PUMOUNT).exists())
     106            MountCommand = QString("%1 %2")
     107                .arg((DoMount) ? PATHTO_PMOUNT : PATHTO_PUMOUNT)
     108                .arg(m_DevicePath);
     109        else
     110            MountCommand = QString("%1 %2")
     111                .arg((DoMount) ? PATHTO_MOUNT : PATHTO_UNMOUNT)
     112                .arg(m_DevicePath);
    104113   
    105114        VERBOSE(VB_IMPORTANT,  QString("Executing '%1'").arg(MountCommand));
    106115        if (0 == myth_system(MountCommand))
    107116        {
    108117            if (DoMount)
    109118            {
     119                // we cannot tell beforehand what the pmount mount point is
     120                // so verify the mount status of the device
     121                isMounted(true);
    110122                m_Status = MEDIASTAT_MOUNTED;
    111123                onDeviceMounted();
    112124            }
     
    213225            // the disk is not / should not be mounted.
    214226            case MEDIASTAT_ERROR:
    215227            case MEDIASTAT_OPEN:
    216                 if (MEDIASTAT_MOUNTED == OldStatus)
    217                     unmount();
    218                 break;
    219228            case MEDIASTAT_NOTMOUNTED:
    220                 if (MEDIASTAT_MOUNTED == OldStatus)
     229                if (isMounted(true))
    221230                    unmount();
    222                 // If we're here it's possible there's unmounted media in the device so try to mount it.
    223                 // The case of no media in the deivce whould be handeled by derived classes and sent
    224                 // as MEDIASTAT_OPEN, MEDISTAT_ERROR or MEDIASTAT_UNKNOWN.
    225                 mount();
    226231                break;
    227232            case MEDIASTAT_UNKNOWN:
    228233            case MEDIASTAT_USEABLE:
    229234            case MEDIASTAT_MOUNTED:
     235            case MEDIASTAT_UNPLUGGED:
    230236                // get rid of the compiler warning...
    231237                break;
    232238        }
     
    243249    return m_Status;
    244250}
    245251
     252void MythMediaDevice::clearData()
     253{
     254    m_VolumeID = QString::null;
     255    m_KeyID = QString::null;
     256    m_MediaType = MEDIATYPE_UNKNOWN;
     257}
  • libs/libmyth/mythmediamonitor.h

     
    4848{
    4949    Q_OBJECT
    5050  public:
     51    ~MediaMonitor();
     52
    5153    bool addFSTab(void);
     54#ifdef linux
     55    bool addPMountable(void);
     56#endif
    5257    void addDevice(MythMediaDevice* pDevice);
    5358    bool addDevice(const char* dev);
    5459    bool addDevice(struct fstab* mep);
     60#ifdef linux
     61    bool addSysFSDevice(const QString &dev, bool checkPartitions);
     62    bool removeDevice(const QString &dev);
     63    void checkUDev();
     64#endif
    5565
    5666    bool isActive(void) const { return m_Active; }
    5767    void checkDevices(void);
    5868    void startMonitoring(void);
    5969    void stopMonitoring(void);
    6070    QValueList <MythMediaDevice*> getMedias(MediaType mediatype);
     71
     72    void chooseAndEjectMedia();
    6173   
    6274    static MediaMonitor* getMediaMonitor();
    6375   
     
    7082    bool m_Active;
    7183    MonitorThread m_Thread;
    7284    bool m_AllowEject;
     85#ifdef linux
     86    int fifo;
     87#endif
     88
     89  private:
     90#ifdef linux
     91    QString getDeviceFile(QString sysfs);
     92    QStringList getCDROMBlockDevices();
     93#endif
    7394};
    7495
    7596#endif
  • libs/libmyth/mythcdrom.h

     
    1919    virtual bool checkOK(void) = 0;
    2020    virtual bool openDevice(void);
    2121    virtual MediaStatus checkMedia(void) = 0;
    22     //virtual MediaError eject(void) = 0;
     22    //virtual MediaError eject(bool open_close = true) = 0;
    2323    //virtual MediaError lock(void) = 0;
    2424    //virtual MediaError unlock(void) = 0;
    2525
     
    4242    virtual bool mediaChanged(void);
    4343    virtual bool checkOK(void);
    4444    virtual MediaStatus checkMedia(void);
    45     virtual MediaError eject(void);
     45    virtual MediaError eject(bool open_close = true);
    4646    virtual MediaError lock(void);
    4747    virtual MediaError unlock(void);
    4848};
     
    6060    virtual bool mediaChanged(void);
    6161    virtual bool checkOK(void);
    6262    virtual MediaStatus checkMedia(void);
    63     virtual MediaError eject(void);
     63    virtual MediaError eject(bool open_close = true);
    6464    virtual MediaError lock(void);
    6565    virtual MediaError unlock(void);
    6666};
  • libs/libmyth/mythdialogs.cpp

     
    234234    RegisterKey("Global", "7", "7", "7");
    235235    RegisterKey("Global", "8", "8", "8");
    236236    RegisterKey("Global", "9", "9", "9");
     237
     238    RegisterKey("Global", "EJECT", "Eject Removable Media", "e");
    237239}
    238240
    239241MythMainWindow::~MythMainWindow()
     
    11041106            }
    11051107            else if (action == "MENU")
    11061108                emit menuButtonPressed();
     1109            else if (action == "EJECT" && QString(name()) != "eject media")
     1110            {
     1111                MediaMonitor *mon = MediaMonitor::getMediaMonitor();
     1112                if (mon)
     1113                    mon->chooseAndEjectMedia();
     1114            }
    11071115            else
    11081116                handled = false;
    11091117        }
  • libs/libmyth/libmyth.pro

     
    6767}
    6868
    6969unix {
    70     SOURCES += mythcdrom.cpp mythmediamonitor.cpp
    71     HEADERS += mythcdrom.h   mythmediamonitor.h
    72     inc.files += mythcdrom.h mythmediamonitor.h
     70    SOURCES += mythhdd.cpp mythcdrom.cpp mythmediamonitor.cpp
     71    HEADERS += mythhdd.h mythcdrom.h   mythmediamonitor.h
     72    inc.files += mythhdd.h mythcdrom.h mythmediamonitor.h
    7373}
    7474
    7575macx {
  • libs/libmyth/mythmediamonitor.cpp

     
    11#include "mythmediamonitor.h"
    22#include "mythcdrom.h"
     3#include "mythhdd.h"
    34#include <qapplication.h>
     5#include <qprocess.h>
     6#include <qdir.h>
     7#include <qfile.h>
    48#include <sys/file.h>
    59#include <fcntl.h>
    610#include <dirent.h>
     
    913#include <iostream>
    1014#include <sys/types.h>
    1115#include <sys/stat.h>
     16#include <sys/wait.h>
    1217#include <unistd.h>
    1318
    1419#include "config.h"
    1520#include "mythcontext.h"
     21#include "mythdialogs.h"
    1622
    1723// For testing
    1824#if 0
     
    4046#endif
    4147#define SUPER_OPT_DEV "dev="
    4248
     49#ifndef UDEV_FIFO
     50#define UDEV_FIFO "/tmp/mythtv_media"
     51#endif
     52
    4353using namespace std;
    4454
    4555MediaMonitor *theMonitor = NULL;
     
    5363        {
    5464            theMonitor = new MediaMonitor(NULL, 500, true);
    5565            theMonitor->addFSTab();
     66#ifdef linux
     67            theMonitor->addPMountable();
     68#endif
    5669        }
    5770    }
    5871
    5972    return theMonitor;
    6073}
    6174
     75/** \fn MediaMonitor::chooseAndEjectMedia()
     76 *  \brief Unmounts and ejects removable media devices.
     77 *
     78 *  If no media devices are known to the MediaMonitor this function does
     79 *  nothing. If a single device is known, it is unmounted and ejected if
     80 *  possible. If mulitple devices are known, a popup box is display so the
     81 *  user can choose which device to eject.
     82 */
     83void MediaMonitor::chooseAndEjectMedia()
     84{
     85    MythMediaDevice *selected = NULL;
     86
     87    if (m_Devices.count() == 1)
     88    {
     89        if (m_Devices.first()->getAllowEject())
     90            selected = m_Devices.first();
     91    }
     92    else if (m_Devices.count() > 1)
     93    {
     94        MythPopupBox ejectbox(gContext->GetMainWindow(), "eject media");
     95
     96        ejectbox.addLabel(tr("Select removable media to eject"));
     97
     98        QValueList <MythMediaDevice *> shownDevices;
     99        QValueList <MythMediaDevice *>::Iterator it = m_Devices.begin();
     100        while (it != m_Devices.end())
     101        {
     102            // if the device is ejectable (ie a CD or DVD device)
     103            // or if it is mounted (ie a USB memory stick)
     104            // then add it to the list of choices
     105            if ((*it)->getAllowEject() || (*it)->isMounted(true))
     106            {
     107                shownDevices.append(*it);
     108
     109                if ((*it)->getVolumeID() != "")
     110                    ejectbox.addButton((*it)->getVolumeID());
     111                else
     112                    ejectbox.addButton((*it)->getDevicePath());
     113            }
     114
     115            it++;
     116        }
     117
     118        ejectbox.addButton(tr("Cancel"))->setFocus();
     119
     120        int ret = ejectbox.ExecPopup();
     121
     122        if (ret < (int)shownDevices.count())
     123            selected = shownDevices[ret];
     124    }
     125
     126    if (selected)
     127    {
     128        switch (selected->getStatus())
     129        {
     130            case MEDIASTAT_OPEN     : selected->eject(false);
     131                                      break;
     132            case MEDIASTAT_MOUNTED  : cerr << "media is mounted" << endl;
     133                                      selected->unmount();
     134
     135                                      if (selected->isMounted(true))
     136                                      {
     137                                          MythPopupBox::showOkPopup(
     138                                             gContext->GetMainWindow(),
     139                                             "eject unmount fail",
     140                                             QString(tr("Failed unmounting %1"))
     141                                               .arg(selected->getDevicePath()));
     142                                          break;
     143                                      }
     144            default                 : // attempt to unlock and eject media
     145                                      selected->unlock();
     146                                      if (selected->eject() == MEDIAERR_UNSUPPORTED)
     147                                      {
     148                                          MythPopupBox::showOkPopup(
     149                                             gContext->GetMainWindow(),
     150                                             "eject success",
     151                                             QString(tr("You may safely remove %1"))
     152                                               .arg(selected->getDevicePath()));
     153                                      }
     154                                      else if (selected->eject() == MEDIAERR_FAILED)
     155                                      {
     156                                          MythPopupBox::showOkPopup(
     157                                             gContext->GetMainWindow(),
     158                                             "eject fail",
     159                                             QString(tr("Failed Ejecting %1"))
     160                                               .arg(selected->getDevicePath()));
     161                                      }
     162        }
     163    }
     164}
     165
    62166// MonitorThread
    63167MonitorThread::MonitorThread(MediaMonitor* pMon, unsigned long interval)
    64168             : QThread()
     
    88192    m_AllowEject = allowEject;
    89193    m_Active = false;
    90194    m_Thread.setMonitor(this);
     195#ifdef linux
     196    fifo = 0;
     197#endif
    91198}
    92199
     200MediaMonitor::~MediaMonitor()
     201{
     202#ifdef linux
     203    if (fifo)
     204    {
     205        close(fifo);
     206        unlink(UDEV_FIFO);
     207    }
     208#endif
     209}
     210
    93211// Loop through the file system table and add any supported devices.
    94212bool MediaMonitor::addFSTab()
    95213{
     
    119237    return true;
    120238}
    121239
     240#ifdef linux
     241/** \fn MediaMonitor::addPMountable()
     242 *  \brief Search /sys/block for valid removable media devices.
     243 *
     244 *  This function creates MediaDevice instances for valid removable media
     245 *  devices found under the /sys/block filesystem in Linux.  CD and DVD
     246 *  devices are created as MythCDROM instances.  MythHDD instances will be
     247 *  created for each partition on removable hard disc devices, if they exists.
     248 *  Otherwise a single MythHDD instance will be created for the entire disc.
     249 *  Floppy discs are ignored.
     250 */
     251bool MediaMonitor::addPMountable()
     252{
     253    mkfifo(UDEV_FIFO, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH);
     254    fifo = open(UDEV_FIFO, O_RDONLY | O_NONBLOCK);
     255
     256    QDir sysfs("/sys/block");
     257    sysfs.setFilter(QDir::Dirs);
     258
     259    QStringList devices = sysfs.entryList();
     260
     261    for (QStringList::Iterator it = devices.begin(); it != devices.end(); ++it)
     262    {
     263        if (*it == "." || *it == "..")
     264            continue;
     265
     266        // we don't do floppies.
     267        if ((*it).startsWith("fd"))
     268            continue;
     269
     270        sysfs.cd(*it);
     271
     272        QFile removable(sysfs.absFilePath("removable"));
     273        if (removable.exists())
     274        {
     275            removable.open(IO_ReadOnly);
     276            int c = removable.getch();
     277            removable.close();
     278
     279            if (c == '1')
     280                addSysFSDevice(sysfs.absPath(), true);
     281        }
     282        sysfs.cdUp();
     283    }
     284    return true;
     285}
     286
     287/** \fn MediaMonitor::getDeviceFile(QString)
     288 *  \brief Returns the device special file associated with the /sys/block node.
     289 *  \param [in]sysfs sysfs path of removable block device.
     290 *  \return path to the device special file
     291 */
     292QString MediaMonitor::getDeviceFile(QString sysfs)
     293{
     294    QProcess udevinfo(this);
     295    udevinfo.addArgument("udevinfo");
     296    udevinfo.addArgument("-q");
     297    udevinfo.addArgument("name");
     298    udevinfo.addArgument("-rp");
     299    udevinfo.addArgument(sysfs);
     300    udevinfo.setCommunication(QProcess::Stdout);
     301
     302    udevinfo.start();
     303
     304    int status;
     305    waitpid(udevinfo.processIdentifier(), &status, 0);
     306
     307    QString ret = udevinfo.readLineStdout();
     308    if (ret != "device not found in database")
     309        return ret;
     310    else
     311        return QString::null;
     312}
     313
     314/** \fn MediaMonitor::getCDROMBlockDevices()
     315 *  \brief Reads the list devices known to be CD or DVD devices.
     316 *  \return list of CD and DVD device names.
     317 */
     318QStringList MediaMonitor::getCDROMBlockDevices()
     319{
     320    QStringList l;
     321
     322    QFile file("/proc/sys/dev/cdrom/info");
     323    if (file.open(IO_ReadOnly))
     324    {
     325        QTextStream stream(&file);
     326        QString line;
     327        while (!stream.atEnd())
     328        {
     329            line = stream.readLine();
     330            if (line.startsWith("drive name:"))
     331            {
     332                QString s = line.section('\t', 2, 2);
     333                l.append(s);
     334            }
     335        }
     336        file.close();
     337    }
     338    return l;
     339}
     340#endif
     341
    122342// Given a media deivce add it to our collection.
    123343void MediaMonitor::addDevice(MythMediaDevice* pDevice)
    124344{
     
    271491    return false;
    272492}
    273493
     494#ifdef linux
     495/** \fn MediaMonitor::addSysFSDevice(const QString &, bool)
     496 *  \brief Creates MythMedia instances for sysfs removable media devices.
     497 *  \param [in]dev path to sysfs block device.
     498 *  \param [in]checkPartitions check for partitions on block device.
     499 *  \return true if MythMedia instances are created.
     500 *
     501 *  Block devices are represented as directories in sysfs with directories for
     502 *  each partition underneath the parent device directory.
     503 *
     504 *  This function recursively calls itself to find all partitions on a block
     505 *  device and creates a MythHDD instance for each partition found.  If no
     506 *  partitions are found and the device is a CD or DVD device a MythCDROM
     507 *  instance is created.  Otherwise a MythHDD instance is created for the
     508 *  entire block device.
     509 */
     510bool MediaMonitor::addSysFSDevice(const QString &dev, bool checkPartitions)
     511{
     512    if (checkPartitions)
     513    {
     514        // check for partitions
     515        QDir sysfs(dev);
     516        sysfs.setFilter(QDir::Dirs);
     517
     518        bool found_partitions = false;
     519        QStringList parts = sysfs.entryList();
     520        for (QStringList::Iterator pit = parts.begin();
     521             pit != parts.end(); pit++)
     522        {
     523            if (*pit == "." || *pit == "..")
     524                continue;
     525
     526            found_partitions |= addSysFSDevice(sysfs.absFilePath(*pit), false);
     527        }
     528
     529        // no partitions on block device, use main device
     530        if (!found_partitions)
     531            found_partitions |= addSysFSDevice(sysfs.absPath(), false);
     532
     533        return found_partitions;
     534    }
     535    else
     536    {
     537        QStringList cdroms = getCDROMBlockDevices();
     538
     539        if (cdroms.contains(dev.section('/', -1)))
     540        {
     541            // found cdrom device
     542            QString device_file = getDeviceFile(dev);
     543            if (!device_file.isNull())
     544            {
     545                addDevice(MythCDROM::get(this, device_file, false, m_AllowEject));
     546                return true;
     547            }
     548        }
     549        else
     550        {
     551            // found block or partition device
     552            QString device_file = getDeviceFile(dev);
     553            if (!device_file.isNull())
     554            {
     555                addDevice(MythHDD::get(this, device_file, false, false));
     556                return true;
     557            }
     558        }
     559    }
     560    return false;
     561}
     562
     563/** \fn MediaMonitor::removeDevice(const QString &)
     564 *  \brief Remove a device from the media monitor.
     565 *  \param [in]dev path to device special file to remove.
     566 *  \return true if device is removed from the Media Monitor.
     567 *
     568 *  This function is usually called after a hotpluggable device is unplugged.
     569 */
     570bool MediaMonitor::removeDevice(const QString &dev)
     571{
     572    QValueList<MythMediaDevice*>::iterator it;
     573    for (it = m_Devices.begin(); it != m_Devices.end(); it++)
     574    {
     575        if ((*it)->getDevicePath() == dev)
     576        {
     577            m_Devices.remove(it);
     578            //cerr << "remove device: " << dev.ascii() << endl;
     579            return true;
     580        }
     581    }
     582    return false;
     583}
     584
     585/** \fn MediaMonitor::checkUDev()
     586 *  \brief Checks the named pipe, UDEV_FIFO, for hotplug events from the udev system.
     587 */
     588void MediaMonitor::checkUDev()
     589{
     590    char buffer[256];
     591    QString qBuffer;
     592
     593    if (fifo)
     594    {
     595        int size = read(fifo, buffer, 255);
     596        while (size > 0)
     597        {
     598            // append buffer to QString
     599            buffer[size] = '\0';
     600
     601            qBuffer.append(buffer);
     602
     603            size = read(fifo, buffer, 255);
     604        }
     605        QStringList devs = QStringList::split('\n', qBuffer);
     606
     607        for (QStringList::Iterator it = devs.begin(); it != devs.end(); it++)
     608        {
     609            if ((*it).startsWith("add"))
     610            {
     611                QString dev = (*it).section(' ', 1, 1);
     612
     613                // check if removeable
     614                QFile removable(dev + "/removable");
     615                if (removable.exists())
     616                {
     617                    removable.open(IO_ReadOnly);
     618                    int c = removable.getch();
     619                    removable.close();
     620
     621                    if (c == '1')
     622                        addSysFSDevice((*it).section(' ', 1, 1), true);
     623                }
     624            }
     625            else if ((*it).startsWith("remove"))
     626            {
     627                removeDevice((*it).section(' ', 2, 2));
     628            }
     629        }
     630    }
     631}
     632#endif
     633
    274634// Poll the devices in our list.
    275635void MediaMonitor::checkDevices()
    276636{
     637#ifdef linux
     638    /* check if new devices have been plugged in */
     639    checkUDev();
     640#endif
     641
    277642    QValueList<MythMediaDevice*>::iterator itr = m_Devices.begin();
    278643    MythMediaDevice* pDev;
    279644    while (itr != m_Devices.end())
     
    317682        pDev = *itr;
    318683        if ((pDev->getMediaType()==mediatype) &&
    319684            ((pDev->getStatus()==MEDIASTAT_USEABLE) ||
    320             (pDev->getStatus()==MEDIASTAT_MOUNTED)))
     685             (pDev->getStatus()==MEDIASTAT_MOUNTED) ||
     686             (pDev->getStatus()==MEDIASTAT_NOTMOUNTED)))
    321687            medias.push_back(pDev);
    322688        itr++;
    323689    }
     
    344710        QApplication::postEvent((QObject*)gContext->GetMainWindow(),
    345711                                new MediaEvent(oldStatus, pMedia));
    346712    }
     713    else if (pMedia->getStatus() == MEDIASTAT_OPEN ||
     714             pMedia->getStatus() == MEDIASTAT_UNPLUGGED)
     715        pMedia->clearData();
    347716}
     717
  • libs/libmyth/mythcdrom-linux.cpp

     
    88
    99#define ASSUME_WANT_AUDIO 1
    1010
    11 MediaError MythCDROMLinux::eject()
     11MediaError MythCDROMLinux::eject(bool open_close)
    1212{
    13     return (ioctl(m_DeviceHandle, CDROMEJECT) == 0) ? MEDIAERR_OK :
    14                                                       MEDIAERR_FAILED;
     13    if (open_close)
     14        return (ioctl(m_DeviceHandle, CDROMEJECT) == 0) ? MEDIAERR_OK
     15                                                        : MEDIAERR_FAILED;
     16    else
     17        return (ioctl(m_DeviceHandle, CDROMCLOSETRAY) == 0) ? MEDIAERR_OK
     18                                                            : MEDIAERR_FAILED;
    1519}
    1620
    1721bool MythCDROMLinux::mediaChanged()
     
    8589        {
    8690            case CDS_DISC_OK:
    8791                //cout << "disk ok - ";
    88                 if (isMounted(true))
    89                     //cout << "it's mounted" << endl;
     92                // If the disc is ok and we already know it's mediatype
     93                // returns MOUNTED.
     94                if (isMounted(true) && m_MediaType != MEDIATYPE_UNKNOWN)
    9095                    return setStatus(MEDIASTAT_MOUNTED, OpenedHere);
    9196                // If the disk is ok but not yet mounted we'll test it further down after this switch exits.
    9297                break;
     
    110115        if (mediaChanged())
    111116        {
    112117            //cout << "media changed - ";
    113             // Regardless of the actual status lie here and say it's open for now, so we can over the case of a missed open.
     118            // Regardless of the actual status lie here and say it's open for now, so we can cover the case of a missed open.
    114119            return setStatus(MEDIASTAT_OPEN, OpenedHere);
    115120        }
    116121        else
     
    136141                        this->m_KeyID = QString("%1%2")
    137142                                      .arg(this->m_VolumeID)
    138143                                      .arg(QString(buf.creation_date).left(16));
    139                         // We'll return NOTMOUNTED  here because we're switching media.
    140                         // The base class will try to mount the deivce causing the next pass to pick up the MOUNTED status.
    141                         return setStatus(MEDIASTAT_NOTMOUNTED, OpenedHere);
     144
     145                        // attempt to mount the disc
     146                        // the base class's onDeviceMounted will do fine
     147                        // grained detection of the type of data on this disc
     148                        mount();
     149
     150                        if (isMounted(true))
     151                        {
     152                            // pretend we're NOTMOUNTED so setStatus emits
     153                            // a signal
     154                            m_Status = MEDIASTAT_NOTMOUNTED;
     155                            return setStatus(MEDIASTAT_MOUNTED, OpenedHere);
     156                        }
     157                        else if (m_MediaType == MEDIATYPE_DVD)
     158                        {
     159                            // pretend we're NOTMOUNTED so setStatus emits
     160                            // a signal
     161                            m_Status = MEDIASTAT_NOTMOUNTED;
     162                            return setStatus(MEDIASTAT_USEABLE, OpenedHere);
     163                        }
     164                        else
     165                            return setStatus(MEDIASTAT_NOTMOUNTED, OpenedHere);
    142166                        break;
    143167                    case CDS_AUDIO:
    144168                        //cout << "found an audio disk" << endl;
     
    154178                            return setStatus(MEDIASTAT_USEABLE, OpenedHere);
    155179                        #else
    156180                            mount();
    157                             return setStatus(MEDIASTAT_NOTMOUNTED, OpenedHere);
     181                            if (isMounted(true))
     182                            {
     183                                // pretend we're NOTMOUNTED so setStatus
     184                                // emits a signal
     185                                m_Status = MEDIASTAT_NOTMOUNTED;
     186                                return setStatus(MEDIASTAT_MOUNTED, OpenedHere);
     187                            }
     188                            else
     189                                return setStatus(MEDIASTAT_USEABLE, OpenedHere);
    158190                        #endif
    159191                        break;
    160192                    case CDS_NO_INFO:
     
    174206                     m_Status == MEDIASTAT_NOTMOUNTED)
    175207            {
    176208                //cout << "current status == " << MythMediaDevice::MediaStatusStrings[m_Status] << " setting status to not mounted - ";
    177                 setStatus(MEDIASTAT_NOTMOUNTED, OpenedHere);
     209                if (isMounted(true))
     210                    setStatus(MEDIASTAT_MOUNTED, OpenedHere);
     211                else
     212                    setStatus(MEDIASTAT_NOTMOUNTED, OpenedHere);
    178213            }
    179214
    180215            if (m_AllowEject)
  • libs/libmyth/mythcdrom-freebsd.cpp

     
    77
    88#define ASSUME_WANT_AUDIO 1
    99
    10 MediaError MythCDROMFreeBSD::eject()
     10MediaError MythCDROMFreeBSD::eject(bool open_close)
    1111{
    12     if (ioctl(m_DeviceHandle, CDIOCEJECT) == 0)
    13         return MEDIAERR_OK;
    14     return MEDIAERR_FAILED;
     12    if (open_close)
     13        return (ioctl(m_DeviceHandle, CDIOCEJECT) == 0) ? MEDIAERR_OK :
     14                                                          MEDIAERR_FAILED;
     15    else
     16        return MEDIAERR_UNSUPPORTED;
    1517}
    1618
    1719bool MythCDROMFreeBSD::mediaChanged()
  • libs/libmyth/mythmedia.h

     
    77typedef enum {
    88    MEDIASTAT_ERROR,
    99    MEDIASTAT_UNKNOWN,
     10    MEDIASTAT_UNPLUGGED,
    1011    MEDIASTAT_OPEN,
    1112    MEDIASTAT_USEABLE,   
    1213    MEDIASTAT_NOTMOUNTED,
     
    6566    virtual bool openDevice();
    6667    virtual bool closeDevice();
    6768    virtual MediaStatus checkMedia() = 0; // Derived classes MUST implement this.
    68     virtual MediaError eject() { return MEDIAERR_UNSUPPORTED; }
     69    virtual MediaError eject(bool open_close = true) { return MEDIAERR_UNSUPPORTED; }
    6970    virtual MediaError lock();
    7071    virtual MediaError unlock();
    7172    virtual bool performMountCmd( bool DoMount );   
     
    7879    static const char* MediaTypeStrings[];
    7980    static const char* MediaErrorStrings[];
    8081
     82    void clearData();
     83
    8184 signals:
    8285    void statusChanged(MediaStatus oldStatus, MythMediaDevice* pMedia);
    8386