File indexing completed on 2024-06-16 07:42:25

0001 /*
0002     SPDX-FileCopyrightText: 1998-2009 Sebastian Trueg <trueg@k3b.org>
0003     SPDX-License-Identifier: GPL-2.0-or-later
0004 */
0005 
0006 #ifndef _K3B_DEVICE_HANDLER_H_
0007 #define _K3B_DEVICE_HANDLER_H_
0008 
0009 #include "k3bthreadjob.h"
0010 #include "k3bdevice.h"
0011 #include "k3bdiskinfo.h"
0012 #include "k3bmsf.h"
0013 #include "k3bcdtext.h"
0014 #include "k3b_export.h"
0015 
0016 
0017 namespace K3b {
0018     namespace Device
0019     {
0020         class Device;
0021 
0022         /**
0023          * The Device::Devicehandler is a threaded wrapper around Device::Device.
0024          * It allows async access to the time consuming blocking Device::Device methods.
0025          * Since it's a Job it is very easy to handle. Just use one of the methods and
0026          * connect to the finished signal.
0027          * Be aware that all methods only return valid values if the corresponding info has
0028          * been successfully requested.
0029          *
0030          * Be aware that multiple requests in a row (without waiting for the job to finish) will
0031          * only result in one finished() signal answering the last request.
0032          */
0033         class LIBK3B_EXPORT DeviceHandler : public ThreadJob
0034         {
0035             Q_OBJECT
0036 
0037         public:
0038             enum Command {
0039                 CommandNone = 0x0,
0040 
0041                 /**
0042                  * Retrieve basic disk information.
0043                  * Always successful, even with an empty or no media at all!
0044                  *
0045                  * \sa diskInfo()
0046                  */
0047                 CommandDiskInfo = 0x1,
0048 
0049                 /**
0050                  * Retrieve the Toc.
0051                  * Always successful, even with an empty or no media at all!
0052                  *
0053                  * \sa toc()
0054                  */
0055                 CommandToc = 0x2,
0056 
0057                 /**
0058                  * Retrieve the CD-Text.
0059                  *
0060                  * Successful if the media contains CD-Text.
0061                  *
0062                  * \sa cdText()
0063                  */
0064                 CommandCdText = 0x4,
0065 
0066                 /**
0067                  * Retrieve the raw, undecoded CD-Text.
0068                  *
0069                  * Successful if the media contains CD-Text.
0070                  *
0071                  * \sa rawCdText()
0072                  */
0073                 CommandCdTextRaw = 0x8,
0074 
0075                 /**
0076                  * Retrieve the size of the disk.
0077                  *
0078                  * Always successful, even with an empty or no media at all!
0079                  *
0080                  * \sa diskSize()
0081                  */
0082                 CommandDiskSize = 0x10,
0083 
0084                 /**
0085                  * Retrieve the remaining size of the disk.
0086                  *
0087                  * Always successful, even with an empty or no media at all!
0088                  *
0089                  * \sa remainingSize()
0090                  */
0091                 CommandRemainingSize = 0x20,
0092 
0093                 /**
0094                  * Always successful, even with an empty or no media at all!
0095                  */
0096                 CommandTocType = 0x40,
0097 
0098                 /**
0099                  * Always successful, even with an empty or no media at all!
0100                  */
0101                 CommandNumSessions = 0x80,
0102 
0103                 /**
0104                  * Successful if the drive could be blocked.
0105                  */
0106                 CommandBlock = 0x100,
0107 
0108                 /**
0109                  * Successful if the drive could be unblocked.
0110                  */
0111                 CommandUnblock = 0x200,
0112 
0113                 /**
0114                  * Successful if the media was ejected.
0115                  */
0116                 CommandEject = 0x400,
0117 
0118                 /**
0119                  * Successful if the media was loaded
0120                  */
0121                 CommandLoad = 0x800,
0122 
0123                 CommandReload = CommandEject|CommandLoad,
0124 
0125                 /**
0126                  * Determine the device buffer state.
0127                  */
0128                 CommandBufferCapacity = 0x1000,
0129 
0130                 CommandNextWritableAddress = 0x2000,
0131 
0132                 /**
0133                  * Retrieves all medium information: CommandDiskInfo, CommandToc, and CommandCdText in case of an audio or mixed
0134                  * mode cd.
0135                  *
0136                  * Always successful, even with an empty or no media at all!
0137                  *
0138                  * \sa diskInfo(), toc(), cdText()
0139                  */
0140                 CommandMediaInfo = CommandDiskInfo|CommandToc|CommandCdText
0141             };
0142             Q_DECLARE_FLAGS( Commands, Command )
0143 
0144             DeviceHandler( Device*, QObject* parent = 0 );
0145             DeviceHandler( QObject* parent = 0 );
0146 
0147             /**
0148              * This constructor is used by the global "quick" methods and should not be used
0149              * otherwise except for the same usage.
0150              */
0151             DeviceHandler( Commands command, Device* );
0152 
0153             ~DeviceHandler() override;
0154 
0155             DiskInfo diskInfo() const;
0156             Toc toc() const;
0157             CdText cdText() const;
0158             QByteArray cdTextRaw() const;
0159             Msf diskSize() const;
0160             Msf remainingSize() const;
0161             int tocType() const;
0162             int numSessions() const;
0163             long long bufferCapacity() const;
0164             long long availableBufferCapacity() const;
0165 
0166             Msf nextWritableAddress() const;
0167 
0168             bool success() const;
0169 
0170         Q_SIGNALS:
0171             void finished( K3b::Device::DeviceHandler* );
0172 
0173         public Q_SLOTS:
0174             void setDevice( K3b::Device::Device* );
0175             void sendCommand( Commands command );
0176 
0177             void getToc();
0178             void getDiskInfo();
0179             void getDiskSize();
0180             void getRemainingSize();
0181             void getTocType();
0182             void getNumSessions();
0183             void block( bool );
0184             void eject();
0185 
0186         private:
0187             void jobFinished( bool success ) override;
0188             bool run() override;
0189 
0190             class Private;
0191             Private* const d;
0192         };
0193 
0194         /**
0195          * Usage:
0196          * \code
0197          *  connect( Device::sendCommand( Device::DeviceHandler::CommandDiskInfo, dev ),
0198          *           SIGNAL(finished(DeviceHandler*)),
0199          *           this, SLOT(someSlot(DeviceHandler*)) );
0200          *
0201          *  void someSlot( DeviceHandler* dh ) {
0202          *     if( dh->success() ) {
0203          * \endcode
0204          *
0205          * Be aware that the DeviceHandler will get destroyed once the signal has been
0206          * emitted.
0207          */
0208         LIBK3B_EXPORT DeviceHandler* sendCommand( DeviceHandler::Commands command, Device* );
0209 
0210         inline DeviceHandler* mediaInfo(Device* dev) {
0211             return sendCommand(DeviceHandler::CommandMediaInfo,dev);
0212         }
0213 
0214         inline DeviceHandler* toc(Device* dev) {
0215             return sendCommand(DeviceHandler::CommandToc,dev);
0216         }
0217 
0218         inline DeviceHandler* diskSize(Device* dev) {
0219             return sendCommand(DeviceHandler::CommandDiskSize,dev);
0220         }
0221 
0222         inline DeviceHandler* remainingSize(Device* dev) {
0223             return sendCommand(DeviceHandler::CommandRemainingSize,dev);
0224         }
0225 
0226         inline DeviceHandler* tocType(Device* dev) {
0227             return sendCommand(DeviceHandler::CommandTocType,dev);
0228         }
0229 
0230         inline DeviceHandler* numSessions(Device* dev) {
0231             return sendCommand(DeviceHandler::CommandNumSessions,dev);
0232         }
0233 
0234         inline DeviceHandler* block(Device* dev) {
0235             return sendCommand(DeviceHandler::CommandBlock,dev);
0236         }
0237 
0238         inline DeviceHandler* unblock(Device* dev) {
0239             return sendCommand(DeviceHandler::CommandUnblock,dev);
0240         }
0241 
0242         inline DeviceHandler* eject(Device* dev) {
0243             return sendCommand(DeviceHandler::CommandEject,dev);
0244         }
0245 
0246         inline DeviceHandler* reload(Device* dev) {
0247             return sendCommand(DeviceHandler::CommandReload,dev);
0248         }
0249 
0250         inline DeviceHandler* load(Device* dev) {
0251             return sendCommand(DeviceHandler::CommandLoad,dev);
0252         }
0253     }
0254 }
0255 
0256 Q_DECLARE_OPERATORS_FOR_FLAGS(K3b::Device::DeviceHandler::Commands)
0257 
0258 LIBK3B_EXPORT QDebug operator<<( QDebug dbg, K3b::Device::DeviceHandler::Commands commands );
0259 
0260 #endif