| 1 |
/* |
|---|
| 2 |
* Copyright 2007, Haiku, Inc. All Rights Reserved. |
|---|
| 3 |
* Distributed under the terms of the MIT License. |
|---|
| 4 |
* |
|---|
| 5 |
* Authors: |
|---|
| 6 |
* Niels Sascha Reedijk, niels.reedijk@gmail.com |
|---|
| 7 |
*/ |
|---|
| 8 |
|
|---|
| 9 |
|
|---|
| 10 |
/*! |
|---|
| 11 |
\file MessageFilter.h |
|---|
| 12 |
\brief Provides BMessageFilter class. |
|---|
| 13 |
*/ |
|---|
| 14 |
|
|---|
| 15 |
|
|---|
| 16 |
/*! |
|---|
| 17 |
\enum filter_result |
|---|
| 18 |
\brief Return Codes and Protocol of the #filter_hook. |
|---|
| 19 |
|
|---|
| 20 |
These return codes should be used in your own filter_hook function, or by |
|---|
| 21 |
your overrided BMessageFilter::Filter() function. |
|---|
| 22 |
*/ |
|---|
| 23 |
|
|---|
| 24 |
|
|---|
| 25 |
/*! |
|---|
| 26 |
\var B_SKIP_MESSAGE |
|---|
| 27 |
\brief The message does not pass the filter criteria and should not be |
|---|
| 28 |
handled. |
|---|
| 29 |
*/ |
|---|
| 30 |
|
|---|
| 31 |
|
|---|
| 32 |
/*! |
|---|
| 33 |
\var B_DISPATCH_MESSAGE |
|---|
| 34 |
\brief The message passes the filter criteria and should be dispatched to |
|---|
| 35 |
a BHandler. |
|---|
| 36 |
*/ |
|---|
| 37 |
|
|---|
| 38 |
|
|---|
| 39 |
/*! |
|---|
| 40 |
\typedef filter_result (*filter_hook) (BMessage* message, |
|---|
| 41 |
BHandler** target, BMessageFilter* filter) |
|---|
| 42 |
\brief Prototype for a custom \c filter_hook for use in the BMessageFilter |
|---|
| 43 |
class. |
|---|
| 44 |
|
|---|
| 45 |
This hook can be used when you are constructing a new BMessageFilter |
|---|
| 46 |
object. It is a custom filter function you can use. |
|---|
| 47 |
|
|---|
| 48 |
This hook should handle the following parameters: |
|---|
| 49 |
|
|---|
| 50 |
\param[in] message The message that needs to be verified. |
|---|
| 51 |
\param[out] target If your filter hook is conscious about the available |
|---|
| 52 |
handlers, you can set a specific BHandler based on your filters |
|---|
| 53 |
requirements. You do not have to change this field, because there will |
|---|
| 54 |
always be a working default. |
|---|
| 55 |
\param[in] filter A pointer to the filter from which this hook is called. |
|---|
| 56 |
|
|---|
| 57 |
\return You should return #B_SKIP_MESSAGE in case the message does not |
|---|
| 58 |
conform to the filter criteria, or #B_DISPATCH_MESSAGE if the message |
|---|
| 59 |
passes these criteria. |
|---|
| 60 |
|
|---|
| 61 |
\see BMessageFilter(uint32, filter_hook) |
|---|
| 62 |
BMessageFilter(message_delivery, message_source, filter_hook) |
|---|
| 63 |
BMessageFilter(message_delivery, message_source, uint32, filter_hook) |
|---|
| 64 |
*/ |
|---|
| 65 |
|
|---|
| 66 |
|
|---|
| 67 |
/*! |
|---|
| 68 |
\enum message_delivery |
|---|
| 69 |
\brief BMessageFilter filter criteria on how a message was delivered. |
|---|
| 70 |
|
|---|
| 71 |
Two constructors of the BMessageFilter class allow you to specify that it |
|---|
| 72 |
should filter based on how the message was delivered. There are two ways in |
|---|
| 73 |
which messages can be delivered within the Haiku API: by direct delivery |
|---|
| 74 |
using the BLooper::PostMessage() function, and by drag and drop in the GUI. |
|---|
| 75 |
With this filter you can, for example, specify that your handler only |
|---|
| 76 |
handles deliveries that were programmed by you, and not any random drag and |
|---|
| 77 |
drop actions initiated by the user. |
|---|
| 78 |
*/ |
|---|
| 79 |
|
|---|
| 80 |
|
|---|
| 81 |
/*! |
|---|
| 82 |
\var B_ANY_DELIVERY |
|---|
| 83 |
\brief Accept both delivery methods. |
|---|
| 84 |
*/ |
|---|
| 85 |
|
|---|
| 86 |
|
|---|
| 87 |
/*! |
|---|
| 88 |
\var B_DROPPED_DELIVERY |
|---|
| 89 |
\brief Only accept messages that were dropped by the user in the GUI. |
|---|
| 90 |
*/ |
|---|
| 91 |
|
|---|
| 92 |
|
|---|
| 93 |
/*! |
|---|
| 94 |
\var B_PROGRAMMED_DELIVERY |
|---|
| 95 |
\brief Only accept messages that were delivered using the |
|---|
| 96 |
BLooper::PostMessage() method. |
|---|
| 97 |
*/ |
|---|
| 98 |
|
|---|
| 99 |
|
|---|
| 100 |
/*! |
|---|
| 101 |
\enum message_source |
|---|
| 102 |
\brief BMessageFilter filter criteria on the source of a message. |
|---|
| 103 |
|
|---|
| 104 |
One of the key features of the messaging system of Haiku, is the ability |
|---|
| 105 |
to send messages between applications. However, your handler or looper |
|---|
| 106 |
might have been written in such a way that it would make no sense to try |
|---|
| 107 |
to process messages from an external source. Use these filter criteria to |
|---|
| 108 |
filter the unwanted messages out. |
|---|
| 109 |
|
|---|
| 110 |
You use these constants in the constructors of the BMessageFilter class. |
|---|
| 111 |
|
|---|
| 112 |
\warning System messages, for example from the \c app_server, are |
|---|
| 113 |
considered remote messages. Keep this in mind when you want to set up |
|---|
| 114 |
criteria for your window and application loopers. |
|---|
| 115 |
*/ |
|---|
| 116 |
|
|---|
| 117 |
|
|---|
| 118 |
/*! |
|---|
| 119 |
\var B_ANY_SOURCE |
|---|
| 120 |
\brief Accept both local and remote messages. |
|---|
| 121 |
*/ |
|---|
| 122 |
|
|---|
| 123 |
|
|---|
| 124 |
/*! |
|---|
| 125 |
\var B_REMOTE_SOURCE |
|---|
| 126 |
\brief Only accept messages from a remote source, so from other |
|---|
| 127 |
applications. |
|---|
| 128 |
*/ |
|---|
| 129 |
|
|---|
| 130 |
|
|---|
| 131 |
/*! |
|---|
| 132 |
\var B_LOCAL_SOURCE |
|---|
| 133 |
\brief Only accept messages from your own local application. |
|---|
| 134 |
*/ |
|---|
| 135 |
|
|---|
| 136 |
|
|---|
| 137 |
/*! |
|---|
| 138 |
\class BMessageFilter |
|---|
| 139 |
\ingroup app |
|---|
| 140 |
\brief Describes a message filter for BLooper and BHandler. |
|---|
| 141 |
|
|---|
| 142 |
Objects of this class serve as a description of properties that incoming |
|---|
| 143 |
messages should have in order to be processed by a handler or a looper. |
|---|
| 144 |
BMessageFilter provides three default filter criteria, the \c what |
|---|
| 145 |
constant, the #message_source and the type of message_delivery, |
|---|
| 146 |
and an extendible #filter_hook. |
|---|
| 147 |
|
|---|
| 148 |
BMessageFilter's standard filter criteria can be extended in two ways: |
|---|
| 149 |
-# Specify a #filter_hook. This is a static function that takes a message |
|---|
| 150 |
and a pointer to a BHandler as arguments, and allows you to accept or |
|---|
| 151 |
reject the message, and even redirect it to a specific BHandler. |
|---|
| 152 |
-# Subclass the BMessageFilter class and override the Filter() function. |
|---|
| 153 |
This has the same capabilities as using a #filter_hook, but it allows |
|---|
| 154 |
cleaner code (in some cases). |
|---|
| 155 |
|
|---|
| 156 |
Both methods have their merits, but please remember that you have to choose |
|---|
| 157 |
which one you want to use, since you can't use both. The order of |
|---|
| 158 |
processing the criteria is in this order: the source, the delivery method, |
|---|
| 159 |
the filter hook and then the overrided Filter() method. Additionally, if a |
|---|
| 160 |
#filter_hook is registered, the Filter() method will not be called. |
|---|
| 161 |
|
|---|
| 162 |
The BMessageFilter objects are used in two different classes. They can be |
|---|
| 163 |
associated with specific BHandlers. Using the BHandler::AddFilter() |
|---|
| 164 |
and the BHandler::SetFilterList() methods, you can add filters to the |
|---|
| 165 |
filter list. It is also possible to associate filters with BLoopers. In |
|---|
| 166 |
that case, all incoming messages of that looper are checked against the |
|---|
| 167 |
criteria. To perform filtering in loopers, have a look at the |
|---|
| 168 |
BLooper::AddCommonFilter() and the BLooper::SetCommonFilterList() methods. |
|---|
| 169 |
|
|---|
| 170 |
An example of a filter that selects on the default criteria: |
|---|
| 171 |
\code |
|---|
| 172 |
// Our window does not handle drop events. |
|---|
| 173 |
BMessageFilter *filter = new BMessageFilter(B_PROGRAMMED_DELIVERY, B_ANY_SOURCE); |
|---|
| 174 |
window->AddCommonFilter(filter); |
|---|
| 175 |
\endcode |
|---|
| 176 |
|
|---|
| 177 |
An example of a filter that only allows one type of message: |
|---|
| 178 |
\code |
|---|
| 179 |
BMessageFilter *filter = new BMessageFilter(kHappyMessages); |
|---|
| 180 |
handler->AddFilter(filter); |
|---|
| 181 |
\endcode |
|---|
| 182 |
|
|---|
| 183 |
An example of a #filter_hook: |
|---|
| 184 |
\code |
|---|
| 185 |
// The handler depends on the what code of a message |
|---|
| 186 |
filter_result |
|---|
| 187 |
ScreenMessage(BMessage* message, BHandler** target, BMessageFilter* filter) |
|---|
| 188 |
{ |
|---|
| 189 |
switch (message->what) { |
|---|
| 190 |
case kTcpEvent: |
|---|
| 191 |
target = &fTcpHandler; |
|---|
| 192 |
return B_DISPATCH_MESSAGE; |
|---|
| 193 |
case kUdpEvent: |
|---|
| 194 |
target = &fUdpHandler; |
|---|
| 195 |
return B_DISPATCH_MESSAGE; |
|---|
| 196 |
} |
|---|
| 197 |
|
|---|
| 198 |
return B_SKIP_MESSAGE; |
|---|
| 199 |
} |
|---|
| 200 |
|
|---|
| 201 |
BMessageFilter *filter = new BMessageFilter(B_ANY_DELIVERY, B_ANY_SOURCE, ScreenMessage); |
|---|
| 202 |
looper->AddCommonFilter(filter); |
|---|
| 203 |
\endcode |
|---|
| 204 |
|
|---|
| 205 |
The two classes that use BMessageFilter are BLooper and BHandler. In the |
|---|
| 206 |
general messaging introduction, there is also a section on |
|---|
| 207 |
\ref app-messaging-receiving "handling messages". |
|---|
| 208 |
*/ |
|---|
| 209 |
|
|---|
| 210 |
|
|---|
| 211 |
|
|---|
| 212 |
/*! |
|---|
| 213 |
\fn BMessageFilter::BMessageFilter(uint32 inWhat, filter_hook func) |
|---|
| 214 |
\brief Construct a new object that filters on a message constant. |
|---|
| 215 |
|
|---|
| 216 |
You can also specify a #filter_hook, if you want apply custom filter |
|---|
| 217 |
criteria. |
|---|
| 218 |
|
|---|
| 219 |
\see BMessageFilter(message_delivery, message_source, filter_hook) |
|---|
| 220 |
\see BMessageFilter(message_delivery, message_source, uint32 what, filter_hook) |
|---|
| 221 |
*/ |
|---|
| 222 |
|
|---|
| 223 |
|
|---|
| 224 |
/*! |
|---|
| 225 |
\fn BMessageFilter::BMessageFilter(message_delivery delivery, |
|---|
| 226 |
message_source source, filter_hook func) |
|---|
| 227 |
\brief Construct a new object that filters on delivery method and message |
|---|
| 228 |
source. |
|---|
| 229 |
|
|---|
| 230 |
You can also specify a #filter_hook, if you want to apply custom filter |
|---|
| 231 |
criteria. |
|---|
| 232 |
|
|---|
| 233 |
\see BMessageFilter(uint32 what,filter_hook) |
|---|
| 234 |
\see BMessageFilter(message_delivery, message_source, uint32 what, filter_hook) |
|---|
| 235 |
*/ |
|---|
| 236 |
|
|---|
| 237 |
|
|---|
| 238 |
/*! |
|---|
| 239 |
\fn BMessageFilter::BMessageFilter(message_delivery delivery, |
|---|
| 240 |
message_source source, uint32 inWhat, filter_hook func) |
|---|
| 241 |
\brief Construct a new object that filters on delivery method, message |
|---|
| 242 |
source and specific message constants. |
|---|
| 243 |
|
|---|
| 244 |
You can also specify a #filter_hook, if you want to apply custom filter |
|---|
| 245 |
criteria. |
|---|
| 246 |
|
|---|
| 247 |
\see BMessageFilter(uint32 what,filter_hook) |
|---|
| 248 |
\see BMessageFilter(message_delivery, message_source, filter_hook) |
|---|
| 249 |
*/ |
|---|
| 250 |
|
|---|
| 251 |
|
|---|
| 252 |
/*! |
|---|
| 253 |
\fn BMessageFilter::BMessageFilter(const BMessageFilter& filter) |
|---|
| 254 |
\brief Copy constructor. Copy the criteria from another object. |
|---|
| 255 |
*/ |
|---|
| 256 |
|
|---|
| 257 |
|
|---|
| 258 |
/*! |
|---|
| 259 |
\fn BMessageFilter::BMessageFilter(const BMessageFilter* filter) |
|---|
| 260 |
\brief Create a new object based on criteria of another object. |
|---|
| 261 |
*/ |
|---|
| 262 |
|
|---|
| 263 |
|
|---|
| 264 |
/*! |
|---|
| 265 |
\fn BMessageFilter::~BMessageFilter() |
|---|
| 266 |
\brief Destructor. Does nothing. |
|---|
| 267 |
*/ |
|---|
| 268 |
|
|---|
| 269 |
|
|---|
| 270 |
/*! |
|---|
| 271 |
\fn BMessageFilter &BMessageFilter::operator=(const BMessageFilter& from) |
|---|
| 272 |
\brief Assignment operator. Copies criteria from another filter. |
|---|
| 273 |
*/ |
|---|
| 274 |
|
|---|
| 275 |
|
|---|
| 276 |
/*! |
|---|
| 277 |
\fn filter_result BMessageFilter::Filter(BMessage* message, |
|---|
| 278 |
BHandler** target) |
|---|
| 279 |
\brief Filter the message according to custom criteria. |
|---|
| 280 |
|
|---|
| 281 |
The default implementation of this method always returns |
|---|
| 282 |
\c B_DISPATCH_MESSAGE. You can override this method in subclasses to |
|---|
| 283 |
suit your own criteria. You receive two arguments. |
|---|
| 284 |
|
|---|
| 285 |
\param message The message that needs to be filtered. |
|---|
| 286 |
\param target If you want to, you can specify a handler that should handle |
|---|
| 287 |
this message. Note that you do have to pass a handler that is |
|---|
| 288 |
associated with the looper that received the message. |
|---|
| 289 |
|
|---|
| 290 |
\return You should return \c B_DISPATCH_MESSAGE in case the message passes |
|---|
| 291 |
the tests, or \c B_SKIP_MESSAGE in case the message does not pass. |
|---|
| 292 |
*/ |
|---|
| 293 |
|
|---|
| 294 |
|
|---|
| 295 |
/*! |
|---|
| 296 |
\fn message_delivery BMessageFilter::MessageDelivery() const |
|---|
| 297 |
\brief Return the message_delivery criterium of this filter. |
|---|
| 298 |
*/ |
|---|
| 299 |
|
|---|
| 300 |
|
|---|
| 301 |
/*! |
|---|
| 302 |
\fn message_source BMessageFilter::MessageSource() const |
|---|
| 303 |
\brief Return the message_source criterium of this filter. |
|---|
| 304 |
*/ |
|---|
| 305 |
|
|---|
| 306 |
|
|---|
| 307 |
/*! |
|---|
| 308 |
\fn uint32 BMessageFilter::Command() const |
|---|
| 309 |
\brief Return the accepted message constant. |
|---|
| 310 |
|
|---|
| 311 |
This method returns zero (0) in case this filter does not filter based on |
|---|
| 312 |
the message constant. |
|---|
| 313 |
|
|---|
| 314 |
\see FiltersAnyCommand() const |
|---|
| 315 |
*/ |
|---|
| 316 |
|
|---|
| 317 |
|
|---|
| 318 |
/*! |
|---|
| 319 |
\fn bool BMessageFilter::FiltersAnyCommand() const |
|---|
| 320 |
\brief Return whether or not this filter has a message command criterium. |
|---|
| 321 |
|
|---|
| 322 |
\see Command() const |
|---|
| 323 |
*/ |
|---|
| 324 |
|
|---|
| 325 |
|
|---|
| 326 |
/*! |
|---|
| 327 |
\fn BLooper *BMessageFilter::Looper() const |
|---|
| 328 |
\brief Return the looper this filter is associated with. |
|---|
| 329 |
*/ |
|---|
| 330 |
|
|---|