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. 173BMessageFilter *filter = new BMessageFilter(B_PROGRAMMED_DELIVERY, B_ANY_SOURCE); 174window->AddCommonFilter(filter); 175\endcode 176 177 An example of a filter that only allows one type of message: 178\code 179BMessageFilter *filter = new BMessageFilter(kHappyMessages); 180handler->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 186filter_result 187ScreenMessage(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 201BMessageFilter *filter = new BMessageFilter(B_ANY_DELIVERY, B_ANY_SOURCE, ScreenMessage); 202looper->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 331