diff options
Diffstat (limited to 'k9devices')
-rw-r--r-- | k9devices/Makefile.am | 10 | ||||
-rw-r--r-- | k9devices/configure.in.in | 134 | ||||
-rw-r--r-- | k9devices/k9cddrive.cpp | 199 | ||||
-rw-r--r-- | k9devices/k9cddrive.h | 87 | ||||
-rw-r--r-- | k9devices/k9dbusdispatch.cpp | 231 | ||||
-rw-r--r-- | k9devices/k9dbusdispatch.h | 66 | ||||
-rw-r--r-- | k9devices/k9halconnection.cpp | 159 | ||||
-rw-r--r-- | k9devices/k9halconnection.h | 66 | ||||
-rw-r--r-- | k9devices/k9haldevice.cpp | 112 | ||||
-rw-r--r-- | k9devices/k9haldevice.h | 86 |
10 files changed, 1150 insertions, 0 deletions
diff --git a/k9devices/Makefile.am b/k9devices/Makefile.am new file mode 100644 index 0000000..c939086 --- /dev/null +++ b/k9devices/Makefile.am @@ -0,0 +1,10 @@ +INCLUDES = -I$(top_srcdir)/dvdread -I$(top_srcdir)/libk9copy $(DBUS_INCS) \ + $(HAL_INCS) $(K3B_INCS) $(all_includes) +METASOURCES = AUTO +libk9devices_la_LDFLAGS = $(all_libraries) +noinst_LTLIBRARIES = libk9devices.la +noinst_HEADERS = k9halconnection.h k9haldevice.h k9cddrive.h k9dbusdispatch.h +libk9devices_la_SOURCES = k9halconnection.cpp k9haldevice.cpp k9cddrive.cpp \ + k9dbusdispatch.cpp + +libk9devices_la_LIBADD = $(K3B_LIBS) $(HAL_DBUS_LIBS) diff --git a/k9devices/configure.in.in b/k9devices/configure.in.in new file mode 100644 index 0000000..b4092e6 --- /dev/null +++ b/k9devices/configure.in.in @@ -0,0 +1,134 @@ + have_hal=no + AC_MSG_CHECKING(for the HAL) + + AC_ARG_ENABLE([k3bdevices], + AC_HELP_STRING([--enable-k3bdevices], + [do not activate hal/dbus support (use k3bdevice instead)]), + [enable_hal=no], + [enable_hal=yes]) + + + if test x"$enable_hal" = xyes; then + hal_inc=NOTFOUND + hal_lib=NOTFOUND + hal=NOTFOUND + + search_incs="$kde_includes /usr/include /usr/include/hal /usr/local/include /usr/local/include/hal" + AC_FIND_FILE(libhal.h libhal-storage.h, $search_incs, hal_incdir) + + if [test -r $hal_incdir/libhal.h] ; then + HAL_INCS="-I$hal_incdir" + hal_inc=FOUND + fi + + if test -r $hal_incdir/libhal-storage.h ; then + hal_storage_version=4 + grep LibHalVolume $hal_incdir/libhal-storage.h \ + > /dev/null 2>&1 && hal_storage_version=5 + if test $hal_storage_version = 4 ; then + AC_DEFINE(HAL_0_4, , [HAL API version 0.4]) + fi + fi + + search_libs="$kde_libraries /usr/lib64 /usr/lib /usr/local/lib /lib /lib64" + AC_FIND_FILE(libhal.so, $search_libs, hal_libdir) + + if [test -r $hal_libdir/libhal.so] ; then + HAL_LIBS="-L$hal_libdir -lhal" + hal_lib=FOUND + fi + + if [test -r $hal_libdir/libhal-storage.so] ; then + HAL_LIBS_STORAGE="-L$hal_libdir -lhal-storage" + hal_lib_storage=FOUND + fi + + if [test $hal_inc = FOUND] && [test $hal_lib = FOUND] ; then + AC_MSG_RESULT(headers $hal_incdir libraries $hal_libdir) + hal=FOUND + else + AC_MSG_RESULT(searched but not found) + AC_MSG_ERROR(libhal may be missing) + fi + + AC_SUBST(HAL_INCS) + AC_SUBST(HAL_LIBS) + + + ########### Check for DBus + + AC_MSG_CHECKING(for DBus) + + dbus_inc=NOTFOUND + dbus_lib=NOTFOUND + dbus=NOTFOUND + + search_incs="$kde_includes /usr/include /usr/include/dbus-1.0 /usr/local/include /usr/local/include/dbus-1.0" + AC_FIND_FILE(dbus/dbus.h, $search_incs, dbus_incdir) + + search_incs_arch_deps="$kde_includes /usr/lib64/dbus-1.0/include /usr/lib/dbus-1.0/include /usr/local/lib/dbus-1.0/include" + AC_FIND_FILE(dbus/dbus-arch-deps.h, $search_incs_arch_deps, dbus_incdir_arch_deps) + + if [test -r $dbus_incdir/dbus/dbus.h] && [test -r $dbus_incdir_arch_deps/dbus/dbus-arch-deps.h] ; then + DBUS_INCS="-I$dbus_incdir -I$dbus_incdir_arch_deps" + dbus_inc=FOUND + fi + + search_libs="$kde_libraries /usr/lib64 /usr/lib /usr/local/lib /lib /lib64" + AC_FIND_FILE(libdbus-1.so, $search_libs, dbus_libdir) + + if test -r $dbus_libdir/libdbus-1.so ; then + DBUS_LIBS="-L$dbus_libdir -ldbus-1" + dbus_lib=FOUND + fi + + if [test $dbus_inc = FOUND] && [test $dbus_lib = FOUND] ; then + AC_MSG_RESULT(headers $dbus_incdir $dbus_incdir_arch_deps libraries $dbus_libdir) + dbus=FOUND + else + AC_MSG_RESULT(searched but not found) + AC_MSG_ERROR(dbus may be missing) + fi + + AC_SUBST(DBUS_INCS) + AC_SUBST(DBUS_LIBS) + + + ########### Check if media HAL backend should be compiled + + HAL_DBUS_LIBS="" + if [test "x$hal" = "xFOUND"] && [test "x$dbus" = "xFOUND"] && [ test $hal_storage_version = 5 ] ; then + AC_DEFINE(HAVE_HAL, , [compile in HAL support]) + have_hal=yes + HAL_DBUS_LIBS="$HAL_LIBS $HAL_LIBS_STORAGE $DBUS_LIBS" + fi + + AC_SUBST(HAL_DBUS_LIBS) +else + search_incs="$kde_includes /usr/include /usr/local/include" + AC_FIND_FILE(k3bdevice.h, $search_incs, k3b_incdir) + + if [test -r $k3b_incdir/k3bdevice.h] ; then + k3b_inc=FOUND + fi + + search_libs="$kde_libraries /usr/lib64 /usr/lib /usr/local/lib /lib /lib64" + AC_FIND_FILE(libk3bdevice.so, $search_libs, k3b_libdir) + + if [test -r $k3b_libdir/libk3bdevice.so] ; then + K3B_LIBS="-lk3bdevice" + k3b_lib=FOUND + fi + + if [test $k3b_inc = FOUND] && [test $k3b_lib = FOUND] ; then + AC_MSG_RESULT(headers $k3b_incdir libraries $k3b_libdir) + k3b=FOUND + else + AC_MSG_RESULT(libk3bdevice searched but not found) + AC_MSG_ERROR(libk3bdevice may be missing) + fi + + AC_SUBST(K3B_LIBS) + +fi + diff --git a/k9devices/k9cddrive.cpp b/k9devices/k9cddrive.cpp new file mode 100644 index 0000000..0a47b70 --- /dev/null +++ b/k9devices/k9cddrive.cpp @@ -0,0 +1,199 @@ +// +// C++ Implementation: k9cddrive +// +// Description: +// +// +// Author: Jean-Michel PETIT <k9copy@free.fr>, (C) 2007 +// +// Copyright: See COPYING file that comes with this distribution +// +// +#include "k9common.h" +#include "k9cddrive.h" +#include "k9config.h" +#include "k9tools.h" + +#ifdef HAVE_HAL +#include "k9halconnection.h" +#include "k9haldevice.h" +#else +#include <k3bdevice.h> +#include <k3bdevicemanager.h> +#endif + +#include <kprocess.h> +k9CdDrive::k9CdDrive() { + canReadDVD=false; + canWriteCDR=false; + canWriteDVD=false; + device=""; + name=""; + #ifdef HAVE_HAL + m_Device=NULL; + #endif +} +k9CdDrive::~k9CdDrive() {} + +k9CdDrives::k9CdDrives():QObject( 0,0) { + drives.setAutoDelete(true); + #ifdef HAVE_HAL + m_connection=k9HalConnection::getInstance(); + connect(m_connection,SIGNAL(deviceAdded( k9HalDevice* )),this,SLOT(deviceAdded( k9HalDevice* ))); + connect(m_connection,SIGNAL(deviceRemoved( k9HalDevice* )),this,SLOT(deviceRemoved( k9HalDevice*))); + #else + m_devMgr=new K3bDevice::DeviceManager(this); + + #endif + scanDrives(); +} +k9CdDrives::~k9CdDrives() { + #ifdef HAVE_HAL + m_connection->end(); + #else + delete m_devMgr; + #endif +} + +void k9CdDrives::deviceAdded( k9HalDevice *_device) { +#ifdef HAVE_HAL + addDrive( _device); +#endif +} + +void k9CdDrives::deviceRemoved(k9HalDevice *_device) { +#ifdef HAVE_HAL + for (k9CdDrive *d=drives.first();d;d=drives.next()) { + if (d->getDevice()==_device) { + emit deviceRemoved( d); + drives.remove(d); + break; + } + } +#endif +} +#ifdef HAVE_HAL +void k9CdDrives::addDrive(k9HalDevice *_device) { + k9CdDrive *drive=new k9CdDrive; + drive->setDevice( _device); + drive->canReadDVD=_device->getCanReadDvd(); + drive->canWriteDVD=_device->getCanBurnDvd(); + drive->canWriteCDR=_device->getCanBurnCd(); + drive->device=_device->getDeviceName(); + drive->name=_device->getModel(); + QValueList <int> writeSpeeds; + for (int i=2;i <=_device->getMaxWriteSpeed()/1385;i+=2) + writeSpeeds.append( i); + drive->setWriteSpeeds(writeSpeeds); + drives.append(drive); + emit deviceAdded( drive); + +} +#endif + +/** No descriptions */ +void k9CdDrives::scanDrives() { + drives.clear(); + + #ifdef HAVE_HAL + QPtrList <k9HalDevice> list=m_connection->getDevices(); + + for (k9HalDevice *hdrive=list.first();hdrive;hdrive=list.next()) { + addDrive(hdrive); + } + #else + m_devMgr->scanBus(); + int row=0; + QPtrList <K3bDevice::Device> lDev=m_devMgr->allDevices(); + for (K3bDevice::Device *dev=lDev.first();dev;dev=lDev.next()) { + k9CdDrive *drive=new k9CdDrive; + drive->device=dev->blockDeviceName(); + drive->name=dev->description(); + drive->canReadDVD=dev->readsDvd(); + drive->canWriteCDR=dev->writesCd(); + drive->canWriteDVD=dev->writesDvd(); + QValueList <int> writeSpeeds; + for (int i=2;i <=dev->determineMaximalWriteSpeed()/1385;i+=2) + writeSpeeds.append( i); + drive->setWriteSpeeds(writeSpeeds); + + drive->num=row; + drives.append(drive); + row++; + emit deviceAdded(drive); + } + + #endif + readConfig(); +} + +void k9CdDrives::eject(const QString & device) { + KProcess *process =new KProcess(); + if (k9Tools::checkProgram("kdeeject")) + *process <<"kdeeject" << device; + else + *process <<"eject" << device; + process->start(); + process->wait(); + delete process; +} + + +/** reads devices that was entered manually **/ +void k9CdDrives::readConfig() { + QStringList ldev; + QStringList llabels; + QStringList lIO; + k9Config config; + ldev=config.getDevices(); + llabels=config.getDevicesLabels(); + lIO=config.getDevicesIO(); + int row=count(); + int i=0; + for ( QStringList::Iterator it = ldev.begin(); it != ldev.end(); ++it ) { + k9CdDrive *drive=new k9CdDrive; + drive->device=(*it); + QStringList::Iterator it2=llabels.at(i); + QStringList::Iterator it3=lIO.at(i); + drive->name=(*it2); + QString c=(*it3); + if (c.contains("I")) { + drive->canReadDVD=true; + } + if (c.contains("O")) { + drive->canWriteCDR=true; + drive->canWriteDVD=true; + } + drive->num=row; + drives.append(drive); + row++; + i++; + emit deviceAdded(drive); + } +} + + + +/** No descriptions */ +int k9CdDrives::count() { + return drives.count(); +} + +/** No descriptions */ +k9CdDrive * k9CdDrives::getDrive(int num) { + return (k9CdDrive *)drives.at(num); +} + + +QValueList< int > k9CdDrive::getWriteSpeeds() const { + return writeSpeeds; +} + + +void k9CdDrive::setWriteSpeeds(const QValueList< int >& _value) { + writeSpeeds = _value; +} + + + +#include "k9cddrive.moc" diff --git a/k9devices/k9cddrive.h b/k9devices/k9cddrive.h new file mode 100644 index 0000000..e64bc0f --- /dev/null +++ b/k9devices/k9cddrive.h @@ -0,0 +1,87 @@ +// +// C++ Interface: k9cddrive +// +// Description: +// +// +// Author: Jean-Michel PETIT <k9copy@free.fr>, (C) 2007 +// +// Copyright: See COPYING file that comes with this distribution +// +// +#ifndef K9CDDRIVE_H +#define K9CDDRIVE_H +#include "k9common.h" + +#include <qobject.h> + +#include <qstring.h> +#include <qstringlist.h> +#include <qvaluelist.h> +#ifndef HAVE_HAL +#include <k3bdevice.h> +#include <k3bdevicemanager.h> +#endif + + +/** + *@author + */ +class k9HalDevice; +class k9HalConnection; + +class k9CdDrive : public QObject { + Q_OBJECT +public: + k9CdDrive(); + ~k9CdDrive(); + int num; + QString name; + QString device; + bool canWriteCDR; + bool canReadDVD; + bool canWriteDVD; + + void setWriteSpeeds(const QValueList< int >& _value); + QValueList< int > getWriteSpeeds() const; + + #ifdef HAVE_HAL + void setDevice(k9HalDevice* _value) { m_Device = _value;} + + k9HalDevice* getDevice() { return m_Device;} + #endif +private: + QValueList <int> writeSpeeds; + #ifdef HAVE_HAL + k9HalDevice *m_Device; + #endif +}; + +class k9CdDrives : public QObject { + Q_OBJECT +public: + k9CdDrives(); + ~k9CdDrives(); + /** No descriptions */ + int count(); + /** No descriptions */ + k9CdDrive * getDrive(int num); + void eject(const QString & device); + void scanDrives(); +public slots: + void deviceAdded(k9HalDevice *device); + void deviceRemoved(k9HalDevice *device); +signals: + void deviceAdded(k9CdDrive *drive); + void deviceRemoved(k9CdDrive *drive); +private: // Private methods + #ifdef HAVE_HAL + k9HalConnection *m_connection; + void addDrive(k9HalDevice *_device); + #else + K3bDevice::DeviceManager *m_devMgr; + #endif + void readConfig(); + QPtrList <k9CdDrive> drives; +}; +#endif diff --git a/k9devices/k9dbusdispatch.cpp b/k9devices/k9dbusdispatch.cpp new file mode 100644 index 0000000..71d8a2f --- /dev/null +++ b/k9devices/k9dbusdispatch.cpp @@ -0,0 +1,231 @@ +// +// C++ Implementation: k9dbusdispatch +// +// Description: +// +// +// Author: Jean-Michel PETIT <k9copy@free.fr>, (C) 2007 +// +// Copyright: See COPYING file that comes with this distribution +// +// +#include "k9dbusdispatch.h" +#ifdef HAVE_HAL +#include <dbus/dbus.h> + +//==============================callbacks ======================================== + + +static dbus_bool_t qDBusAddWatch(DBusWatch *watch, void *data) +{ + + int flags = dbus_watch_get_flags(watch); + int fd = dbus_watch_get_fd(watch); + + K9DBusDispatch *d=(K9DBusDispatch*)data; + + k9Watcher watcher; + if (flags & DBUS_WATCH_READABLE) { + bool enabled = dbus_watch_get_enabled(watch); + //qDebug("addReadWatch %d %s", fd, (enabled ? "enabled" : "disabled")); + watcher.watch = watch; + watcher.read = new QSocketNotifier(fd, QSocketNotifier::Read, d); + if (!enabled) watcher.read->setEnabled(false); + d->connect(watcher.read, SIGNAL(activated(int)), SLOT(socketRead(int))); + } + if (flags & DBUS_WATCH_WRITABLE) { + bool enabled = dbus_watch_get_enabled(watch); + //qDebug("addWriteWatch %d %s", fd, (enabled ? "enabled" : "disabled")); + watcher.watch = watch; + watcher.write = new QSocketNotifier(fd, QSocketNotifier::Write, d); + if (!enabled) watcher.write->setEnabled(false); + d->connect(watcher.write, SIGNAL(activated(int)), SLOT(socketWrite(int))); + } + // FIXME-QT4 d->watchers.insertMulti(fd, watcher); + K9DBusDispatch::WatcherHash::iterator it = d->watchers.find(fd); + if (it == d->watchers.end()) + { + it = d->watchers.insert(fd, K9DBusDispatch::WatcherList()); + } + it.data().append(watcher); + + return true; +} + +static void qDBusRemoveWatch(DBusWatch *watch, void *data) +{ + K9DBusDispatch *d = (K9DBusDispatch*)data; + + int fd = dbus_watch_get_fd(watch); + + K9DBusDispatch::WatcherHash::iterator it = d->watchers.find(fd); + if (it != d->watchers.end()) + { + K9DBusDispatch::WatcherList& list = *it; + for (K9DBusDispatch::WatcherList::iterator wit = list.begin(); + wit != list.end(); ++wit) + { + if ((*wit).watch == watch) + { + // migth be called from a function triggered by a socket listener + // so just disconnect them and schedule their delayed deletion. + + d->removedWatches.append(*wit); + if ((*wit).read) + { + (*wit).read->disconnect(d); + (*wit).read = 0; + } + if ((*wit).write) + { + (*wit).write->disconnect(d); + (*wit).write = 0; + } + (*wit).watch = 0; + } + } + } + + if (d->removedWatches.count() > 0) + QTimer::singleShot(0, d, SLOT(purgeRemovedWatches())); + +} + +static void qDBusToggleWatch(DBusWatch *watch, void *data) +{ + K9DBusDispatch *d=(K9DBusDispatch*)data; + int fd = dbus_watch_get_fd(watch); + + K9DBusDispatch::WatcherHash::iterator it = d->watchers.find(fd); + if (it != d->watchers.end()) { + K9DBusDispatch::WatcherList& list = *it; + for (K9DBusDispatch::WatcherList::iterator wit = list.begin(); wit != list.end(); + ++wit) + { + if ((*wit).watch == watch) { + bool enabled = dbus_watch_get_enabled(watch); + int flags = dbus_watch_get_flags(watch); + +// qDebug("toggle watch %d to %d (write: %d, read: %d)", +// dbus_watch_get_fd(watch), enabled, +// flags & DBUS_WATCH_WRITABLE, flags & DBUS_WATCH_READABLE); + + if (flags & DBUS_WATCH_READABLE && (*wit).read) + (*wit).read->setEnabled(enabled); + if (flags & DBUS_WATCH_WRITABLE && (*wit).write) + (*wit).write->setEnabled(enabled); + return; + } + } + } +} + + +void K9DBusDispatch::purgeRemovedWatches() +{ + if (removedWatches.isEmpty()) return; + + WatcherList::iterator listIt = removedWatches.begin(); + for (; listIt != removedWatches.end(); ++listIt) + { + delete (*listIt).read; + delete (*listIt).write; + } + removedWatches.clear(); + + uint count = 0; + WatcherHash::iterator it = watchers.begin(); + while (it != watchers.end()) + { + WatcherList& list = *it; + listIt = list.begin(); + while (listIt != list.end()) + { + if (!((*listIt).read) && !((*listIt).write)) + { + listIt = list.erase(listIt); + ++count; + } + } + + if (list.isEmpty()) + { + WatcherHash::iterator copyIt = it; + ++it; + watchers.erase(copyIt); + } + else + ++it; + } +} +//============================================================================== + +void K9DBusDispatch::socketRead(int fd) +{ + // FIXME-QT4 QHashIterator<int, QDBusConnectionPrivate::Watcher> it(watchers); + WatcherHash::const_iterator it = watchers.find(fd); + if (it != watchers.end()) { + const WatcherList& list = *it; + for (WatcherList::const_iterator wit = list.begin(); wit != list.end(); ++wit) { + if ((*wit).read && (*wit).read->isEnabled()) { + if (!dbus_watch_handle((*wit).watch, DBUS_WATCH_READABLE)) + qDebug("OUT OF MEM"); + } + } + } + scheduleDispatch(); +} + +void K9DBusDispatch::socketWrite(int fd) +{ + // FIXME-QT4 QHashIterator<int, QDBusConnectionPrivate::Watcher> it(watchers); + WatcherHash::const_iterator it = watchers.find(fd); + if (it != watchers.end()) { + const WatcherList& list = *it; + for (WatcherList::const_iterator wit = list.begin(); wit != list.end(); ++wit) { + if ((*wit).write && (*wit).write->isEnabled()) { + if (!dbus_watch_handle((*wit).watch, DBUS_WATCH_WRITABLE)) + qDebug("OUT OF MEM"); + } + } + } +} + +void K9DBusDispatch::scheduleDispatch() +{ + m_dispatcher->start(0); +} + +void K9DBusDispatch::dispatch() +{ + if (dbus_connection_dispatch(m_connection) != DBUS_DISPATCH_DATA_REMAINS) + { + // stop dispatch timer + m_dispatcher->stop(); + } +} + +K9DBusDispatch::K9DBusDispatch(QObject *parent, const char *name) + : QObject(parent, name) +{ + m_dispatcher = new QTimer(this); + QObject::connect(m_dispatcher, SIGNAL(timeout()), this, SLOT(dispatch())); +} + + +K9DBusDispatch::~K9DBusDispatch() +{ +} + + +void K9DBusDispatch::setConnection(DBusConnection* _value) { + m_connection = _value; + + dbus_connection_set_exit_on_disconnect(m_connection, false); + dbus_connection_set_watch_functions(m_connection, qDBusAddWatch, qDBusRemoveWatch, + qDBusToggleWatch, this, 0); +} + +#include "k9dbusdispatch.moc" +#endif + diff --git a/k9devices/k9dbusdispatch.h b/k9devices/k9dbusdispatch.h new file mode 100644 index 0000000..a93c2b0 --- /dev/null +++ b/k9devices/k9dbusdispatch.h @@ -0,0 +1,66 @@ +// +// C++ Interface: k9dbusdispatch +// +// Description: the main goal of this class is to dispatch dbus messages so that libhal can +// detect changes on devices. +// This code is based on QDBusConnectionPrivate from the new Qt DBus bindings +// +// +// Author: Jean-Michel PETIT <k9copy@free.fr>, (C) 2007 +// +// Copyright: See COPYING file that comes with this distribution +// +// +#ifndef K9DBUSDISPATCH_H +#define K9DBUSDISPATCH_H +#include "k9common.h" + +#ifdef HAVE_HAL + +#include <qobject.h> +#include <qtimer.h> +#define DBUS_API_SUBJECT_TO_CHANGE +#include <dbus/dbus.h> +#include <qsocketnotifier.h> +#include <qvaluelist.h> +#include <qmap.h> + +/** + @author Jean-Michel PETIT <k9copy@free.fr> +*/ + +class k9Watcher { +public: + k9Watcher() { read=write=0; watch=0;}; + DBusWatch *watch; + QSocketNotifier *read,*write; +}; + +class K9DBusDispatch : public QObject +{ +Q_OBJECT +public: + K9DBusDispatch(QObject *parent = 0, const char *name = 0); + + ~K9DBusDispatch(); + void setConnection(DBusConnection* _value); + typedef QValueList<k9Watcher> WatcherList; + WatcherList removedWatches; + typedef QMap<int, WatcherList> WatcherHash; + WatcherHash watchers; + +private: + QTimer *m_dispatcher; + DBusConnection *m_connection; + + void purgeRemovedWatches(); + void scheduleDispatch(); +private slots: + void socketRead(int fd); + void socketWrite(int fd); + void dispatch(); + + +}; +#endif +#endif diff --git a/k9devices/k9halconnection.cpp b/k9devices/k9halconnection.cpp new file mode 100644 index 0000000..4de67ac --- /dev/null +++ b/k9devices/k9halconnection.cpp @@ -0,0 +1,159 @@ +// +// C++ Implementation: k9halconnection +// +// Description: +// +// +// Author: Jean-Michel PETIT <k9copy@free.fr>, (C) 2007 +// +// Copyright: See COPYING file that comes with this distribution +// +// +#include "k9common.h" +#ifdef HAVE_HAL + +#include "k9halconnection.h" +#define DBUS_API_SUBJECT_TO_CHANGE +#include "k9haldevice.h" +#include <dbus/dbus.h> +#include <hal/libhal.h> +k9HalConnection *Hinstance=NULL; + +void halDeviceAdded (LibHalContext *ctx, const char *udi) { + Hinstance->addDevice(udi); + Hinstance->testVolumeChanged( udi); + +} + +void halDeviceRemoved (LibHalContext *ctx, const char *udi) { + Hinstance->removeDevice( udi); + Hinstance->testVolumeChanged( udi); +} + + +k9HalConnection::k9HalConnection(QObject *parent, const char *name) + : QObject(parent, name) +{ + m_devices.setAutoDelete(true); + m_context =(void*) libhal_ctx_new(); + + DBusError error; + dbus_error_init( &error ); + m_dbusConnect = dbus_bus_get( DBUS_BUS_SYSTEM, &error ); + if( dbus_error_is_set(&error) ) { + qDebug(QString("Error connecting to DBUS : %1").arg(error.message)); + return; + } + + m_dbusDispatch=new K9DBusDispatch(this,0); + m_dbusDispatch->setConnection(m_dbusConnect); + + libhal_ctx_set_dbus_connection((LibHalContext*) m_context,m_dbusConnect ); + + libhal_ctx_set_device_added( (LibHalContext*)m_context, halDeviceAdded ); + libhal_ctx_set_device_removed( (LibHalContext*)m_context, halDeviceRemoved ); + + if( !libhal_ctx_init((LibHalContext*) m_context, 0 ) ) { + qDebug("HAL init failed"); + return; + } + + int numDevices; + char** halDeviceList = libhal_get_all_devices((LibHalContext*) m_context, &numDevices, 0 ); + for( int i = 0; i < numDevices; ++i ) + //qDebug(halDeviceList[i]); + addDevice( halDeviceList[i] ); +} + +void k9HalConnection::removeDevice( const char* udi ) { + k9HalDevice *device=findDevice( udi); + if (device !=NULL) { + emit deviceRemoved( device); + m_devices.remove(device); + } +} + +void k9HalConnection::addDevice( const char* udi ) +{ + // ignore devices that have no property "info.capabilities" to suppress error messages + if( !libhal_device_property_exists( (LibHalContext*) m_context, udi, "info.capabilities", 0 ) ) + return; + + if( libhal_device_query_capability( (LibHalContext*) m_context, udi, "storage.cdrom", 0 ) ) { + char* dev = libhal_device_get_property_string( (LibHalContext*) m_context, udi, "block.device", 0 ); + if( dev ) { + QString s( dev ); + libhal_free_string( dev ); + + if( !s.isEmpty() ) { + k9HalDevice *device=new k9HalDevice(this,udi); + m_devices.append( device); + emit deviceAdded( device); + } + } + } +} + + +void k9HalConnection::testVolumeChanged( const char * udi) { + // ignore devices that have no property "info.capabilities" to suppress error messages + if( !libhal_device_property_exists( (LibHalContext*) m_context, udi, "info.capabilities", 0 ) ){ + k9HalDevice *device=findDeviceByVolume( udi); + if (device != NULL) + device->updateVolumeName(); + } + else + if( libhal_device_query_capability( (LibHalContext*) m_context, udi, "volume", 0 ) ) { + char* udiParent = libhal_device_get_property_string( (LibHalContext*) m_context, udi, "info.parent", 0 ); + if( udiParent ) { + k9HalDevice *device=findDevice( udiParent); + libhal_free_string( udiParent ); + if (device) + device->updateVolumeName(); + } + } + } + + +k9HalConnection::~k9HalConnection() +{ + libhal_ctx_shutdown((LibHalContext*)m_context, 0 ); + libhal_ctx_free ((LibHalContext*)m_context); + #ifdef DBUS_QT3 + //QDBusConnection::closeConnection("sbus"); + #else + //delete m_dBusQtConnect; + #endif +} + + +k9HalConnection * k9HalConnection::getInstance() { + if (Hinstance==NULL) + Hinstance=new k9HalConnection(NULL,NULL); + return Hinstance; +} + +k9HalDevice *k9HalConnection::findDevice( const char *udi) { + for (k9HalDevice *dev= m_devices.first();dev;dev=m_devices.next()) { + if (dev->name()==QString(udi)) + return dev; + } + return NULL; +} + +k9HalDevice *k9HalConnection::findDeviceByVolume( const char *udi) { + for (k9HalDevice *dev= m_devices.first();dev;dev=m_devices.next()) { + if (dev->getVolumeUdi()==QString(udi)) + return dev; + } + return NULL; +} + +void k9HalConnection::end() { + if (Hinstance !=NULL){ + delete Hinstance; + } + Hinstance=NULL; +} +#include "k9halconnection.moc" +#endif diff --git a/k9devices/k9halconnection.h b/k9devices/k9halconnection.h new file mode 100644 index 0000000..27119a5 --- /dev/null +++ b/k9devices/k9halconnection.h @@ -0,0 +1,66 @@ +// +// C++ Interface: k9halconnection +// +// Description: +// +// +// Author: Jean-Michel PETIT <k9copy@free.fr>, (C) 2007 +// +// Copyright: See COPYING file that comes with this distribution +// +// +#include "k9common.h" +#ifdef HAVE_HAL +#ifndef K9HALCONNECTION_H +#define K9HALCONNECTION_H + +#include <qobject.h> +#include <qptrlist.h> +#include "k9dbusdispatch.h" +/** + @author Jean-Michel PETIT <k9copy@free.fr> +*/ + +class k9HalDevice; +class DBusConnection; +#ifdef DBUS_QT3 +class QDBusConnection; +#else +namespace DBusQt { + class Connection; +}; +#endif + +class k9HalConnection : public QObject +{ +Q_OBJECT +friend class k9HalDevice; +public: + static k9HalConnection* getInstance(); + static void end(); + + QPtrList< k9HalDevice > getDevices() const { return m_devices;} + void addDevice( const char* udi ); + void removeDevice( const char* udi ); + void testVolumeChanged( const char * udi); + k9HalDevice *findDevice (const char* udi); + k9HalDevice *findDeviceByVolume (const char* udi); +signals: + void deviceAdded(k9HalDevice *); + void deviceRemoved(k9HalDevice*); +private: + QPtrList <k9HalDevice> m_devices; + void *m_context; + DBusConnection * m_dbusConnect; + K9DBusDispatch *m_dbusDispatch; +private: + + k9HalConnection(QObject *parent = 0, const char *name = 0); + + ~k9HalConnection(); + + +}; + +#endif +#endif diff --git a/k9devices/k9haldevice.cpp b/k9devices/k9haldevice.cpp new file mode 100644 index 0000000..0f70c42 --- /dev/null +++ b/k9devices/k9haldevice.cpp @@ -0,0 +1,112 @@ +// +// C++ Implementation: k9haldevice +// +// Description: +// +// +// Author: Jean-Michel PETIT <k9copy@free.fr>, (C) 2007 +// +// Copyright: See COPYING file that comes with this distribution +// +// +#include "k9haldevice.h" +#ifdef HAVE_HAL +#include "k9halconnection.h" +#define DBUS_API_SUBJECT_TO_CHANGE +#include <dbus/dbus.h> +#include <hal/libhal.h> +#include <hal/libhal-storage.h> + +k9HalDevice::k9HalDevice(QObject *parent, const char *udi) + : QObject(parent, udi) { + + m_connection=(k9HalConnection*)parent; + getDriveProperties(); +} + +k9HalDevice::~k9HalDevice() {} + +QString k9HalDevice::volumeName() { + QString sVol(""); + LibHalDrive *drive= libhal_drive_from_udi ((LibHalContext *)m_connection->m_context, name()); + int num_volumes; + if (drive !=NULL) { + char** volumes = libhal_drive_find_all_volumes ((LibHalContext *)m_connection->m_context, drive, &num_volumes); + if (volumes != NULL) { + for (int i = 0; i < num_volumes; i++) { + char *volume_udi; + LibHalVolume *volume; + volume_udi = volumes[i]; + QString s(volume_udi); + m_volumeUdi=s; + volume = libhal_volume_from_udi ((LibHalContext *)m_connection->m_context, volume_udi); + if (volume != NULL) { + sVol=QString(libhal_volume_get_label (volume)); + libhal_volume_free (volume); + } + } + if (num_volumes >0) + libhal_free_string_array (volumes); + } + libhal_drive_free(drive); + } + return sVol; +} + +QString k9HalDevice::mountPoint() { + QString sMountPoint(""); + LibHalDrive *drive= libhal_drive_from_udi ((LibHalContext *)m_connection->m_context, name()); + if (drive !=NULL) { + int num_volumes; + char** volumes = libhal_drive_find_all_volumes ((LibHalContext *)m_connection->m_context, drive, &num_volumes); + if (volumes != NULL) { + for (int i = 0; i < num_volumes; i++) { + char *volume_udi; + LibHalVolume *volume; + volume_udi = volumes[i]; + volume = libhal_volume_from_udi ((LibHalContext *)m_connection->m_context, volume_udi); + if (volume != NULL) { + sMountPoint=QString(libhal_volume_get_mount_point (volume)); + libhal_volume_free (volume); + } + } + if (num_volumes >0) + libhal_free_string_array (volumes); + } + libhal_drive_free(drive); + } + return sMountPoint; +} + + +void k9HalDevice::updateVolumeName() { + m_volumeName=volumeName(); + emit volumeChanged(this->getDeviceName(),m_volumeName); +} + +void k9HalDevice::getDriveProperties() { + LibHalContext *context=(LibHalContext *)m_connection->m_context; + LibHalDrive *drive= libhal_drive_from_udi (context, name()); + LibHalDriveCdromCaps caps; + caps= libhal_drive_get_cdrom_caps (drive); + m_canReadCd=m_canReadDvd=m_canBurnCd=m_canBurnDvd=false; + m_canReadCd= (caps & LIBHAL_DRIVE_CDROM_CAPS_CDROM)==LIBHAL_DRIVE_CDROM_CAPS_CDROM; + m_canBurnCd= (caps & LIBHAL_DRIVE_CDROM_CAPS_CDR)==LIBHAL_DRIVE_CDROM_CAPS_CDR; + m_canReadDvd=(caps & LIBHAL_DRIVE_CDROM_CAPS_DVDROM)==LIBHAL_DRIVE_CDROM_CAPS_DVDROM; + m_canBurnDvd=(caps & LIBHAL_DRIVE_CDROM_CAPS_DVDR)==LIBHAL_DRIVE_CDROM_CAPS_DVDR; + m_model=QString(libhal_drive_get_model(drive)); + // qDebug(QString("canReadDvd:%1 canBurnDvd:%2 model:%3").arg(m_canReadDvd).arg(m_canBurnDvd).arg(m_model)); + + + libhal_drive_free(drive); + if (libhal_device_property_exists( (LibHalContext*) m_connection->m_context, name(), "storage.cdrom.write_speed", 0 )) { + m_maxWriteSpeed= libhal_device_get_property_int( (LibHalContext*)m_connection->m_context, name(), "storage.cdrom.write_speed", 0 ); + } + char* dev = libhal_device_get_property_string( (LibHalContext*) m_connection->m_context, name(), "block.device", 0 ); + m_deviceName=QString ( dev ); + libhal_free_string( dev ); + + m_volumeName=volumeName(); +} +#include "k9haldevice.moc" +#endif diff --git a/k9devices/k9haldevice.h b/k9devices/k9haldevice.h new file mode 100644 index 0000000..e7c25f1 --- /dev/null +++ b/k9devices/k9haldevice.h @@ -0,0 +1,86 @@ +// +// C++ Interface: k9haldevice +// +// Description: +// +// +// Author: Jean-Michel PETIT <k9copy@free.fr>, (C) 2007 +// +// Copyright: See COPYING file that comes with this distribution +// +// + +#ifndef K9HALDEVICE_H +#define K9HALDEVICE_H +#include "k9common.h" +#ifdef HAVE_HAL + +#include <qobject.h> +/** + @author Jean-Michel PETIT <k9copy@free.fr> +*/ +class k9HalConnection; +class k9HalDevice : public QObject +{ +Q_OBJECT +public: + + k9HalDevice(QObject *parent = 0, const char *name = 0); + + ~k9HalDevice(); + + bool getCanReadCd() const { + return m_canReadCd; + } + + bool getCanReadDvd() const { + return m_canReadDvd; + } + + bool getCanBurnCd() const { + return m_canBurnCd; + } + + bool getCanBurnDvd() const { + return m_canBurnDvd; + } + + QString getModel() const { + return m_model; + } + + int getMaxWriteSpeed() const { + return m_maxWriteSpeed; + } + + QString getDeviceName() const { + return m_deviceName; + } + void updateVolumeName(); + + QString getVolumeUdi() const { + return m_volumeUdi; + } + + QString getVolumeName() const { + return m_volumeName; + } + + QString mountPoint(); +signals: + void volumeChanged(const QString &device,const QString &volumeName); + +private: + QString m_volumeName; + QString m_volumeUdi; + k9HalConnection *m_connection; + bool m_canReadCd,m_canReadDvd,m_canBurnCd,m_canBurnDvd; + QString m_model; + QString m_deviceName; + int m_maxWriteSpeed; + void getDriveProperties(); + QString volumeName(); +}; + +#endif +#endif |