summaryrefslogtreecommitdiffstats
path: root/k9devices
diff options
context:
space:
mode:
Diffstat (limited to 'k9devices')
-rw-r--r--k9devices/Makefile.am10
-rw-r--r--k9devices/configure.in.in134
-rw-r--r--k9devices/k9cddrive.cpp199
-rw-r--r--k9devices/k9cddrive.h87
-rw-r--r--k9devices/k9dbusdispatch.cpp231
-rw-r--r--k9devices/k9dbusdispatch.h66
-rw-r--r--k9devices/k9halconnection.cpp159
-rw-r--r--k9devices/k9halconnection.h66
-rw-r--r--k9devices/k9haldevice.cpp112
-rw-r--r--k9devices/k9haldevice.h86
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