-rw-r--r-- | libopie2/examples/opiecore/onotifydemo/onotifydemo.cpp | 43 | ||||
-rw-r--r-- | libopie2/opiecore/ofilenotify.cpp | 160 | ||||
-rw-r--r-- | libopie2/opiecore/ofilenotify.h | 36 |
3 files changed, 176 insertions, 63 deletions
diff --git a/libopie2/examples/opiecore/onotifydemo/onotifydemo.cpp b/libopie2/examples/opiecore/onotifydemo/onotifydemo.cpp index a8a5717..74a8158 100644 --- a/libopie2/examples/opiecore/onotifydemo/onotifydemo.cpp +++ b/libopie2/examples/opiecore/onotifydemo/onotifydemo.cpp @@ -10,2 +10,3 @@ using namespace Opie::Ui; /* QT */ +#include <qcheckbox.h> #include <qvbox.h> @@ -14,4 +15,4 @@ using namespace Opie::Ui; #include <qvbuttongroup.h> +#include <qmessagebox.h> #include <qpushbutton.h> -#include <qcheckbox.h> @@ -29,3 +30,6 @@ public: l->addColumn( "Notification Path" ); - l->addColumn( "Trigger" ); + l->addColumn( "Trigger Type" ); + l->addColumn( "Trigger Mask" ); + l->setColumnAlignment( 1, AlignCenter ); + l->setColumnAlignment( 2, AlignCenter ); @@ -47,2 +51,3 @@ public: g2->insert( c7, Attrib ); + connect( g2, SIGNAL( pressed(int) ), this, SLOT( modifierClicked(int) ) ); @@ -70,2 +75,8 @@ public: { + if ( !m ) + { + QMessageBox::warning( 0, "Add Trigger", "<p>Can't add trigger without at least one selected trigger type</p>", "&Sorry", 0 ); + return; + } + QString filename = OFileDialog::getOpenFileName( OFileSelector::ExtendedAll ); @@ -74,7 +85,12 @@ public: odebug << "Filename = " << filename << oendl; - new OListViewItem( l, filename, "Modify" ); - + int fntype = m; + if ( multi ) fntype |=(int) Multi; - OFileNotifier::singleShot( filename, this, SLOT( trigger() ) ); + QString modifier = QString().sprintf( " = 0x%08x", fntype ); + new OListViewItem( l, filename, multi ? "MULTI" : "SINGLE", modifier ); + if ( !multi ) + OFileNotification::singleShot( filename, this, SLOT( trigger() ), (OFileNotificationType) fntype ); + else + OFileNotification::singleShot( filename, this, SLOT( trigger() ), (OFileNotificationType) fntype ); } @@ -87,3 +103,3 @@ public: public slots: - + void modifierClicked( int modifier ) { (int)m ^= modifier; }; void addSingle() { addTrigger(); }; @@ -93,4 +109,13 @@ public slots: { - QString filename( "bla" ); - odebug << "Filename = " << filename << oendl; + QListViewItem* item = l->selectedItem(); + if ( !item ) + { + QMessageBox::warning( 0, "Del Trigger", "<p>No trigger selected!</p>", "&Sorry", 0 ); + return; + } + else + { + QString filename( item->text( 0 ) ); + odebug << "Filename = " << filename << oendl; + } } @@ -106,3 +131,3 @@ private: QButtonGroup* g2; - int m; + OFileNotificationType m; }; diff --git a/libopie2/opiecore/ofilenotify.cpp b/libopie2/opiecore/ofilenotify.cpp index 2242570..5e9f97b 100644 --- a/libopie2/opiecore/ofilenotify.cpp +++ b/libopie2/opiecore/ofilenotify.cpp @@ -34,2 +34,3 @@ using namespace Opie::Core; /* QT */ +#include <qobject.h> #include <qsignal.h> @@ -41,5 +42,14 @@ using namespace Opie::Core; #include <sys/stat.h> -#include <fcntl.h> +#ifndef _GNU_SOURCE + #define _GNU_SOURCE + #include <fcntl.h> + #undef _GNU_SOURCE +#else + #include <fcntl.h> +#endif #include <string.h> #include <errno.h> +#include <unistd.h> + +static QIntDict<OFileNotification> notification_list; @@ -48,34 +58,27 @@ namespace Core { -class OFileNotification +OFileNotification::OFileNotification( QObject* parent, const char* name ) + :QObject( parent, name ), _active( false ) { - public: - OFileNotification( QObject* receiver, const char* member, OFileNotificationType type ) : _type( type ) - { - _signal.connect( receiver, member ); - } - ~OFileNotification() - { - } - - void activate() - { - _signal.activate(); - } + qDebug( "OFileNotification::OFileNotification()" ); +} - OFileNotificationType type() - { - return _type; - } - private: - OFileNotificationType _type; - QSignal _signal; -}; +OFileNotification::~OFileNotification() +{ + qDebug( "OFileNotification::~OFileNotification()" ); +} -static QIntDict<OFileNotification> notification_list; +bool OFileNotification::isActive() const +{ + return _active; +} -void OFileNotifier::singleShot( const QString& path, QObject* receiver, const char* member, OFileNotificationType type ) +int OFileNotification::start( const QString& path, bool sshot, OFileNotificationType type ) { + _path = QString::null; + _fd = 0; + if ( _active ) stop(); + int fd = ::open( (const char*) path, O_RDONLY ); @@ -85,3 +88,3 @@ void OFileNotifier::singleShot( const QString& path, QObject* receiver, const ch { - OFileNotifier::registerSignalHandler(); + OFileNotification::registerSignalHandler(); } @@ -90,5 +93,6 @@ void OFileNotifier::singleShot( const QString& path, QObject* receiver, const ch { - qWarning( "OFileNotifier::singleShot(): Can't subscribe to '%s': %s.", (const char*) path, strerror( errno ) ); - return; + qWarning( "OFileNotification::start(): Can't subscribe to '%s': %s.", (const char*) path, strerror( errno ) ); + return -1; } + if ( !sshot ) (int) type |= (int) Multi; result = ::fcntl( fd, F_NOTIFY, type ); @@ -96,7 +100,11 @@ void OFileNotifier::singleShot( const QString& path, QObject* receiver, const ch { - qWarning( "OFileNotifier::singleShot(): Can't subscribe to '%s': %s.", (const char*) path, strerror( errno ) ); - return; + qWarning( "OFileNotification::start(): Can't subscribe to '%s': %s.", (const char*) path, strerror( errno ) ); + return -1; } - qDebug( "OFileNotifier::singleShot(): Subscribed for changes to %s (fd = %d)", (const char*) path, fd ); - notification_list.insert( fd, new OFileNotification( receiver, member, type ) ); + qDebug( "OFileNotification::start(): Subscribed for changes to %s (fd = %d, mask = 0x%0x)", (const char*) path, fd, type ); + notification_list.insert( fd, this ); + _type = type; + _path = path; + _fd = fd; + return fd; } @@ -104,3 +112,4 @@ void OFileNotifier::singleShot( const QString& path, QObject* receiver, const ch { - qWarning( "OFileNotifier::singleShot(): Error with path '%s': %s.", (const char*) path, strerror( errno ) ); + qWarning( "OFileNotification::start(): Error with path '%s': %s.", (const char*) path, strerror( errno ) ); + return -1; } @@ -109,5 +118,56 @@ void OFileNotifier::singleShot( const QString& path, QObject* receiver, const ch -void OFileNotifier::__signalHandler( int sig, siginfo_t *si, void *data ) +void OFileNotification::stop() { - qWarning( "OFileNotifier::__signalHandler(): reached." ); + if ( !_active ) return; + + int result = ::fcntl( _fd, F_NOTIFY, 0 ); + if ( result == -1 ) + { + qWarning( "OFileNotification::stop(): Can't remove subscription to '%s': %s.", (const char*) _path, strerror( errno ) ); + } + else + { + ::close( _fd ); + _type = Single; + _path = QString::null; + _fd = 0; + _active = false; + } +} + + +OFileNotificationType OFileNotification::type() const +{ + return _type; +} + + +QString OFileNotification::path() const +{ + return _path; +} + +int OFileNotification::fileno() const +{ + return _fd; +} + +void OFileNotification::activate() +{ + emit triggered(); + _signal.activate(); +} + + +void OFileNotification::singleShot( const QString& path, QObject* receiver, const char* member, OFileNotificationType type ) +{ + OFileNotification* ofn = new OFileNotification(); + ofn->_signal.connect( receiver, member ); + ofn->start( path, true, type ); +} + + +void OFileNotification::__signalHandler( int sig, siginfo_t *si, void *data ) +{ + qWarning( "OFileNotification::__signalHandler(): reached." ); int fd = si->si_fd; @@ -120,3 +180,3 @@ void OFileNotifier::__signalHandler( int sig, siginfo_t *si, void *data ) { - qDebug( "OFileNotifier::__signalHandler(): '%d' was singleShot. Removing from list.", fd ); + qDebug( "OFileNotification::__signalHandler(): '%d' was singleShot. Removing from list.", fd ); notification_list.remove( fd ); @@ -124,3 +184,3 @@ void OFileNotifier::__signalHandler( int sig, siginfo_t *si, void *data ) { - OFileNotifier::unregisterSignalHandler(); + OFileNotification::unregisterSignalHandler(); } @@ -131,3 +191,3 @@ void OFileNotifier::__signalHandler( int sig, siginfo_t *si, void *data ) { - qWarning( "OFileNotifier::__signalHandler(): D'oh! Called without fd in notification_list. Race condition?" ); + qWarning( "OFileNotification::__signalHandler(): D'oh! Called without fd in notification_list. Race condition?" ); } @@ -136,10 +196,14 @@ void OFileNotifier::__signalHandler( int sig, siginfo_t *si, void *data ) -void OFileNotifier::registerSignalHandler() +bool OFileNotification::registerSignalHandler() { struct sigaction act; - act.sa_sigaction = OFileNotifier::__signalHandler; + act.sa_sigaction = OFileNotification::__signalHandler; ::sigemptyset( &act.sa_mask ); act.sa_flags = SA_SIGINFO; - ::sigaction( SIGRTMIN, &act, NULL ); - qDebug( "OFileNotifier::registerSignalHandler(): done" ); + if ( ::sigaction( SIGRTMIN, &act, NULL ) == -1 ) + { + qWarning( "OFileNotification::registerSignalHandler(): couldn't register signal handler: %s", strerror( errno ) ); + return false; + } + qDebug( "OFileNotification::registerSignalHandler(): done" ); } @@ -147,3 +211,3 @@ void OFileNotifier::registerSignalHandler() -void OFileNotifier::unregisterSignalHandler() +void OFileNotification::unregisterSignalHandler() { @@ -151,5 +215,9 @@ void OFileNotifier::unregisterSignalHandler() act.sa_sigaction = ( void (*)(int, siginfo_t*, void*) ) SIG_DFL; - sigemptyset( &act.sa_mask ); - ::sigaction( SIGRTMIN, &act, NULL ); - qDebug( "OFileNotifier::unregisterSignalHandler(): done" ); + ::sigemptyset( &act.sa_mask ); + if ( ::sigaction( SIGRTMIN, &act, NULL ) == -1 ) + if ( ::sigaction( SIGRTMIN, &act, NULL ) == -1 ) + { + qWarning( "OFileNotification::unregisterSignalHandler(): couldn't deregister signal handler: %s", strerror( errno ) ); + } + qDebug( "OFileNotification::unregisterSignalHandler(): done" ); } diff --git a/libopie2/opiecore/ofilenotify.h b/libopie2/opiecore/ofilenotify.h index 638eb6c..a14842a 100644 --- a/libopie2/opiecore/ofilenotify.h +++ b/libopie2/opiecore/ofilenotify.h @@ -32,4 +32,5 @@ _;:, .> :=|. This program is free software; you can /* QT */ -#include <qstring.h> #include <qobject.h> +#include <qsignal.h> +#include <qstring.h> @@ -51,10 +52,26 @@ enum OFileNotificationType { Single = 0x0000000, -class OFileNotifier : public QObject +class OFileNotification : public QObject { + Q_OBJECT + public: - static void singleShot( const QString& path, - QObject *receiver, const char *member, - OFileNotificationType type = Modify ); + OFileNotification( QObject* parent = 0, const char* name = 0 ); + ~OFileNotification(); + + static void singleShot( const QString& path, QObject* receiver, const char* member, OFileNotificationType type = Modify ); + + int start( const QString& path, bool sshot = false, OFileNotificationType type = Modify ); + void stop(); + + OFileNotificationType type() const; + QString path() const; + int fileno() const; + bool isActive() const; + + signals: + void triggered(); + protected: - static void registerSignalHandler(); + void activate(); + static bool registerSignalHandler(); static void unregisterSignalHandler(); @@ -63,4 +80,7 @@ class OFileNotifier : public QObject private: - OFileNotifier(); - ~OFileNotifier(); + QString _path; + OFileNotificationType _type; + QSignal _signal; + int _fd; + bool _active; }; |