author | mickeyl <mickeyl> | 2004-04-18 18:25:24 (UTC) |
---|---|---|
committer | mickeyl <mickeyl> | 2004-04-18 18:25:24 (UTC) |
commit | df539f67050ebe61b5dc589f9c138bb9ef1719f6 (patch) (unidiff) | |
tree | 7baa2dc1e44be92dec2736b8205f9642fffc4302 | |
parent | 56f49e8293110e488f3ea6bc6dad282981c81d4b (diff) | |
download | opie-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
-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; | |||
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: | |||
87 | public slots: | 103 | public 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 | |||
54 | static QIntDict<OFileNotification> notification_list; | ||
45 | 55 | ||
@@ -48,34 +58,27 @@ namespace Core { | |||
48 | 58 | ||
49 | class OFileNotification | 59 | OFileNotification::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: | 66 | OFileNotification::~OFileNotification() |
71 | OFileNotificationType _type; | 67 | { |
72 | QSignal _signal; | 68 | qDebug( "OFileNotification::~OFileNotification()" ); |
73 | }; | 69 | } |
74 | 70 | ||
75 | 71 | ||
76 | static QIntDict<OFileNotification> notification_list; | 72 | bool OFileNotification::isActive() const |
73 | { | ||
74 | return _active; | ||
75 | } | ||
77 | 76 | ||
78 | 77 | ||
79 | void OFileNotifier::singleShot( const QString& path, QObject* receiver, const char* member, OFileNotificationType type ) | 78 | int 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 | ||
110 | void OFileNotifier::__signalHandler( int sig, siginfo_t *si, void *data ) | 119 | void 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 | |||
139 | OFileNotificationType OFileNotification::type() const | ||
140 | { | ||
141 | return _type; | ||
142 | } | ||
143 | |||
144 | |||
145 | QString OFileNotification::path() const | ||
146 | { | ||
147 | return _path; | ||
148 | } | ||
149 | |||
150 | int OFileNotification::fileno() const | ||
151 | { | ||
152 | return _fd; | ||
153 | } | ||
154 | |||
155 | void OFileNotification::activate() | ||
156 | { | ||
157 | emit triggered(); | ||
158 | _signal.activate(); | ||
159 | } | ||
160 | |||
161 | |||
162 | void 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 | |||
170 | void 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 | ||
137 | void OFileNotifier::registerSignalHandler() | 197 | bool 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 | ||
148 | void OFileNotifier::unregisterSignalHandler() | 212 | void 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 | ||
52 | class OFileNotifier : public QObject | 53 | class 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 | }; |