From 401e682124655c88430437d27be9247c6ac4c3e5 Mon Sep 17 00:00:00 2001 From: Ivailo Monev Date: Tue, 8 Jun 2021 21:18:36 +0300 Subject: [PATCH] solid: stub optical disc/drive functionality on top ob UDev backend Signed-off-by: Ivailo Monev --- CMakeLists.txt | 8 ++ cmake/modules/CMakeLists.txt | 1 + cmake/modules/FindLibCDIO.cmake | 40 ++++++ solid/solid/CMakeLists.txt | 9 ++ solid/solid/backends/udev/udevdevice.cpp | 116 ++++++++++++++++++ solid/solid/backends/udev/udevmanager.cpp | 4 + solid/solid/backends/udev/udevopticaldisc.cpp | 64 ++++++++++ solid/solid/backends/udev/udevopticaldisc.h | 58 +++++++++ .../solid/backends/udev/udevopticaldrive.cpp | 92 ++++++++++++++ solid/solid/backends/udev/udevopticaldrive.h | 64 ++++++++++ 10 files changed, 456 insertions(+) create mode 100644 cmake/modules/FindLibCDIO.cmake create mode 100644 solid/solid/backends/udev/udevopticaldisc.cpp create mode 100644 solid/solid/backends/udev/udevopticaldisc.h create mode 100644 solid/solid/backends/udev/udevopticaldrive.cpp create mode 100644 solid/solid/backends/udev/udevopticaldrive.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 8e1413f7..8daacadc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -238,6 +238,14 @@ set_package_properties(UDev PROPERTIES TYPE OPTIONAL ) +macro_optional_find_package(LibCDIO) +set_package_properties(LibCDIO PROPERTIES + DESCRIPTION "GNU Compact Disc Input and Control Library" + URL "https://www.gnu.org/software/libcdio/" + PURPOSE "Allows Solid to use libcdio to provide information about CD-ROM devices on Linux" + TYPE OPTIONAL +) + ################# configure checks and create the configured files ################# include(ConfigureChecks.cmake) diff --git a/cmake/modules/CMakeLists.txt b/cmake/modules/CMakeLists.txt index 5bd62a8b..ffb7a3a2 100644 --- a/cmake/modules/CMakeLists.txt +++ b/cmake/modules/CMakeLists.txt @@ -15,6 +15,7 @@ set(cmakeFilesDontInstall FindDNSSD.cmake FindENCHANT.cmake FindACL.cmake + FindLibCDIO.cmake ) # Explicitly list all files which will be installed. diff --git a/cmake/modules/FindLibCDIO.cmake b/cmake/modules/FindLibCDIO.cmake new file mode 100644 index 00000000..0ceeb3f4 --- /dev/null +++ b/cmake/modules/FindLibCDIO.cmake @@ -0,0 +1,40 @@ +# Try to find libcdio, once done this will define: +# +# LIBCDIO_FOUND - system has libcdio +# LIBCDIO_INCLUDES - the libcdio include directory +# LIBCDIO_LIBRARIES - the libraries needed to use libcdio +# +# Copyright (c) 2021 Ivailo Monev +# +# Redistribution and use is allowed according to the terms of the BSD license. +# For details see the accompanying COPYING-CMAKE-SCRIPTS file. + +if(NOT WIN32) + include(FindPkgConfig) + pkg_check_modules(PC_LIBCDIO QUIET libcdio) + + set(LIBCDIO_INCLUDES ${PC_LIBCDIO_INCLUDE_DIRS}) + set(LIBCDIO_LIBRARIES ${PC_LIBCDIO_LIBRARIES}) +endif() + +set(LIBCDIO_VERSION ${PC_LIBCDIO_VERSION}) + +if(NOT LIBCDIO_INCLUDES OR NOT LIBCDIO_LIBRARIES) + find_path(LIBCDIO_INCLUDES + NAMES cdio/cdio.h + HINTS $ENV{LIBCDIODIR}/include + ) + + find_library(LIBCDIO_LIBRARIES + NAMES cdio + HINTS $ENV{LIBCDIODIR}/lib + ) +endif() + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(LibCDIO + VERSION_VAR LIBCDIO_VERSION + REQUIRED_VARS LIBCDIO_LIBRARIES LIBCDIO_INCLUDES +) + +mark_as_advanced(LIBCDIO_INCLUDES LIBCDIO_LIBRARIES) diff --git a/solid/solid/CMakeLists.txt b/solid/solid/CMakeLists.txt index e66af4bc..6c18ba89 100644 --- a/solid/solid/CMakeLists.txt +++ b/solid/solid/CMakeLists.txt @@ -156,6 +156,15 @@ if(UDEV_FOUND AND CMAKE_SYSTEM_NAME MATCHES Linux) backends/shared/udevqtclient.cpp backends/shared/udevqtdevice.cpp ) + + if(LIBCDIO_FOUND) + set(solid_LIB_SRCS ${solid_LIB_SRCS} + backends/udev/udevopticaldisc.cpp + backends/udev/udevopticaldrive.cpp + ) + add_definitions(-DUDEV_CDIO) + endif() + set(UDEV_DETAILED_OUTPUT OFF CACHE BOOL "provide extended output regarding udev events") if(UDEV_DETAILED_OUTPUT) add_definitions(-DUDEV_DETAILED_OUTPUT) diff --git a/solid/solid/backends/udev/udevdevice.cpp b/solid/solid/backends/udev/udevdevice.cpp index 00772852..2f109e35 100644 --- a/solid/solid/backends/udev/udevdevice.cpp +++ b/solid/solid/backends/udev/udevdevice.cpp @@ -40,6 +40,11 @@ #include "kglobal.h" #include "klocale.h" +#ifdef UDEV_CDIO +#include "udevopticaldisc.h" +#include "udevopticaldrive.h" +#endif + #include #include @@ -165,6 +170,40 @@ QString UDevDevice::icon() const return QLatin1String("battery"); } else if (queryDeviceInterface(Solid::DeviceInterface::Processor)) { return QLatin1String("cpu"); +#ifdef UDEV_CDIO + // TODO: if removable should return "drive-removable-media-usb" + } else if (queryDeviceInterface(Solid::DeviceInterface::OpticalDrive)) { + return QLatin1String("drive-removable-media"); + } else if (queryDeviceInterface(Solid::DeviceInterface::OpticalDisc)) { + bool isWritable = property("OpticalBlank").toBool(); // TODO: + const QString media; // TODO: + + const OpticalDisc disc(const_cast(this)); + Solid::OpticalDisc::ContentTypes availContent = disc.availableContent(); + + if (availContent & Solid::OpticalDisc::VideoDvd) { // Video DVD + return QLatin1String("media-optical-dvd-video"); + } else if ((availContent & Solid::OpticalDisc::VideoCd) || (availContent & Solid::OpticalDisc::SuperVideoCd)) { // Video CD + return QLatin1String("media-optical-video"); + } else if ((availContent & Solid::OpticalDisc::Data) && (availContent & Solid::OpticalDisc::Audio)) { // Mixed CD + return QLatin1String("media-optical-mixed-cd"); + } else if (availContent & Solid::OpticalDisc::Audio) { // Audio CD + return QLatin1String("media-optical-audio"); + } else if (availContent & Solid::OpticalDisc::Data) { // Data CD + return QLatin1String("media-optical-data"); + } else if ( isWritable ) { + return QLatin1String("media-optical-recordable"); + } else { + if ( media.startsWith( "optical_dvd" ) || media.startsWith( "optical_hddvd" ) ) { // DVD + return QLatin1String("media-optical-dvd"); + } else if ( media.startsWith( "optical_bd" ) ) { // BluRay + return QLatin1String("media-optical-blu-ray"); + } + } + + // fallback for every other optical disc + return QLatin1String("media-optical"); +#endif } else if (queryDeviceInterface(Solid::DeviceInterface::PortableMediaPlayer)) { // TODO: check out special cases like iPod return QLatin1String("multimedia-player"); @@ -288,6 +327,69 @@ QString UDevDevice::description() const // TODO: check out special cases like iPod return QObject::tr("Portable Media Player"); } +#ifdef UDEV_CDIO + } else if (queryDeviceInterface(Solid::DeviceInterface::OpticalDrive)) { + const OpticalDrive opticalDrive(const_cast(this)); + Solid::OpticalDrive::MediumTypes mediumTypes = opticalDrive.supportedMedia(); + QString first; + QString second; + bool drive_is_hotpluggable = false; // TODO: + + first = QObject::tr("CD-ROM"); + if (mediumTypes & Solid::OpticalDrive::Cdr) + first = QObject::tr("CD-R"); + if (mediumTypes & Solid::OpticalDrive::Cdrw) + first = QObject::tr("CD-RW"); + + if (mediumTypes & Solid::OpticalDrive::Dvd) + second = QObject::tr("/DVD-ROM"); + if (mediumTypes & Solid::OpticalDrive::Dvdplusr) + second = QObject::tr("/DVD+R"); + if (mediumTypes & Solid::OpticalDrive::Dvdplusrw) + second = QObject::tr("/DVD+RW"); + if (mediumTypes & Solid::OpticalDrive::Dvdr) + second = QObject::tr("/DVD-R"); + if (mediumTypes & Solid::OpticalDrive::Dvdrw) + second = QObject::tr("/DVD-RW"); + if (mediumTypes & Solid::OpticalDrive::Dvdram) + second = QObject::tr("/DVD-RAM"); + if ((mediumTypes & Solid::OpticalDrive::Dvdr) && (mediumTypes & Solid::OpticalDrive::Dvdplusr)) { + if (mediumTypes & Solid::OpticalDrive::Dvdplusdl) { + second = QObject::tr("/DVD±R DL"); + } else { + second = QObject::tr("/DVD±R"); + } + } + if ((mediumTypes & Solid::OpticalDrive::Dvdrw) && (mediumTypes & Solid::OpticalDrive::Dvdplusrw)) { + if((mediumTypes & Solid::OpticalDrive::Dvdplusdl) || (mediumTypes & Solid::OpticalDrive::Dvdplusdlrw)) { + second = QObject::tr("/DVD±RW DL"); + } else { + second = QObject::tr("/DVD±RW"); + } + } + if (mediumTypes & Solid::OpticalDrive::Bd) + second = QObject::tr("/BD-ROM"); + if (mediumTypes & Solid::OpticalDrive::Bdr) + second = QObject::tr("/BD-R"); + if (mediumTypes & Solid::OpticalDrive::Bdre) + second = QObject::tr("/BD-RE"); + if (mediumTypes & Solid::OpticalDrive::HdDvd) + second = QObject::tr("/HD DVD-ROM"); + if (mediumTypes & Solid::OpticalDrive::HdDvdr) + second = QObject::tr("/HD DVD-R"); + if (mediumTypes & Solid::OpticalDrive::HdDvdrw) + second = QObject::tr("/HD DVD-RW"); + + QString description; + if (drive_is_hotpluggable) { + description = QObject::tr("External %1%2 Drive"); + } else { + description = QObject::tr("%1%2 Drive"); + } + description = description.arg(first, second); + + return description; +#endif // UDEV_CDIO } else if (queryDeviceInterface(Solid::DeviceInterface::Camera)) { return QObject::tr("Camera"); } else if (queryDeviceInterface(Solid::DeviceInterface::Video)) { @@ -323,6 +425,13 @@ bool UDevDevice::queryDeviceInterface(const Solid::DeviceInterface::Type &type) case Solid::DeviceInterface::Processor: return property("DRIVER").toString() == "processor"; +#ifdef UDEV_CDIO + case Solid::DeviceInterface::OpticalDrive: + return (property("ID_TYPE").toString() == "cd" || property("ID_CDROM_MEDIA_CD").toInt() == 1); + case Solid::DeviceInterface::OpticalDisc: + return false; // TODO: +#endif + case Solid::DeviceInterface::Camera: return property("ID_GPHOTO2").toInt() == 1; @@ -383,6 +492,13 @@ QObject *UDevDevice::createDeviceInterface(const Solid::DeviceInterface::Type &t case Solid::DeviceInterface::Processor: return new Processor(this); +#ifdef UDEV_CDIO + case Solid::DeviceInterface::OpticalDrive: + return new OpticalDrive(this); + case Solid::DeviceInterface::OpticalDisc: + return new OpticalDisc(this); +#endif + case Solid::DeviceInterface::Camera: return new Camera(this); diff --git a/solid/solid/backends/udev/udevmanager.cpp b/solid/solid/backends/udev/udevmanager.cpp index ae8b6d66..1114e68e 100644 --- a/solid/solid/backends/udev/udevmanager.cpp +++ b/solid/solid/backends/udev/udevmanager.cpp @@ -187,6 +187,10 @@ UDevManager::UDevManager(QObject *parent) << Solid::DeviceInterface::AcAdapter << Solid::DeviceInterface::Battery << Solid::DeviceInterface::Processor +#ifdef UDEV_CDIO + << Solid::DeviceInterface::OpticalDrive + << Solid::DeviceInterface::OpticalDisc +#endif << Solid::DeviceInterface::AudioInterface << Solid::DeviceInterface::NetworkInterface << Solid::DeviceInterface::SerialInterface diff --git a/solid/solid/backends/udev/udevopticaldisc.cpp b/solid/solid/backends/udev/udevopticaldisc.cpp new file mode 100644 index 00000000..1f8afc5e --- /dev/null +++ b/solid/solid/backends/udev/udevopticaldisc.cpp @@ -0,0 +1,64 @@ +/* + Copyright 2021 Ivailo Monev + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + +#include "udevopticaldisc.h" + +using namespace Solid::Backends::UDev; + +OpticalDisc::OpticalDisc(UDevDevice *device) + : StorageVolume(device) +{ +} + +OpticalDisc::~OpticalDisc() +{ +} + +qulonglong OpticalDisc::capacity() const +{ + return 0; // TODO: +} + +bool OpticalDisc::isRewritable() const +{ + return false; // TODO: +} + +bool OpticalDisc::isBlank() const +{ + return false; // TODO: +} + +bool OpticalDisc::isAppendable() const +{ + return false; // TODO: +} + +Solid::OpticalDisc::DiscType OpticalDisc::discType() const +{ + return Solid::OpticalDisc::UnknownDiscType; // TODO: +} + +Solid::OpticalDisc::ContentTypes OpticalDisc::availableContent() const +{ + return 0; // TODO: +} + +#include "moc_udevopticaldisc.cpp" diff --git a/solid/solid/backends/udev/udevopticaldisc.h b/solid/solid/backends/udev/udevopticaldisc.h new file mode 100644 index 00000000..d68bd0ec --- /dev/null +++ b/solid/solid/backends/udev/udevopticaldisc.h @@ -0,0 +1,58 @@ +/* + Copyright 2021 Ivailo Monev + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + +#ifndef UDEVOPTICALDISC_H +#define UDEVOPTICALDISC_H + +#include + +#include "../shared/udevqt.h" + +#include "udevstoragevolume.h" +#include "udevdevice.h" + +namespace Solid +{ +namespace Backends +{ +namespace UDev +{ + +class OpticalDisc: public StorageVolume, virtual public Solid::Ifaces::OpticalDisc +{ + Q_OBJECT + Q_INTERFACES(Solid::Ifaces::OpticalDisc) + +public: + OpticalDisc(UDevDevice *device); + virtual ~OpticalDisc(); + + virtual qulonglong capacity() const; + virtual bool isRewritable() const; + virtual bool isBlank() const; + virtual bool isAppendable() const; + virtual Solid::OpticalDisc::DiscType discType() const; + virtual Solid::OpticalDisc::ContentTypes availableContent() const; +}; + +} +} +} +#endif // UDEVOPTICALDISC_H \ No newline at end of file diff --git a/solid/solid/backends/udev/udevopticaldrive.cpp b/solid/solid/backends/udev/udevopticaldrive.cpp new file mode 100644 index 00000000..59331ced --- /dev/null +++ b/solid/solid/backends/udev/udevopticaldrive.cpp @@ -0,0 +1,92 @@ +/* + Copyright 2021 Ivailo Monev + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + +#include "udevopticaldrive.h" + +using namespace Solid::Backends::UDev; + +OpticalDrive::OpticalDrive(UDevDevice *device) + : StorageDrive(device) +{ + m_device->registerAction("eject", this, + SLOT(slotEjectRequested()), + SLOT(slotEjectDone(int,QString))); +} + +OpticalDrive::~OpticalDrive() +{ +} + +bool OpticalDrive::eject() +{ + m_device->broadcastActionRequested("eject"); + +#if 0 + Solid::DeviceBusy + Solid::OperationFailed + Solid::UserCanceled + Solid::InvalidOption + Solid::MissingDriver + Solid::UnauthorizedOperation + + if (true) { + m_device->broadcastActionDone("setup", Solid::NoError, QString()); + } else { + const QString ejecterror; + m_device->broadcastActionDone("eject", Solid::UnauthorizedOperation, ejecterror); + } +#endif + + const QString ejecterror; + m_device->broadcastActionDone("eject", Solid::UnauthorizedOperation, ejecterror); + return false; // TODO: +} + +QList OpticalDrive::writeSpeeds() const +{ + return QList(); // TODO: +} + +int OpticalDrive::writeSpeed() const +{ + return 0; // TODO: +} + +int OpticalDrive::readSpeed() const +{ + return 0; // TODO: +} + +Solid::OpticalDrive::MediumTypes OpticalDrive::supportedMedia() const +{ + return 0; // TODO: +} + +void OpticalDrive::slotEjectRequested() +{ + emit ejectRequested(m_device->udi()); +} + +void OpticalDrive::slotEjectDone(int error, const QString &errorString) +{ + emit ejectDone(static_cast(error), errorString, m_device->udi()); +} + +#include "moc_udevopticaldrive.cpp" diff --git a/solid/solid/backends/udev/udevopticaldrive.h b/solid/solid/backends/udev/udevopticaldrive.h new file mode 100644 index 00000000..4546724d --- /dev/null +++ b/solid/solid/backends/udev/udevopticaldrive.h @@ -0,0 +1,64 @@ +/* + Copyright 2021 Ivailo Monev + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see . +*/ + +#ifndef UDEVOPTICALDRIVE_H +#define UDEVOPTICALDRIVE_H + +#include +#include "udevstoragedrive.h" + +namespace Solid +{ +namespace Backends +{ +namespace UDev +{ + +class OpticalDrive: public StorageDrive, virtual public Solid::Ifaces::OpticalDrive +{ + Q_OBJECT + Q_INTERFACES(Solid::Ifaces::OpticalDrive) + +public: + OpticalDrive(UDevDevice *device); + virtual ~OpticalDrive(); + +Q_SIGNALS: + void ejectPressed(const QString &udi); + void ejectDone(Solid::ErrorType error, QVariant errorData, const QString &udi); + void ejectRequested(const QString &udi); + +public: + virtual bool eject(); + virtual QList writeSpeeds() const; + virtual int writeSpeed() const; + virtual int readSpeed() const; + virtual Solid::OpticalDrive::MediumTypes supportedMedia() const; + +private Q_SLOTS: + void slotEjectRequested(); + void slotEjectDone(int error, const QString &errorString); +}; + +} +} +} + +#endif // UDEVOPTICALDRIVE_H \ No newline at end of file