summaryrefslogtreecommitdiff
authormickeyl <mickeyl>2005-05-10 13:30:51 (UTC)
committer mickeyl <mickeyl>2005-05-10 13:30:51 (UTC)
commite31f22952f47aeb54b206349f1e469704a6a6e8f (patch) (unidiff)
tree2aa06bf1ebd9850b1e987d1dcc94794699a0c9fe
parent9bcf6a5112d31ffdc196ebcd22a584c68f9f7b1e (diff)
downloadopie-e31f22952f47aeb54b206349f1e469704a6a6e8f.zip
opie-e31f22952f47aeb54b206349f1e469704a6a6e8f.tar.gz
opie-e31f22952f47aeb54b206349f1e469704a6a6e8f.tar.bz2
add foundation for a much more intuitive API for file notifications
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--examples/opiecore/onotifytest/.cvsignore6
-rw-r--r--examples/opiecore/onotifytest/main.cpp59
-rw-r--r--examples/opiecore/onotifytest/onotifytest.pro16
-rw-r--r--examples/opiecore/opiecore.pro2
-rw-r--r--libopie2/opiecore/ofilenotify.cpp58
-rw-r--r--libopie2/opiecore/ofilenotify.h37
6 files changed, 176 insertions, 2 deletions
diff --git a/examples/opiecore/onotifytest/.cvsignore b/examples/opiecore/onotifytest/.cvsignore
new file mode 100644
index 0000000..8f7300c
--- a/dev/null
+++ b/examples/opiecore/onotifytest/.cvsignore
@@ -0,0 +1,6 @@
1Makefile*
2moc*
3*moc
4*.o
5~*
6
diff --git a/examples/opiecore/onotifytest/main.cpp b/examples/opiecore/onotifytest/main.cpp
new file mode 100644
index 0000000..467ebc9
--- a/dev/null
+++ b/examples/opiecore/onotifytest/main.cpp
@@ -0,0 +1,59 @@
1// (C) Michael 'Mickey' Lauer <mickey@Vanille.de>
2// LICENSE = "GPLv2"
3
4/* OPIE */
5#include <opie2/odebug.h>
6#include <opie2/oapplication.h>
7#include <opie2/ofilenotify.h>
8using namespace Opie::Core;
9
10/* QT */
11#include <qpushbutton.h>
12#include <qtextstream.h>
13
14class App : public OApplication
15{
16
17public:
18OFile* tmpfoo;
19
20App( int argc, char** argv ) : OApplication( argc, argv, "libopie2 notify test" )
21{
22 odebug << "App()" << oendl;
23
24 tmpfoo = new OFile( "/tmp/foo" );
25 if ( tmpfoo->open( IO_ReadWrite ) )
26 {
27 QTextStream stream( tmpfoo );
28 stream << "This is my content";
29 }
30
31 QObject::connect( tmpfoo, SIGNAL(accessed(const QString&)), this, SLOT(quit()) );
32 QObject::connect( tmpfoo, SIGNAL(closed(const QString&,bool)), this, SLOT(quit()) );
33}
34
35~App()
36{
37 odebug << "~App()" << oendl;
38
39 delete tmpfoo;
40}
41
42};
43
44int main( int argc, char** argv )
45{
46 App* app = new App( argc, argv );
47 QPushButton* b = new QPushButton( "Click me to close", 0 );
48 QObject::connect( b, SIGNAL(clicked()), app, SLOT(quit()) );
49 b->resize( 200, 200 );
50 b->move( 150, 150 );
51 b->show();
52 app->setMainWidget( b );
53 app->exec();
54 delete app;
55
56 return 0;
57
58}
59
diff --git a/examples/opiecore/onotifytest/onotifytest.pro b/examples/opiecore/onotifytest/onotifytest.pro
new file mode 100644
index 0000000..4e0faec
--- a/dev/null
+++ b/examples/opiecore/onotifytest/onotifytest.pro
@@ -0,0 +1,16 @@
1TEMPLATE = app
2CONFIG = qt warn_on
3SOURCES = main.cpp
4INCLUDEPATH += $(OPIEDIR)/include
5DEPENDPATH += $(OPIEDIR)/include
6LIBS += -lopiecore2
7TARGET = onotifytest
8
9!contains( platform, x11 ) {
10 include( $(OPIEDIR)/include.pro )
11}
12
13contains( platform, x11 ) {
14 LIBS += -L$(OPIEDIR)/lib -Wl,-rpath,$(OPIEDIR)/lib
15}
16
diff --git a/examples/opiecore/opiecore.pro b/examples/opiecore/opiecore.pro
index 1f86a40..3550055 100644
--- a/examples/opiecore/opiecore.pro
+++ b/examples/opiecore/opiecore.pro
@@ -1,2 +1,2 @@
1TEMPLATE = subdirs 1TEMPLATE = subdirs
2unix:SUBDIRS = odebugdemo oconfigdemo oglobalsettingsdemo onotifydemo oprocessdemo oplugins oinputsystemdemo 2unix:SUBDIRS = odebugdemo oconfigdemo oglobalsettingsdemo onotifydemo onotifytest oprocessdemo oplugins oinputsystemdemo
diff --git a/libopie2/opiecore/ofilenotify.cpp b/libopie2/opiecore/ofilenotify.cpp
index 4264327..36ec6bf 100644
--- a/libopie2/opiecore/ofilenotify.cpp
+++ b/libopie2/opiecore/ofilenotify.cpp
@@ -1,318 +1,374 @@
1/* 1/*
2� � � � � � � � This file is part of the Opie Project 2� � � � � � � � This file is part of the Opie Project
3 =. Copyright (C) 2004-2005 Michael 'Mickey' Lauer <mickey@Vanille.de> 3 =. Copyright (C) 2004-2005 Michael 'Mickey' Lauer <mickey@Vanille.de>
4 .=l. Copyright (C) The Opie Team <opie-devel@handhelds.org> 4 .=l. Copyright (C) The Opie Team <opie-devel@handhelds.org>
5 � � � � �.>+-= 5 � � � � �.>+-=
6_;:, � � .> � �:=|. This program is free software; you can 6_;:, � � .> � �:=|. This program is free software; you can
7.> <`_, � > �. � <= redistribute it and/or modify it under 7.> <`_, � > �. � <= redistribute it and/or modify it under
8:`=1 )Y*s>-.-- � : the terms of the GNU Library General Public 8:`=1 )Y*s>-.-- � : the terms of the GNU Library General Public
9.="- .-=="i, � � .._ License as published by the Free Software 9.="- .-=="i, � � .._ License as published by the Free Software
10- . � .-<_> � � .<> Foundation; version 2 of the License. 10- . � .-<_> � � .<> Foundation; version 2 of the License.
11 � �._= =} � � � : 11 � �._= =} � � � :
12 � .%`+i> � � � _;_. 12 � .%`+i> � � � _;_.
13 � .i_,=:_. � � �-<s. This program is distributed in the hope that 13 � .i_,=:_. � � �-<s. This program is distributed in the hope that
14 � �+ �. �-:. � � � = it will be useful, but WITHOUT ANY WARRANTY; 14 � �+ �. �-:. � � � = it will be useful, but WITHOUT ANY WARRANTY;
15 � : .. � �.:, � � . . . without even the implied warranty of 15 � : .. � �.:, � � . . . without even the implied warranty of
16 � =_ � � � �+ � � =;=|` MERCHANTABILITY or FITNESS FOR A 16 � =_ � � � �+ � � =;=|` MERCHANTABILITY or FITNESS FOR A
17 _.=:. � � � : � �:=>`: PARTICULAR PURPOSE. See the GNU 17 _.=:. � � � : � �:=>`: PARTICULAR PURPOSE. See the GNU
18..}^=.= � � � = � � � ; Library General Public License for more 18..}^=.= � � � = � � � ; Library General Public License for more
19++= � -. � � .` � � .: details. 19++= � -. � � .` � � .: details.
20: � � = �...= . :.=- 20: � � = �...= . :.=-
21-. � .:....=;==+<; You should have received a copy of the GNU 21-. � .:....=;==+<; You should have received a copy of the GNU
22 -_. . . � )=. �= Library General Public License along with 22 -_. . . � )=. �= Library General Public License along with
23 � -- � � � �:-=` this library; see the file COPYING.LIB. 23 � -- � � � �:-=` this library; see the file COPYING.LIB.
24 If not, write to the Free Software Foundation, 24 If not, write to the Free Software Foundation,
25 Inc., 59 Temple Place - Suite 330, 25 Inc., 59 Temple Place - Suite 330,
26 Boston, MA 02111-1307, USA. 26 Boston, MA 02111-1307, USA.
27*/ 27*/
28 28
29#include "ofilenotify.h" 29#include "ofilenotify.h"
30using namespace Opie::Core; 30using namespace Opie::Core;
31 31
32/* OPIE */ 32/* OPIE */
33 33
34/* QT */ 34/* QT */
35#include <qobject.h> 35#include <qobject.h>
36#include <qsocketnotifier.h> 36#include <qsocketnotifier.h>
37#include <qsignal.h> 37#include <qsignal.h>
38#include <qintdict.h> 38#include <qintdict.h>
39#include <qdir.h> 39#include <qdir.h>
40 40
41/* STD */ 41/* STD */
42#include <sys/types.h> 42#include <sys/types.h>
43#include <sys/stat.h> 43#include <sys/stat.h>
44#include <sys/ioctl.h> 44#include <sys/ioctl.h>
45#include <fcntl.h> 45#include <fcntl.h>
46#include <assert.h> 46#include <assert.h>
47#include <string.h> 47#include <string.h>
48#include <errno.h> 48#include <errno.h>
49#include <unistd.h> 49#include <unistd.h>
50 50
51static QIntDict<OFileNotification> notification_list; 51static QIntDict<OFileNotification> notification_list;
52 52
53QSocketNotifier* OFileNotification::_sn; 53QSocketNotifier* OFileNotification::_sn;
54int OFileNotification::_fd = -1; 54int OFileNotification::_fd = -1;
55 55
56#define INOTIFY_DEVICE "/dev/inotify" 56#define INOTIFY_DEVICE "/dev/inotify"
57 57
58namespace Opie { 58namespace Opie {
59namespace Core { 59namespace Core {
60 60
61//================================================================================================= 61//=================================================================================================
62// OFile
63//=================================================================================================
64
65OFile::OFile() : QObject( 0, 0 ), QFile()
66{
67 qDebug( "OFile()" );
68}
69
70OFile::OFile( const QString& name ) : QObject( 0, 0 ), QFile( name )
71{
72 qDebug( "OFile()" );
73}
74
75OFile::~OFile()
76{
77 qDebug( "~OFile()" );
78}
79
80void OFile::connectNotify( const char *signal )
81{
82 QString s = normalizeSignalSlot( signal+1 );
83 qDebug( "OFile::connectNotify() signal = '%s'", (const char*) s );
84
85 if ( s.startsWith( "accessed" ) )
86
87
88
89
90
91
92
93 QObject::connectNotify( signal );
94
95/*
96 void accessed( const QString& );
97 void modified( const QString& );
98 void attributed( const QString& );
99 void closed( const QString&, bool );
100 void opened( const QString& );
101 void deleted( const QString& );
102 void unmounted( const QString& );
103*/
104
105}
106
107void OFile::disconnectNotify( const char* signal )
108{
109 qDebug( "OFile::disconnectNotify() signal = '%s'", signal );
110 QObject::disconnectNotify( signal );
111}
112
113int OFile::startWatch( int mode )
114{
115}
116
117//=================================================================================================
62// OFileNotificationEvent 118// OFileNotificationEvent
63//================================================================================================= 119//=================================================================================================
64OFileNotificationEvent::OFileNotificationEvent( OFileNotification* parent, int wd, unsigned int mask, unsigned int cookie, const QString& name ) 120OFileNotificationEvent::OFileNotificationEvent( OFileNotification* parent, int wd, unsigned int mask, unsigned int cookie, const QString& name )
65 :_parent( parent ), _wd( wd ), _mask( mask ), _cookie( cookie ), _name( name ) 121 :_parent( parent ), _wd( wd ), _mask( mask ), _cookie( cookie ), _name( name )
66{ 122{
67 qDebug( "OFileNotificationEvent()" ); 123 qDebug( "OFileNotificationEvent()" );
68} 124}
69 125
70 126
71OFileNotificationEvent::~OFileNotificationEvent() 127OFileNotificationEvent::~OFileNotificationEvent()
72{ 128{
73 qDebug( "~OFileNotificationEvent()" ); 129 qDebug( "~OFileNotificationEvent()" );
74} 130}
75 131
76//================================================================================================= 132//=================================================================================================
77// OFileNotification 133// OFileNotification
78//================================================================================================= 134//=================================================================================================
79OFileNotification::OFileNotification( QObject* parent, const char* name ) 135OFileNotification::OFileNotification( QObject* parent, const char* name )
80 :QObject( parent, name ), _active( false ), _multi( true ) 136 :QObject( parent, name ), _active( false ), _multi( true )
81{ 137{
82 qDebug( "OFileNotification::OFileNotification()" ); 138 qDebug( "OFileNotification::OFileNotification()" );
83} 139}
84 140
85 141
86OFileNotification::~OFileNotification() 142OFileNotification::~OFileNotification()
87{ 143{
88 stop(); 144 stop();
89 qDebug( "OFileNotification::~OFileNotification()" ); 145 qDebug( "OFileNotification::~OFileNotification()" );
90} 146}
91 147
92 148
93bool OFileNotification::isActive() const 149bool OFileNotification::isActive() const
94{ 150{
95 return _active; 151 return _active;
96} 152}
97 153
98 154
99int OFileNotification::watch( const QString& path, bool sshot, OFileNotificationType type ) 155int OFileNotification::watch( const QString& path, bool sshot, OFileNotificationType type )
100{ 156{
101 // check if path exists and is a regular file 157 // check if path exists and is a regular file
102 struct stat s; 158 struct stat s;
103 if ( ::stat( (const char*) path, &s ) == -1 ) 159 if ( ::stat( (const char*) path, &s ) == -1 )
104 { 160 {
105 qWarning( "OFileNotification::watch(): Can't watch '%s': %s.", (const char*) path, strerror( errno ) ); 161 qWarning( "OFileNotification::watch(): Can't watch '%s': %s.", (const char*) path, strerror( errno ) );
106 return -1; 162 return -1;
107 } 163 }
108 if ( !S_ISREG( s.st_mode ) ) 164 if ( !S_ISREG( s.st_mode ) )
109 { 165 {
110 qWarning( "OFileNotification::watch(): Can't watch '%s': %s.", (const char*) path, "not a regular file" ); 166 qWarning( "OFileNotification::watch(): Can't watch '%s': %s.", (const char*) path, "not a regular file" );
111 return -1; 167 return -1;
112 } 168 }
113 169
114 return startWatching( path, sshot, type ); 170 return startWatching( path, sshot, type );
115} 171}
116 172
117 173
118int OFileNotification::startWatching( const QString& path, bool sshot, OFileNotificationType type ) 174int OFileNotification::startWatching( const QString& path, bool sshot, OFileNotificationType type )
119{ 175{
120 if ( notification_list.isEmpty() ) 176 if ( notification_list.isEmpty() )
121 { 177 {
122 OFileNotification::registerEventHandler(); 178 OFileNotification::registerEventHandler();
123 } 179 }
124 180
125 struct inotify_watch_request iwr; 181 struct inotify_watch_request iwr;
126 ::memset( &iwr, 0, sizeof iwr ); 182 ::memset( &iwr, 0, sizeof iwr );
127 iwr.name = const_cast<char*>( (const char*) path ); 183 iwr.name = const_cast<char*>( (const char*) path );
128 iwr.mask = type; 184 iwr.mask = type;
129 185
130 _wd = ::ioctl( OFileNotification::_fd, INOTIFY_WATCH, &iwr ); 186 _wd = ::ioctl( OFileNotification::_fd, INOTIFY_WATCH, &iwr );
131 187
132 if ( _wd < 0 ) 188 if ( _wd < 0 )
133 { 189 {
134 qWarning( "OFileNotification::watch(): inotify can't watch '%s': %s.", (const char*) path, strerror( errno ) ); 190 qWarning( "OFileNotification::watch(): inotify can't watch '%s': %s.", (const char*) path, strerror( errno ) );
135 return -1; 191 return -1;
136 } 192 }
137 193
138 notification_list.insert( _wd, this ); 194 notification_list.insert( _wd, this );
139 _path = path; 195 _path = path;
140 _multi = !sshot; 196 _multi = !sshot;
141 _type = type; 197 _type = type;
142 _active = true; 198 _active = true;
143 qDebug( "OFileNotification::watch(): watching '%s' [wd=%d].", (const char*) path, _wd ); 199 qDebug( "OFileNotification::watch(): watching '%s' [wd=%d].", (const char*) path, _wd );
144 return _wd; 200 return _wd;
145} 201}
146 202
147 203
148void OFileNotification::stop() 204void OFileNotification::stop()
149{ 205{
150 notification_list.remove( _wd ); 206 notification_list.remove( _wd );
151 _path = QString::null; 207 _path = QString::null;
152 _wd = 0; 208 _wd = 0;
153 _active = false; 209 _active = false;
154 if ( notification_list.isEmpty() ) 210 if ( notification_list.isEmpty() )
155 { 211 {
156 OFileNotification::unregisterEventHandler(); 212 OFileNotification::unregisterEventHandler();
157 } 213 }
158} 214}
159 215
160 216
161OFileNotificationType OFileNotification::type() const 217OFileNotificationType OFileNotification::type() const
162{ 218{
163 return _type; 219 return _type;
164} 220}
165 221
166 222
167QString OFileNotification::path() const 223QString OFileNotification::path() const
168{ 224{
169 return _path; 225 return _path;
170} 226}
171 227
172 228
173bool OFileNotification::activate( const OFileNotificationEvent* e ) 229bool OFileNotification::activate( const OFileNotificationEvent* e )
174{ 230{
175 qDebug( "OFileNotification::activate(): e = ( %s, %d, 0x%08x, %d, %s )", (const char*) _path, e->descriptor(), e->mask(), e->cookie(), (const char*) e->name() ); 231 qDebug( "OFileNotification::activate(): e = ( %s, %d, 0x%08x, %d, %s )", (const char*) _path, e->descriptor(), e->mask(), e->cookie(), (const char*) e->name() );
176 232
177 // dumb signal 233 // dumb signal
178 _signal.activate(); 234 _signal.activate();
179 235
180 // generic signal 236 // generic signal
181 emit triggered( _path, e->mask(), e->name() ); 237 emit triggered( _path, e->mask(), e->name() );
182 238
183 // specialized signals 239 // specialized signals
184 switch ( e->mask() ) 240 switch ( e->mask() )
185 { 241 {
186 case Access: emit accessed( _path ); break; 242 case Access: emit accessed( _path ); break;
187 case Modify: emit modified( _path ); break; 243 case Modify: emit modified( _path ); break;
188 case Attrib: emit attributed( _path); break; 244 case Attrib: emit attributed( _path); break;
189 case CloseWrite: emit closed( _path, true ); break; 245 case CloseWrite: emit closed( _path, true ); break;
190 case CloseNoWrite: emit closed( _path, false ); break; 246 case CloseNoWrite: emit closed( _path, false ); break;
191 case Open: emit opened( _path ); break; 247 case Open: emit opened( _path ); break;
192 case MovedFrom: emit movedFrom( _path, e->name() ); break; 248 case MovedFrom: emit movedFrom( _path, e->name() ); break;
193 case MovedTo: emit movedTo( _path, e->name() ); break; 249 case MovedTo: emit movedTo( _path, e->name() ); break;
194 case DeleteSubdir: emit deletedSubdir( _path, e->name() ); break; 250 case DeleteSubdir: emit deletedSubdir( _path, e->name() ); break;
195 case DeleteFile: emit deletedFile( _path, e->name() ); break; 251 case DeleteFile: emit deletedFile( _path, e->name() ); break;
196 case CreateSubdir: emit createdSubdir( _path, e->name() ); break; 252 case CreateSubdir: emit createdSubdir( _path, e->name() ); break;
197 case CreateFile: emit createdFile( _path, e->name() ); break; 253 case CreateFile: emit createdFile( _path, e->name() ); break;
198 case DeleteSelf: emit deleted( _path ); break; 254 case DeleteSelf: emit deleted( _path ); break;
199 case Unmount: emit unmounted( _path ); break; 255 case Unmount: emit unmounted( _path ); break;
200 default: assert( 0 ); 256 default: assert( 0 );
201 } 257 }
202 258
203 if ( !_multi ) stop(); 259 if ( !_multi ) stop();
204 260
205 return true; 261 return true;
206} 262}
207 263
208 264
209bool OFileNotification::singleShot( const QString& path, QObject* receiver, const char* member, OFileNotificationType type ) 265bool OFileNotification::singleShot( const QString& path, QObject* receiver, const char* member, OFileNotificationType type )
210{ 266{
211 OFileNotification* ofn = new OFileNotification(); 267 OFileNotification* ofn = new OFileNotification();
212 ofn->_signal.connect( receiver, member ); 268 ofn->_signal.connect( receiver, member );
213 return ofn->watch( path, true, type ) != -1; 269 return ofn->watch( path, true, type ) != -1;
214} 270}
215 271
216 272
217void OFileNotification::inotifyEventHandler() 273void OFileNotification::inotifyEventHandler()
218{ 274{
219 qDebug( "OFileNotification::inotifyEventHandler(): reached." ); 275 qDebug( "OFileNotification::inotifyEventHandler(): reached." );
220 276
221 char buffer[16384]; 277 char buffer[16384];
222 size_t buffer_i; 278 ssize_t buffer_i;
223 struct inotify_event *pevent, *event; 279 struct inotify_event *pevent, *event;
224 ssize_t r; 280 ssize_t r;
225 size_t event_size; 281 size_t event_size;
226 int count = 0; 282 int count = 0;
227 283
228 r = ::read(_fd, buffer, 16384); 284 r = ::read(_fd, buffer, 16384);
229 285
230 if ( r <= 0 ) 286 if ( r <= 0 )
231 return; 287 return;
232 288
233 buffer_i = 0; 289 buffer_i = 0;
234 while ( buffer_i < r ) 290 while ( buffer_i < r )
235 { 291 {
236 pevent = (struct inotify_event *)&buffer[buffer_i]; 292 pevent = (struct inotify_event *)&buffer[buffer_i];
237 event_size = sizeof(struct inotify_event) + pevent->len; 293 event_size = sizeof(struct inotify_event) + pevent->len;
238 OFileNotificationEvent* e = new OFileNotificationEvent( notification_list[ pevent->wd ], pevent->wd, pevent->mask, 294 OFileNotificationEvent* e = new OFileNotificationEvent( notification_list[ pevent->wd ], pevent->wd, pevent->mask,
239 pevent->cookie, pevent->len ? pevent->name : 0 ); 295 pevent->cookie, pevent->len ? pevent->name : 0 );
240 e->activate(); 296 e->activate();
241 buffer_i += event_size; 297 buffer_i += event_size;
242 count++; 298 count++;
243 } 299 }
244 300
245 qDebug( "OFileNotification::inotifyEventHandler(): processed %d events", count ); 301 qDebug( "OFileNotification::inotifyEventHandler(): processed %d events", count );
246} 302}
247 303
248 304
249bool OFileNotification::registerEventHandler() 305bool OFileNotification::registerEventHandler()
250{ 306{
251 OFileNotification::_fd = ::open( INOTIFY_DEVICE, O_RDONLY ); 307 OFileNotification::_fd = ::open( INOTIFY_DEVICE, O_RDONLY );
252 if ( OFileNotification::_fd < 0 ) 308 if ( OFileNotification::_fd < 0 )
253 { 309 {
254 qWarning( "OFileNotification::registerEventHandler(): couldn't register event handler: %s", strerror( errno ) ); 310 qWarning( "OFileNotification::registerEventHandler(): couldn't register event handler: %s", strerror( errno ) );
255 return false; 311 return false;
256 } 312 }
257 313
258 OFileNotification::_sn = new QSocketNotifier( _fd, QSocketNotifier::Read, this, "inotify event" ); 314 OFileNotification::_sn = new QSocketNotifier( _fd, QSocketNotifier::Read, this, "inotify event" );
259 connect( OFileNotification::_sn, SIGNAL( activated(int) ), this, SLOT( inotifyEventHandler() ) ); 315 connect( OFileNotification::_sn, SIGNAL( activated(int) ), this, SLOT( inotifyEventHandler() ) );
260 316
261 qDebug( "OFileNotification::registerEventHandler(): done" ); 317 qDebug( "OFileNotification::registerEventHandler(): done" );
262 return true; 318 return true;
263} 319}
264 320
265 321
266void OFileNotification::unregisterEventHandler() 322void OFileNotification::unregisterEventHandler()
267{ 323{
268 if ( _sn ) delete _sn; 324 if ( _sn ) delete _sn;
269 if ( OFileNotification::_fd ) 325 if ( OFileNotification::_fd )
270 ::close( OFileNotification::_fd ); 326 ::close( OFileNotification::_fd );
271 qDebug( "OFileNotification::unregisterEventHandler(): done" ); 327 qDebug( "OFileNotification::unregisterEventHandler(): done" );
272} 328}
273 329
274//================================================================================================= 330//=================================================================================================
275// ODirNotification 331// ODirNotification
276//================================================================================================= 332//=================================================================================================
277ODirNotification::ODirNotification( QObject* parent, const char* name ) 333ODirNotification::ODirNotification( QObject* parent, const char* name )
278 :QObject( parent, name ) 334 :QObject( parent, name )
279{ 335{
280 qDebug( "ODirNotification::ODirNotification()" ); 336 qDebug( "ODirNotification::ODirNotification()" );
281} 337}
282 338
283 339
284ODirNotification::~ODirNotification() 340ODirNotification::~ODirNotification()
285{ 341{
286 qDebug( "ODirNotification::~ODirNotification()" ); 342 qDebug( "ODirNotification::~ODirNotification()" );
287} 343}
288 344
289 345
290int ODirNotification::watch( const QString& path, bool sshot, OFileNotificationType type, int recurse ) 346int ODirNotification::watch( const QString& path, bool sshot, OFileNotificationType type, int recurse )
291{ 347{
292 qDebug( "ODirNotification::watch( %s, %d, 0x%08x, %d )", (const char*) path, sshot, type, recurse ); 348 qDebug( "ODirNotification::watch( %s, %d, 0x%08x, %d )", (const char*) path, sshot, type, recurse );
293 349
294 if ( recurse == 0 ) 350 if ( recurse == 0 )
295 { 351 {
296 OFileNotification* fn = new OFileNotification( this, "ODirNotification delegate" ); 352 OFileNotification* fn = new OFileNotification( this, "ODirNotification delegate" );
297 int result = fn->startWatching( path, sshot, type ); 353 int result = fn->startWatching( path, sshot, type );
298 if ( result != -1 ) 354 if ( result != -1 )
299 { 355 {
300 connect( fn, SIGNAL( triggered( const QString&, unsigned int, const QString& ) ), this, SIGNAL( triggered( const QString&, unsigned int, const QString& ) ) ); 356 connect( fn, SIGNAL( triggered( const QString&, unsigned int, const QString& ) ), this, SIGNAL( triggered( const QString&, unsigned int, const QString& ) ) );
301 connect( fn, SIGNAL( accessed( const QString& ) ), this, SIGNAL( accessed( const QString& ) ) ); 357 connect( fn, SIGNAL( accessed( const QString& ) ), this, SIGNAL( accessed( const QString& ) ) );
302 connect( fn, SIGNAL( modified( const QString& ) ), this, SIGNAL( modified( const QString& ) ) ); 358 connect( fn, SIGNAL( modified( const QString& ) ), this, SIGNAL( modified( const QString& ) ) );
303 connect( fn, SIGNAL( attributed( const QString& ) ), this, SIGNAL( attributed( const QString& ) ) ); 359 connect( fn, SIGNAL( attributed( const QString& ) ), this, SIGNAL( attributed( const QString& ) ) );
304 connect( fn, SIGNAL( closed( const QString&, bool ) ), this, SIGNAL( closed( const QString&, bool ) ) ); 360 connect( fn, SIGNAL( closed( const QString&, bool ) ), this, SIGNAL( closed( const QString&, bool ) ) );
305 connect( fn, SIGNAL( opened( const QString& ) ), this, SIGNAL( opened( const QString& ) ) ); 361 connect( fn, SIGNAL( opened( const QString& ) ), this, SIGNAL( opened( const QString& ) ) );
306 connect( fn, SIGNAL( movedTo( const QString&, const QString& ) ), this, SIGNAL( movedTo( const QString&, const QString& ) ) ); 362 connect( fn, SIGNAL( movedTo( const QString&, const QString& ) ), this, SIGNAL( movedTo( const QString&, const QString& ) ) );
307 connect( fn, SIGNAL( movedFrom( const QString&, const QString& ) ), this, SIGNAL( movedFrom( const QString&, const QString& ) ) ); 363 connect( fn, SIGNAL( movedFrom( const QString&, const QString& ) ), this, SIGNAL( movedFrom( const QString&, const QString& ) ) );
308 connect( fn, SIGNAL( deletedSubdir( const QString&, const QString& ) ), this, SIGNAL( deletedSubdir( const QString&, const QString& ) ) ); 364 connect( fn, SIGNAL( deletedSubdir( const QString&, const QString& ) ), this, SIGNAL( deletedSubdir( const QString&, const QString& ) ) );
309 connect( fn, SIGNAL( deletedFile( const QString&, const QString& ) ), this, SIGNAL( deletedFile( const QString&, const QString& ) ) );; 365 connect( fn, SIGNAL( deletedFile( const QString&, const QString& ) ), this, SIGNAL( deletedFile( const QString&, const QString& ) ) );;
310 connect( fn, SIGNAL( createdSubdir( const QString&, const QString& ) ), this, SIGNAL( createdSubdir( const QString&, const QString& ) ) ); 366 connect( fn, SIGNAL( createdSubdir( const QString&, const QString& ) ), this, SIGNAL( createdSubdir( const QString&, const QString& ) ) );
311 connect( fn, SIGNAL( createdFile( const QString&, const QString& ) ), this, SIGNAL( createdFile( const QString&, const QString& ) ) ); 367 connect( fn, SIGNAL( createdFile( const QString&, const QString& ) ), this, SIGNAL( createdFile( const QString&, const QString& ) ) );
312 connect( fn, SIGNAL( deleted( const QString& ) ), this, SIGNAL( deleted( const QString& ) ) ); 368 connect( fn, SIGNAL( deleted( const QString& ) ), this, SIGNAL( deleted( const QString& ) ) );
313 connect( fn, SIGNAL( unmounted( const QString& ) ), this, SIGNAL( unmounted( const QString& ) ) ); 369 connect( fn, SIGNAL( unmounted( const QString& ) ), this, SIGNAL( unmounted( const QString& ) ) );
314 } 370 }
315 return result; 371 return result;
316 } 372 }
317 else 373 else
318 { 374 {
diff --git a/libopie2/opiecore/ofilenotify.h b/libopie2/opiecore/ofilenotify.h
index 5bbf421..05343b9 100644
--- a/libopie2/opiecore/ofilenotify.h
+++ b/libopie2/opiecore/ofilenotify.h
@@ -1,140 +1,177 @@
1/* 1/*
2� � � � � � � � This file is part of the Opie Project 2� � � � � � � � This file is part of the Opie Project
3 =. Copyright (C) 2004-2005 Michael 'Mickey' Lauer <mickey@Vanille.de> 3 =. Copyright (C) 2004-2005 Michael 'Mickey' Lauer <mickey@Vanille.de>
4 .=l. Copyright (C) The Opie Team <opie-devel@handhelds.org> 4 .=l. Copyright (C) The Opie Team <opie-devel@handhelds.org>
5 � � � � �.>+-= 5 � � � � �.>+-=
6_;:, � � .> � �:=|. This program is free software; you can 6_;:, � � .> � �:=|. This program is free software; you can
7.> <`_, � > �. � <= redistribute it and/or modify it under 7.> <`_, � > �. � <= redistribute it and/or modify it under
8:`=1 )Y*s>-.-- � : the terms of the GNU Library General Public 8:`=1 )Y*s>-.-- � : the terms of the GNU Library General Public
9.="- .-=="i, � � .._ License as published by the Free Software 9.="- .-=="i, � � .._ License as published by the Free Software
10- . � .-<_> � � .<> Foundation; version 2 of the License. 10- . � .-<_> � � .<> Foundation; version 2 of the License.
11 � �._= =} � � � : 11 � �._= =} � � � :
12 � .%`+i> � � � _;_. 12 � .%`+i> � � � _;_.
13 � .i_,=:_. � � �-<s. This program is distributed in the hope that 13 � .i_,=:_. � � �-<s. This program is distributed in the hope that
14 � �+ �. �-:. � � � = it will be useful, but WITHOUT ANY WARRANTY; 14 � �+ �. �-:. � � � = it will be useful, but WITHOUT ANY WARRANTY;
15 � : .. � �.:, � � . . . without even the implied warranty of 15 � : .. � �.:, � � . . . without even the implied warranty of
16 � =_ � � � �+ � � =;=|` MERCHANTABILITY or FITNESS FOR A 16 � =_ � � � �+ � � =;=|` MERCHANTABILITY or FITNESS FOR A
17 _.=:. � � � : � �:=>`: PARTICULAR PURPOSE. See the GNU 17 _.=:. � � � : � �:=>`: PARTICULAR PURPOSE. See the GNU
18..}^=.= � � � = � � � ; Library General Public License for more 18..}^=.= � � � = � � � ; Library General Public License for more
19++= � -. � � .` � � .: details. 19++= � -. � � .` � � .: details.
20: � � = �...= . :.=- 20: � � = �...= . :.=-
21-. � .:....=;==+<; You should have received a copy of the GNU 21-. � .:....=;==+<; You should have received a copy of the GNU
22 -_. . . � )=. �= Library General Public License along with 22 -_. . . � )=. �= Library General Public License along with
23 � -- � � � �:-=` this library; see the file COPYING.LIB. 23 � -- � � � �:-=` this library; see the file COPYING.LIB.
24 If not, write to the Free Software Foundation, 24 If not, write to the Free Software Foundation,
25 Inc., 59 Temple Place - Suite 330, 25 Inc., 59 Temple Place - Suite 330,
26 Boston, MA 02111-1307, USA. 26 Boston, MA 02111-1307, USA.
27*/ 27*/
28 28
29#ifndef OFILENOTIFY_H 29#ifndef OFILENOTIFY_H
30#define OFILENOTIFY_H 30#define OFILENOTIFY_H
31#if defined (__GNUC__) && (__GNUC__ < 3) 31#if defined (__GNUC__) && (__GNUC__ < 3)
32#define _GNU_SOURCE 32#define _GNU_SOURCE
33#endif 33#endif
34 34
35#include "linux_inotify.h" 35#include "linux_inotify.h"
36 36
37/* QT */ 37/* QT */
38#include <qsocketnotifier.h> 38#include <qsocketnotifier.h>
39#include <qsignal.h> 39#include <qsignal.h>
40#include <qstring.h> 40#include <qstring.h>
41#include <qobject.h>
42#include <qfile.h>
41 43
42namespace Opie { 44namespace Opie {
43namespace Core { 45namespace Core {
44 46
47class OFile : public QObject, public QFile
48{
49 Q_OBJECT
50
51 public:
52 OFile();
53 OFile( const QString & name );
54 virtual ~OFile();
55
56 protected:
57 virtual void connectNotify( const char* signal );
58 virtual void disconnectNotify( const char* signal );
59
60 private:
61 int startWatch( int mode );
62
63 signals:
64 void accessed( const QString& );
65 void modified( const QString& );
66 void attributed( const QString& );
67 void closed( const QString&, bool );
68 void opened( const QString& );
69 void deleted( const QString& );
70 void unmounted( const QString& );
71};
72
73/*
74 void movedTo( const QString&, const QString& );
75 void movedFrom( const QString&, const QString& );
76 void deletedSubdir( const QString&, const QString& );
77 void deletedFile( const QString&, const QString& );
78 void createdSubdir( const QString&, const QString& );
79 void createdFile( const QString&, const QString& );
80*/
81
45class OFileNotificationEvent; 82class OFileNotificationEvent;
46 83
47/*====================================================================================== 84/*======================================================================================
48 * OFileNotificationType 85 * OFileNotificationType
49 *======================================================================================*/ 86 *======================================================================================*/
50 87
51/** 88/**
52 * @brief An enumerate for the different types of file notifications 89 * @brief An enumerate for the different types of file notifications
53 * 90 *
54 * This enumerate provides a means to specify the type of events that you are interest in. 91 * This enumerate provides a means to specify the type of events that you are interest in.
55 * Valid values are: 92 * Valid values are:
56 * <ul> 93 * <ul>
57 * <li>Access: The file was accessed (read) 94 * <li>Access: The file was accessed (read)
58 * <li>Modify The file was modified (write,truncate) 95 * <li>Modify The file was modified (write,truncate)
59 * <li>Attrib = The file had its attributes changed (chmod,chown,chgrp) 96 * <li>Attrib = The file had its attributes changed (chmod,chown,chgrp)
60 * <li>CloseWrite = Writable file was closed 97 * <li>CloseWrite = Writable file was closed
61 * <li>CloseNoWrite = Unwritable file was closed 98 * <li>CloseNoWrite = Unwritable file was closed
62 * <li>Open = File was opened 99 * <li>Open = File was opened
63 * <li>MovedFrom = File was moved from X 100 * <li>MovedFrom = File was moved from X
64 * <li>MovedTo = File was moved to Y 101 * <li>MovedTo = File was moved to Y
65 * <li>DeleteSubdir = Subdir was deleted 102 * <li>DeleteSubdir = Subdir was deleted
66 * <li>DeleteFile = Subfile was deleted 103 * <li>DeleteFile = Subfile was deleted
67 * <li>CreateSubdir = Subdir was created 104 * <li>CreateSubdir = Subdir was created
68 * <li>CreateFile = Subfile was created 105 * <li>CreateFile = Subfile was created
69 * <li>DeleteSelf = Self was deleted 106 * <li>DeleteSelf = Self was deleted
70 * <li>Unmount = The backing filesystem was unmounted 107 * <li>Unmount = The backing filesystem was unmounted
71 * </ul> 108 * </ul>
72 * 109 *
73 **/ 110 **/
74 111
75enum OFileNotificationType 112enum OFileNotificationType
76{ 113{
77 Access = IN_ACCESS, 114 Access = IN_ACCESS,
78 Modify = IN_MODIFY, 115 Modify = IN_MODIFY,
79 Attrib = IN_ATTRIB, 116 Attrib = IN_ATTRIB,
80 CloseWrite = IN_CLOSE_WRITE, 117 CloseWrite = IN_CLOSE_WRITE,
81 CloseNoWrite = IN_CLOSE_NOWRITE, 118 CloseNoWrite = IN_CLOSE_NOWRITE,
82 Open = IN_OPEN, 119 Open = IN_OPEN,
83 MovedFrom = IN_MOVED_FROM, 120 MovedFrom = IN_MOVED_FROM,
84 MovedTo = IN_MOVED_TO, 121 MovedTo = IN_MOVED_TO,
85 DeleteSubdir = IN_DELETE_SUBDIR, 122 DeleteSubdir = IN_DELETE_SUBDIR,
86 DeleteFile = IN_DELETE_FILE, 123 DeleteFile = IN_DELETE_FILE,
87 CreateSubdir = IN_CREATE_SUBDIR, 124 CreateSubdir = IN_CREATE_SUBDIR,
88 CreateFile = IN_CREATE_FILE, 125 CreateFile = IN_CREATE_FILE,
89 DeleteSelf = IN_DELETE_SELF, 126 DeleteSelf = IN_DELETE_SELF,
90 Unmount = IN_UNMOUNT, 127 Unmount = IN_UNMOUNT,
91 _QueueOverflow = IN_Q_OVERFLOW, /* Internal, don't use this in client code */ 128 _QueueOverflow = IN_Q_OVERFLOW, /* Internal, don't use this in client code */
92 _Ignored = IN_IGNORED, /* Internal, don't use this in client code */ 129 _Ignored = IN_IGNORED, /* Internal, don't use this in client code */
93}; 130};
94 131
95/*====================================================================================== 132/*======================================================================================
96 * OFileNotification 133 * OFileNotification
97 *======================================================================================*/ 134 *======================================================================================*/
98 135
99/** 136/**
100 * @brief Represents a file notification 137 * @brief Represents a file notification
101 * 138 *
102 * This class allows to watch for events happening to files. 139 * This class allows to watch for events happening to files.
103 * It uses the inotify linux (2.6.x) kernel interface. 140 * It uses the inotify linux (2.6.x) kernel interface.
104 * 141 *
105 * @see http://www.kernel.org/pub/linux/kernel/people/rml/inotify/ 142 * @see http://www.kernel.org/pub/linux/kernel/people/rml/inotify/
106 * 143 *
107 * @author Michael 'Mickey' Lauer <mickey@vanille.de> 144 * @author Michael 'Mickey' Lauer <mickey@vanille.de>
108 * 145 *
109 **/ 146 **/
110 147
111class OFileNotification : public QObject 148class OFileNotification : public QObject
112{ 149{
113 Q_OBJECT 150 Q_OBJECT
114 151
115 public: 152 public:
116 OFileNotification( QObject* parent = 0, const char* name = 0 ); 153 OFileNotification( QObject* parent = 0, const char* name = 0 );
117 ~OFileNotification(); 154 ~OFileNotification();
118 /** 155 /**
119 * This static function calls a slot when an event with @a type happens to file @a path. 156 * This static function calls a slot when an event with @a type happens to file @a path.
120 * 157 *
121 * It is very convenient to use this function because you do not need to 158 * It is very convenient to use this function because you do not need to
122 * bother with a timerEvent or to create a local QTimer object. 159 * bother with a timerEvent or to create a local QTimer object.
123 * 160 *
124 * Example: 161 * Example:
125 * <pre> 162 * <pre>
126 * 163 *
127 * #include <opie2/oapplication.h> 164 * #include <opie2/oapplication.h>
128 * #include <opie2/ofilenotify.h> 165 * #include <opie2/ofilenotify.h>
129 * using namespace Opie::Core; 166 * using namespace Opie::Core;
130 * 167 *
131 * int main( int argc, char **argv ) 168 * int main( int argc, char **argv )
132 * { 169 * {
133 * OApplication a( argc, argv, "File Notification Example" ); 170 * OApplication a( argc, argv, "File Notification Example" );
134 * OFileNotification::singleShot( "/tmp/quit", &a, SLOT(quit()), Access ); 171 * OFileNotification::singleShot( "/tmp/quit", &a, SLOT(quit()), Access );
135 * ... // create and show your widgets 172 * ... // create and show your widgets
136 * return a.exec(); 173 * return a.exec();
137 * } 174 * }
138 * </pre> 175 * </pre>
139 * 176 *
140 * This sample program automatically terminates when the file "/tmp/quit" has been accessed. 177 * This sample program automatically terminates when the file "/tmp/quit" has been accessed.