summaryrefslogtreecommitdiffstats
path: root/kioslave/media/mediamanager/linuxcdpolling.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'kioslave/media/mediamanager/linuxcdpolling.cpp')
-rw-r--r--kioslave/media/mediamanager/linuxcdpolling.cpp585
1 files changed, 0 insertions, 585 deletions
diff --git a/kioslave/media/mediamanager/linuxcdpolling.cpp b/kioslave/media/mediamanager/linuxcdpolling.cpp
deleted file mode 100644
index 0fcda8d0f..000000000
--- a/kioslave/media/mediamanager/linuxcdpolling.cpp
+++ /dev/null
@@ -1,585 +0,0 @@
-/* This file is part of the KDE Project
- Copyright (c) 2003 Gav Wood <gav kde org>
- Copyright (c) 2004 Kévin Ottens <ervin ipsquad net>
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License version 2 as published by the Free Software Foundation.
-
- 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
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public License
- along with this library; see the file COPYING.LIB. If not, write to
- the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- Boston, MA 02110-1301, USA.
-*/
-
-/* Some code of this file comes from kdeautorun */
-
-#include "linuxcdpolling.h"
-
-#include <tqthread.h>
-#include <tqmutex.h>
-#include <tqfile.h>
-
-#include <kdebug.h>
-
-#include "fstabbackend.h"
-
-#include <sys/ioctl.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <stdlib.h>
-#include <unistd.h>
-
-// Never ever include directly a kernel header!
-// #include <linux/cdrom.h>
-// Instead we redefine the necessary (copied from the header)
-
-/* This struct is used by the CDROMREADTOCHDR ioctl */
-struct cdrom_tochdr
-{
- unsigned char cdth_trk0; /* start track */
- unsigned char cdth_trk1; /* end track */
-};
-
-#define CDROMREADTOCHDR 0x5305 /* Read TOC header
- (struct cdrom_tochdr) */
-#define CDROM_DRIVE_STATUS 0x5326 /* Get tray position, etc. */
-#define CDROM_DISC_STATUS 0x5327 /* Get disc type, etc. */
-
-/* drive status possibilities returned by CDROM_DRIVE_STATUS ioctl */
-#define CDS_NO_INFO 0 /* if not implemented */
-#define CDS_NO_DISC 1
-#define CDS_TRAY_OPEN 2
-#define CDS_DRIVE_NOT_READY 3
-#define CDS_DISC_OK 4
-
-/* return values for the CDROM_DISC_STATUS ioctl */
-/* can also return CDS_NO_[INFO|DISC], from above */
-#define CDS_AUDIO 100
-#define CDS_DATA_1 101
-#define CDS_DATA_2 102
-#define CDS_XA_2_1 103
-#define CDS_XA_2_2 104
-#define CDS_MIXED 105
-
-#define CDSL_CURRENT ((int) (~0U>>1))
-
-// -------
-
-
-
-DiscType::DiscType(Type type)
- : m_type(type)
-{
-}
-
-bool DiscType::isKnownDisc() const
-{
- return m_type != None
- && m_type != Unknown
- && m_type != UnknownType
- && m_type != Broken;
-}
-
-bool DiscType::isDisc() const
-{
- return m_type != None
- && m_type != Unknown
- && m_type != Broken;
-}
-
-bool DiscType::isNotDisc() const
-{
- return m_type == None;
-}
-
-bool DiscType::isData() const
-{
- return m_type == Data;
-}
-
-DiscType::operator int() const
-{
- return (int)m_type;
-}
-
-
-class PollingThread : public TQThread
-{
-public:
- PollingThread(const TQCString &devNode) : m_dev(devNode)
- {
- kdDebug(1219) << "PollingThread::PollingThread("
- << devNode << ")" << endl;
- m_stop = false;
- m_currentType = DiscType::None;
- m_lastPollType = DiscType::None;
- }
-
-
- void stop()
- {
- TQMutexLocker locker(&m_mutex);
- m_stop = true;
- }
-
- bool hasChanged()
- {
- TQMutexLocker locker(&m_mutex);
-
- return m_currentType!=m_lastPollType;
- }
-
- DiscType type()
- {
- TQMutexLocker locker(&m_mutex);
- m_currentType = m_lastPollType;
- return m_currentType;
- }
-
-protected:
- virtual void run()
- {
- kdDebug(1219) << "PollingThread(" << m_dev << ") start" << endl;
- while (!m_stop && m_lastPollType!=DiscType::Broken)
- {
- m_mutex.lock();
- DiscType type = m_lastPollType;
- m_mutex.unlock();
-
- type = LinuxCDPolling::identifyDiscType(m_dev, type);
-
- m_mutex.lock();
- m_lastPollType = type;
- m_mutex.unlock();
-
- msleep(500);
- }
- kdDebug(1219) << "PollingThread(" << m_dev << ") stop" << endl;
- }
-
-private:
- TQMutex m_mutex;
- bool m_stop;
- const TQCString m_dev;
- DiscType m_currentType;
- DiscType m_lastPollType;
-};
-
-
-LinuxCDPolling::LinuxCDPolling(MediaList &list)
- : TQObject(), BackendBase(list)
-{
- connect(&m_mediaList, TQT_SIGNAL(mediumAdded(const TQString &,
- const TQString &, bool)),
- this, TQT_SLOT(slotMediumAdded(const TQString &)) );
-
- connect(&m_mediaList, TQT_SIGNAL(mediumRemoved(const TQString &,
- const TQString &, bool)),
- this, TQT_SLOT(slotMediumRemoved(const TQString &)) );
-
- connect(&m_mediaList, TQT_SIGNAL(mediumStateChanged(const TQString &,
- const TQString &, bool, bool)),
- this, TQT_SLOT(slotMediumStateChanged(const TQString &)) );
-
- connect(&m_timer, TQT_SIGNAL(timeout()), this, TQT_SLOT(slotTimeout()));
-}
-
-LinuxCDPolling::~LinuxCDPolling()
-{
- TQMap<TQString, PollingThread*>::iterator it = m_threads.begin();
- TQMap<TQString, PollingThread*>::iterator end = m_threads.end();
-
- for(; it!=end; ++it)
- {
- PollingThread *thread = it.data();
- thread->stop();
- thread->wait();
- delete thread;
- }
-}
-
-void LinuxCDPolling::slotMediumAdded(const TQString &id)
-{
- kdDebug(1219) << "LinuxCDPolling::slotMediumAdded(" << id << ")" << endl;
-
- if (m_threads.contains(id)) return;
-
- const Medium *medium = m_mediaList.findById(id);
-
- TQString mime = medium->mimeType();
- kdDebug(1219) << "mime == " << mime << endl;
-
- if (mime.find("dvd")==-1 && mime.find("cd")==-1) return;
-
- if (!medium->isMounted())
- {
- m_excludeNotification.append( id );
-
- TQCString dev = TQFile::encodeName( medium->deviceNode() ).data();
- PollingThread *thread = new PollingThread(dev);
- m_threads[id] = thread;
- thread->start();
- m_timer.start(500);
- }
-}
-
-void LinuxCDPolling::slotMediumRemoved(const TQString &id)
-{
- kdDebug(1219) << "LinuxCDPolling::slotMediumRemoved(" << id << ")" << endl;
-
- if (!m_threads.contains(id)) return;
-
- PollingThread *thread = m_threads[id];
- m_threads.remove(id);
- thread->stop();
- thread->wait();
- delete thread;
-
- m_excludeNotification.remove(id);
-}
-
-void LinuxCDPolling::slotMediumStateChanged(const TQString &id)
-{
- kdDebug(1219) << "LinuxCDPolling::slotMediumStateChanged("
- << id << ")" << endl;
-
- const Medium *medium = m_mediaList.findById(id);
-
- TQString mime = medium->mimeType();
- kdDebug(1219) << "mime == " << mime << endl;
-
- if (mime.find("dvd")==-1 && mime.find("cd")==-1) return;
-
- if (!m_threads.contains(id) && !medium->isMounted())
- {
- // It is just a mount state change, no need to notify
- m_excludeNotification.append( id );
-
- TQCString dev = TQFile::encodeName( medium->deviceNode() ).data();
- PollingThread *thread = new PollingThread(dev);
- m_threads[id] = thread;
- thread->start();
- m_timer.start(500);
- }
- else if (m_threads.contains(id) && medium->isMounted())
- {
- PollingThread *thread = m_threads[id];
- m_threads.remove(id);
- thread->stop();
- thread->wait();
- delete thread;
- }
-}
-
-void LinuxCDPolling::slotTimeout()
-{
- //kdDebug(1219) << "LinuxCDPolling::slotTimeout()" << endl;
-
- if (m_threads.isEmpty())
- {
- m_timer.stop();
- return;
- }
-
- TQMap<TQString, PollingThread*>::iterator it = m_threads.begin();
- TQMap<TQString, PollingThread*>::iterator end = m_threads.end();
-
- for(; it!=end; ++it)
- {
- TQString id = it.key();
- PollingThread *thread = it.data();
-
- if (thread->hasChanged())
- {
- DiscType type = thread->type();
- const Medium *medium = m_mediaList.findById(id);
- applyType(type, medium);
- }
- }
-}
-
-static TQString baseType(const Medium *medium)
-{
- kdDebug(1219) << "baseType(" << medium->id() << ")" << endl;
-
- TQString devNode = medium->deviceNode();
- TQString mountPoint = medium->mountPoint();
- TQString fsType = medium->fsType();
- bool mounted = medium->isMounted();
-
- TQString mimeType, iconName, label;
-
- FstabBackend::guess(devNode, mountPoint, fsType, mounted,
- mimeType, iconName, label);
-
- if (devNode.find("dvd")!=-1)
- {
- kdDebug(1219) << "=> dvd" << endl;
- return "dvd";
- }
- else
- {
- kdDebug(1219) << "=> cd" << endl;
- return "cd";
- }
-}
-
-static void restoreEmptyState(MediaList &list, const Medium *medium,
- bool allowNotification)
-{
- kdDebug(1219) << "restoreEmptyState(" << medium->id() << ")" << endl;
-
- TQString id = medium->id();
- TQString devNode = medium->deviceNode();
- TQString mountPoint = medium->mountPoint();
- TQString fsType = medium->fsType();
- bool mounted = medium->isMounted();
-
- TQString mimeType, iconName, label;
-
- FstabBackend::guess(devNode, mountPoint, fsType, mounted,
- mimeType, iconName, label);
-
- list.changeMediumState(id, devNode, mountPoint, fsType, mounted,
- allowNotification, mimeType, iconName, label);
-}
-
-
-void LinuxCDPolling::applyType(DiscType type, const Medium *medium)
-{
- kdDebug(1219) << "LinuxCDPolling::applyType(" << type << ", "
- << medium->id() << ")" << endl;
-
- TQString id = medium->id();
- TQString dev = medium->deviceNode();
-
- bool notify = !m_excludeNotification.contains(id);
- m_excludeNotification.remove(id);
-
- switch (type)
- {
- case DiscType::Data:
- restoreEmptyState(m_mediaList, medium, notify);
- break;
- case DiscType::Audio:
- case DiscType::Mixed:
- m_mediaList.changeMediumState(id, "audiocd:/?device="+dev,
- notify, "media/audiocd");
- break;
- case DiscType::VCD:
- m_mediaList.changeMediumState(id, false, notify, "media/vcd");
- break;
- case DiscType::SVCD:
- m_mediaList.changeMediumState(id, false, notify, "media/svcd");
- break;
- case DiscType::DVD:
- m_mediaList.changeMediumState(id, false, notify, "media/dvdvideo");
- break;
- case DiscType::Blank:
- if (baseType(medium)=="dvd")
- {
- m_mediaList.changeMediumState(id, false,
- notify, "media/blankdvd");
- }
- else
- {
- m_mediaList.changeMediumState(id, false,
- notify, "media/blankcd");
- }
- break;
- case DiscType::None:
- case DiscType::Unknown:
- case DiscType::UnknownType:
- restoreEmptyState(m_mediaList, medium, false);
- break;
- }
-}
-
-DiscType LinuxCDPolling::identifyDiscType(const TQCString &devNode,
- const DiscType &current)
-{
- //kdDebug(1219) << "LinuxCDPolling::identifyDiscType("
- // << devNode << ")" << endl;
-
- int fd;
- struct cdrom_tochdr th;
-
- // open the device
- fd = open(devNode, O_RDONLY | O_NONBLOCK);
- if (fd < 0) return DiscType::Broken;
-
- switch (ioctl(fd, CDROM_DRIVE_STATUS, CDSL_CURRENT))
- {
- case CDS_DISC_OK:
- {
- if (current.isDisc())
- {
- close(fd);
- return current;
- }
-
- // see if we can read the disc's table of contents (TOC).
- if (ioctl(fd, CDROMREADTOCHDR, &th))
- {
- close(fd);
- return DiscType::Blank;
- }
-
- // read disc status info
- int status = ioctl(fd, CDROM_DISC_STATUS, CDSL_CURRENT);
-
- // release the device
- close(fd);
-
- switch (status)
- {
- case CDS_AUDIO:
- return DiscType::Audio;
- case CDS_DATA_1:
- case CDS_DATA_2:
- if (hasDirectory(devNode, "video_ts"))
- {
- return DiscType::DVD;
- }
- else if (hasDirectory(devNode, "vcd"))
- {
- return DiscType::VCD;
- }
- else if (hasDirectory(devNode, "svcd"))
- {
- return DiscType::SVCD;
- }
- else
- {
- return DiscType::Data;
- }
- case CDS_MIXED:
- return DiscType::Mixed;
- default:
- return DiscType::UnknownType;
- }
- }
- case CDS_NO_INFO:
- close(fd);
- return DiscType::Unknown;
- default:
- close(fd);
- return DiscType::None;
- }
-}
-
-bool LinuxCDPolling::hasDirectory(const TQCString &devNode, const TQCString &dir)
-{
- bool ret = false; // return value
- int fd = 0; // file descriptor for drive
- unsigned short bs; // the discs block size
- unsigned short ts; // the path table size
- unsigned int tl; // the path table location (in blocks)
- unsigned char len_di = 0; // length of the directory name in current path table entry
- unsigned int parent = 0; // the number of the parent directory's path table entry
- char dirname[256]; // filename for the current path table entry
- int pos = 0; // our position into the path table
- int curr_record = 1; // the path table record we're on
- TQCString fixed_directory = dir.upper(); // the uppercase version of the "directory" parameter
-
- // open the drive
- fd = open(devNode, O_RDONLY | O_NONBLOCK);
- if (fd == -1) return false;
-
- // read the block size
- lseek(fd, 0x8080, SEEK_CUR);
- if (read(fd, &bs, 2) != 2)
- {
- close(fd);
- return false;
- }
- if (Q_BYTE_ORDER != Q_LITTLE_ENDIAN)
- bs = ((bs << 8) & 0xFF00) | ((bs >> 8) & 0xFF);
-
- // read in size of path table
- lseek(fd, 2, SEEK_CUR);
- if (read(fd, &ts, 2) != 2)
- {
- close(fd);
- return false;
- }
- if (Q_BYTE_ORDER != Q_LITTLE_ENDIAN)
- ts = ((ts << 8) & 0xFF00) | ((ts >> 8) & 0xFF);
-
- // read in which block path table is in
- lseek(fd, 6, SEEK_CUR);
- if (read(fd, &tl, 4) != 4)
- {
- close(fd);
- return false;
- }
- if (Q_BYTE_ORDER != Q_LITTLE_ENDIAN)
- tl = ((tl << 24) & 0xFF000000) | ((tl << 8) & 0xFF0000) |
- ((tl >> 8) & 0xFF00) | ((tl >> 24) & 0xFF);
-
- // seek to the path table
- lseek(fd, bs * tl, SEEK_SET);
-
- // loop through the path table entries
- while (pos < ts)
- {
- // get the length of the filename of the current entry
- if (read(fd, &len_di, 1) != 1)
- {
- ret = false;
- break;
- }
-
- // get the record number of this entry's parent
- // i'm pretty sure that the 1st entry is always the top directory
- lseek(fd, 5, SEEK_CUR);
- if (read(fd, &parent, 2) != 2)
- {
- ret = false;
- break;
- }
- if (Q_BYTE_ORDER != Q_LITTLE_ENDIAN)
- parent = ((parent << 8) & 0xFF00) | ((parent >> 8) & 0xFF);
-
- // read the name
- if (read(fd, dirname, len_di) != len_di)
- {
- ret = false;
- break;
- }
- dirname[len_di] = 0;
- qstrcpy(dirname, TQCString(dirname).upper());
-
- // if we found a folder that has the root as a parent, and the directory name matches
- // then return success
- if ((parent == 1) && (dirname == fixed_directory))
- {
- ret = true;
- break;
- }
-
- // all path table entries are padded to be even, so if this is an odd-length table, seek a byte to fix it
- if (len_di%2 == 1)
- {
- lseek(fd, 1, SEEK_CUR);
- pos++;
- }
-
- // update our position
- pos += 8 + len_di;
- curr_record++;
- }
-
- close(fd);
- return ret;
-}
-
-
-#include "linuxcdpolling.moc"