summaryrefslogtreecommitdiff
authormickeyl <mickeyl>2004-04-18 18:25:24 (UTC)
committer mickeyl <mickeyl>2004-04-18 18:25:24 (UTC)
commitdf539f67050ebe61b5dc589f9c138bb9ef1719f6 (patch) (unidiff)
tree7baa2dc1e44be92dec2736b8205f9642fffc4302
parent56f49e8293110e488f3ea6bc6dad282981c81d4b (diff)
downloadopie-df539f67050ebe61b5dc589f9c138bb9ef1719f6.zip
opie-df539f67050ebe61b5dc589f9c138bb9ef1719f6.tar.gz
opie-df539f67050ebe61b5dc589f9c138bb9ef1719f6.tar.bz2
the notifier interface is shaping up
Brad: I sorted the "DN_xxx undeclared" issue out, please test
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--libopie2/examples/opiecore/onotifydemo/onotifydemo.cpp43
-rw-r--r--libopie2/opiecore/ofilenotify.cpp160
-rw-r--r--libopie2/opiecore/ofilenotify.h36
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;
10/* QT */ 10/* QT */
11#include <qcheckbox.h>
11#include <qvbox.h> 12#include <qvbox.h>
@@ -14,4 +15,4 @@ using namespace Opie::Ui;
14#include <qvbuttongroup.h> 15#include <qvbuttongroup.h>
16#include <qmessagebox.h>
15#include <qpushbutton.h> 17#include <qpushbutton.h>
16#include <qcheckbox.h>
17 18
@@ -29,3 +30,6 @@ public:
29 l->addColumn( "Notification Path" ); 30 l->addColumn( "Notification Path" );
30 l->addColumn( "Trigger" ); 31 l->addColumn( "Trigger Type" );
32 l->addColumn( "Trigger Mask" );
33 l->setColumnAlignment( 1, AlignCenter );
34 l->setColumnAlignment( 2, AlignCenter );
31 35
@@ -47,2 +51,3 @@ public:
47 g2->insert( c7, Attrib ); 51 g2->insert( c7, Attrib );
52 connect( g2, SIGNAL( pressed(int) ), this, SLOT( modifierClicked(int) ) );
48 53
@@ -70,2 +75,8 @@ public:
70 { 75 {
76 if ( !m )
77 {
78 QMessageBox::warning( 0, "Add Trigger", "<p>Can't add trigger without at least one selected trigger type</p>", "&Sorry", 0 );
79 return;
80 }
81
71 QString filename = OFileDialog::getOpenFileName( OFileSelector::ExtendedAll ); 82 QString filename = OFileDialog::getOpenFileName( OFileSelector::ExtendedAll );
@@ -74,7 +85,12 @@ public:
74 odebug << "Filename = " << filename << oendl; 85 odebug << "Filename = " << filename << oendl;
75 new OListViewItem( l, filename, "Modify" );
76
77 86
87 int fntype = m;
88 if ( multi ) fntype |=(int) Multi;
78 89
79 OFileNotifier::singleShot( filename, this, SLOT( trigger() ) ); 90 QString modifier = QString().sprintf( " = 0x%08x", fntype );
91 new OListViewItem( l, filename, multi ? "MULTI" : "SINGLE", modifier );
92 if ( !multi )
93 OFileNotification::singleShot( filename, this, SLOT( trigger() ), (OFileNotificationType) fntype );
94 else
95 OFileNotification::singleShot( filename, this, SLOT( trigger() ), (OFileNotificationType) fntype );
80 } 96 }
@@ -87,3 +103,3 @@ public:
87public slots: 103public slots:
88 104 void modifierClicked( int modifier ) { (int)m ^= modifier; };
89 void addSingle() { addTrigger(); }; 105 void addSingle() { addTrigger(); };
@@ -93,4 +109,13 @@ public slots:
93 { 109 {
94 QString filename( "bla" ); 110 QListViewItem* item = l->selectedItem();
95 odebug << "Filename = " << filename << oendl; 111 if ( !item )
112 {
113 QMessageBox::warning( 0, "Del Trigger", "<p>No trigger selected!</p>", "&Sorry", 0 );
114 return;
115 }
116 else
117 {
118 QString filename( item->text( 0 ) );
119 odebug << "Filename = " << filename << oendl;
120 }
96 } 121 }
@@ -106,3 +131,3 @@ private:
106 QButtonGroup* g2; 131 QButtonGroup* g2;
107 int m; 132 OFileNotificationType m;
108}; 133};
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;
34/* QT */ 34/* QT */
35#include <qobject.h>
35#include <qsignal.h> 36#include <qsignal.h>
@@ -41,5 +42,14 @@ using namespace Opie::Core;
41#include <sys/stat.h> 42#include <sys/stat.h>
42#include <fcntl.h> 43#ifndef _GNU_SOURCE
44 #define _GNU_SOURCE
45 #include <fcntl.h>
46 #undef _GNU_SOURCE
47#else
48 #include <fcntl.h>
49#endif
43#include <string.h> 50#include <string.h>
44#include <errno.h> 51#include <errno.h>
52#include <unistd.h>
53
54static QIntDict<OFileNotification> notification_list;
45 55
@@ -48,34 +58,27 @@ namespace Core {
48 58
49class OFileNotification 59OFileNotification::OFileNotification( QObject* parent, const char* name )
60 :QObject( parent, name ), _active( false )
50{ 61{
51 public: 62 qDebug( "OFileNotification::OFileNotification()" );
52 OFileNotification( QObject* receiver, const char* member, OFileNotificationType type ) : _type( type ) 63}
53 {
54 _signal.connect( receiver, member );
55 }
56 ~OFileNotification()
57 {
58 }
59
60 void activate()
61 {
62 _signal.activate();
63 }
64 64
65 OFileNotificationType type()
66 {
67 return _type;
68 }
69 65
70 private: 66OFileNotification::~OFileNotification()
71 OFileNotificationType _type; 67{
72 QSignal _signal; 68 qDebug( "OFileNotification::~OFileNotification()" );
73}; 69}
74 70
75 71
76static QIntDict<OFileNotification> notification_list; 72bool OFileNotification::isActive() const
73{
74 return _active;
75}
77 76
78 77
79void OFileNotifier::singleShot( const QString& path, QObject* receiver, const char* member, OFileNotificationType type ) 78int OFileNotification::start( const QString& path, bool sshot, OFileNotificationType type )
80{ 79{
80 _path = QString::null;
81 _fd = 0;
82 if ( _active ) stop();
83
81 int fd = ::open( (const char*) path, O_RDONLY ); 84 int fd = ::open( (const char*) path, O_RDONLY );
@@ -85,3 +88,3 @@ void OFileNotifier::singleShot( const QString& path, QObject* receiver, const ch
85 { 88 {
86 OFileNotifier::registerSignalHandler(); 89 OFileNotification::registerSignalHandler();
87 } 90 }
@@ -90,5 +93,6 @@ void OFileNotifier::singleShot( const QString& path, QObject* receiver, const ch
90 { 93 {
91 qWarning( "OFileNotifier::singleShot(): Can't subscribe to '%s': %s.", (const char*) path, strerror( errno ) ); 94 qWarning( "OFileNotification::start(): Can't subscribe to '%s': %s.", (const char*) path, strerror( errno ) );
92 return; 95 return -1;
93 } 96 }
97 if ( !sshot ) (int) type |= (int) Multi;
94 result = ::fcntl( fd, F_NOTIFY, type ); 98 result = ::fcntl( fd, F_NOTIFY, type );
@@ -96,7 +100,11 @@ void OFileNotifier::singleShot( const QString& path, QObject* receiver, const ch
96 { 100 {
97 qWarning( "OFileNotifier::singleShot(): Can't subscribe to '%s': %s.", (const char*) path, strerror( errno ) ); 101 qWarning( "OFileNotification::start(): Can't subscribe to '%s': %s.", (const char*) path, strerror( errno ) );
98 return; 102 return -1;
99 } 103 }
100 qDebug( "OFileNotifier::singleShot(): Subscribed for changes to %s (fd = %d)", (const char*) path, fd ); 104 qDebug( "OFileNotification::start(): Subscribed for changes to %s (fd = %d, mask = 0x%0x)", (const char*) path, fd, type );
101 notification_list.insert( fd, new OFileNotification( receiver, member, type ) ); 105 notification_list.insert( fd, this );
106 _type = type;
107 _path = path;
108 _fd = fd;
109 return fd;
102 } 110 }
@@ -104,3 +112,4 @@ void OFileNotifier::singleShot( const QString& path, QObject* receiver, const ch
104 { 112 {
105 qWarning( "OFileNotifier::singleShot(): Error with path '%s': %s.", (const char*) path, strerror( errno ) ); 113 qWarning( "OFileNotification::start(): Error with path '%s': %s.", (const char*) path, strerror( errno ) );
114 return -1;
106 } 115 }
@@ -109,5 +118,56 @@ void OFileNotifier::singleShot( const QString& path, QObject* receiver, const ch
109 118
110void OFileNotifier::__signalHandler( int sig, siginfo_t *si, void *data ) 119void OFileNotification::stop()
111{ 120{
112 qWarning( "OFileNotifier::__signalHandler(): reached." ); 121 if ( !_active ) return;
122
123 int result = ::fcntl( _fd, F_NOTIFY, 0 );
124 if ( result == -1 )
125 {
126 qWarning( "OFileNotification::stop(): Can't remove subscription to '%s': %s.", (const char*) _path, strerror( errno ) );
127 }
128 else
129 {
130 ::close( _fd );
131 _type = Single;
132 _path = QString::null;
133 _fd = 0;
134 _active = false;
135 }
136}
137
138
139OFileNotificationType OFileNotification::type() const
140{
141 return _type;
142}
143
144
145QString OFileNotification::path() const
146{
147 return _path;
148}
149
150int OFileNotification::fileno() const
151{
152 return _fd;
153}
154
155void OFileNotification::activate()
156{
157 emit triggered();
158 _signal.activate();
159}
160
161
162void OFileNotification::singleShot( const QString& path, QObject* receiver, const char* member, OFileNotificationType type )
163{
164 OFileNotification* ofn = new OFileNotification();
165 ofn->_signal.connect( receiver, member );
166 ofn->start( path, true, type );
167}
168
169
170void OFileNotification::__signalHandler( int sig, siginfo_t *si, void *data )
171{
172 qWarning( "OFileNotification::__signalHandler(): reached." );
113 int fd = si->si_fd; 173 int fd = si->si_fd;
@@ -120,3 +180,3 @@ void OFileNotifier::__signalHandler( int sig, siginfo_t *si, void *data )
120 { 180 {
121 qDebug( "OFileNotifier::__signalHandler(): '%d' was singleShot. Removing from list.", fd ); 181 qDebug( "OFileNotification::__signalHandler(): '%d' was singleShot. Removing from list.", fd );
122 notification_list.remove( fd ); 182 notification_list.remove( fd );
@@ -124,3 +184,3 @@ void OFileNotifier::__signalHandler( int sig, siginfo_t *si, void *data )
124 { 184 {
125 OFileNotifier::unregisterSignalHandler(); 185 OFileNotification::unregisterSignalHandler();
126 } 186 }
@@ -131,3 +191,3 @@ void OFileNotifier::__signalHandler( int sig, siginfo_t *si, void *data )
131 { 191 {
132 qWarning( "OFileNotifier::__signalHandler(): D'oh! Called without fd in notification_list. Race condition?" ); 192 qWarning( "OFileNotification::__signalHandler(): D'oh! Called without fd in notification_list. Race condition?" );
133 } 193 }
@@ -136,10 +196,14 @@ void OFileNotifier::__signalHandler( int sig, siginfo_t *si, void *data )
136 196
137void OFileNotifier::registerSignalHandler() 197bool OFileNotification::registerSignalHandler()
138{ 198{
139 struct sigaction act; 199 struct sigaction act;
140 act.sa_sigaction = OFileNotifier::__signalHandler; 200 act.sa_sigaction = OFileNotification::__signalHandler;
141 ::sigemptyset( &act.sa_mask ); 201 ::sigemptyset( &act.sa_mask );
142 act.sa_flags = SA_SIGINFO; 202 act.sa_flags = SA_SIGINFO;
143 ::sigaction( SIGRTMIN, &act, NULL ); 203 if ( ::sigaction( SIGRTMIN, &act, NULL ) == -1 )
144 qDebug( "OFileNotifier::registerSignalHandler(): done" ); 204 {
205 qWarning( "OFileNotification::registerSignalHandler(): couldn't register signal handler: %s", strerror( errno ) );
206 return false;
207 }
208 qDebug( "OFileNotification::registerSignalHandler(): done" );
145} 209}
@@ -147,3 +211,3 @@ void OFileNotifier::registerSignalHandler()
147 211
148void OFileNotifier::unregisterSignalHandler() 212void OFileNotification::unregisterSignalHandler()
149{ 213{
@@ -151,5 +215,9 @@ void OFileNotifier::unregisterSignalHandler()
151 act.sa_sigaction = ( void (*)(int, siginfo_t*, void*) ) SIG_DFL; 215 act.sa_sigaction = ( void (*)(int, siginfo_t*, void*) ) SIG_DFL;
152 sigemptyset( &act.sa_mask ); 216 ::sigemptyset( &act.sa_mask );
153 ::sigaction( SIGRTMIN, &act, NULL ); 217 if ( ::sigaction( SIGRTMIN, &act, NULL ) == -1 )
154 qDebug( "OFileNotifier::unregisterSignalHandler(): done" ); 218 if ( ::sigaction( SIGRTMIN, &act, NULL ) == -1 )
219 {
220 qWarning( "OFileNotification::unregisterSignalHandler(): couldn't deregister signal handler: %s", strerror( errno ) );
221 }
222 qDebug( "OFileNotification::unregisterSignalHandler(): done" );
155} 223}
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
32/* QT */ 32/* QT */
33#include <qstring.h>
34#include <qobject.h> 33#include <qobject.h>
34#include <qsignal.h>
35#include <qstring.h>
35 36
@@ -51,10 +52,26 @@ enum OFileNotificationType { Single = 0x0000000,
51 52
52class OFileNotifier : public QObject 53class OFileNotification : public QObject
53{ 54{
55 Q_OBJECT
56
54 public: 57 public:
55 static void singleShot( const QString& path, 58 OFileNotification( QObject* parent = 0, const char* name = 0 );
56 QObject *receiver, const char *member, 59 ~OFileNotification();
57 OFileNotificationType type = Modify ); 60
61 static void singleShot( const QString& path, QObject* receiver, const char* member, OFileNotificationType type = Modify );
62
63 int start( const QString& path, bool sshot = false, OFileNotificationType type = Modify );
64 void stop();
65
66 OFileNotificationType type() const;
67 QString path() const;
68 int fileno() const;
69 bool isActive() const;
70
71 signals:
72 void triggered();
73
58 protected: 74 protected:
59 static void registerSignalHandler(); 75 void activate();
76 static bool registerSignalHandler();
60 static void unregisterSignalHandler(); 77 static void unregisterSignalHandler();
@@ -63,4 +80,7 @@ class OFileNotifier : public QObject
63 private: 80 private:
64 OFileNotifier(); 81 QString _path;
65 ~OFileNotifier(); 82 OFileNotificationType _type;
83 QSignal _signal;
84 int _fd;
85 bool _active;
66}; 86};