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 \brief Describes a message filter for BLooper and BHandler. 140 141 Objects of this class serve as a description of properties that incoming 142 messages should have in order to be processed by a handler or a looper. 143 BMessageFilter provides three default filter criteria, the \c what 144 constant, the #message_source and the type of message_delivery, 145 and an extendible #filter_hook. 146 147 BMessageFilter's standard filter criteria can be extended in two ways: 148 -# Specify a #filter_hook. This is a static function that takes a message 149 and a pointer to a BHandler as arguments, and allows you to accept or 150 reject the message, and even redirect it to a specific BHandler. 151 -# Subclass the BMessageFilter class and override the Filter() function. 152 This has the same capabilities as using a #filter_hook, but it allows 153 cleaner code (in some cases). 154 155 Both methods have their merits, but please remember that you have to choose 156 which one you want to use, since you can't use both. The order of 157 processing the criteria is in this order: the source, the delivery method, 158 the filter hook and then the overrided Filter() method. Additionally, if a 159 #filter_hook is registered, the Filter() method will not be called. 160 161 The BMessageFilter objects are used in two different classes. They can be 162 associated with specific BHandlers. Using the BHandler::AddFilter() 163 and the BHandler::SetFilterList() methods, you can add filters to the 164 filter list. It is also possible to associate filters with BLoopers. In 165 that case, all incoming messages of that looper are checked against the 166 criteria. To perform filtering in loopers, have a look at the 167 BLooper::AddCommonFilter() and the BLooper::SetCommonFilterList() methods. 168 169 An example of a filter that selects on the default criteria: 170\code 171// Our window does not handle drop events. 172BMessageFilter *filter = new BMessageFilter(B_PROGRAMMED_DELIVERY, B_ANY_SOURCE); 173window->AddCommonFilter(filter); 174\endcode 175 176 An example of a filter that only allows one type of message: 177\code 178BMessageFilter *filter = new BMessageFilter(kHappyMessages); 179handler->AddFilter(filter); 180\endcode 181 182 An example of a #filter_hook: 183\code 184// The handler depends on the what code of a message 185filter_result 186ScreenMessage(BMessage* message, BHandler** target, BMessageFilter* filter) 187{ 188 switch (message->what) { 189 case kTcpEvent: 190 target = &fTcpHandler; 191 return B_DISPATCH_MESSAGE; 192 case kUdpEvent: 193 target = &fUdpHandler; 194 return B_DISPATCH_MESSAGE; 195 } 196 197 return B_SKIP_MESSAGE; 198} 199 200BMessageFilter *filter = new BMessageFilter(B_ANY_DELIVERY, B_ANY_SOURCE, ScreenMessage); 201looper->AddCommonFilter(filter); 202\endcode 203 204 The two classes that use BMessageFilter are BLooper and BHandler. In the 205 general messaging introduction, there is also a section on 206 \ref app-messaging-receiving "handling messages". 207*/ 208 209 210 211/*! 212 \fn BMessageFilter::BMessageFilter(uint32 inWhat, filter_hook func) 213 \brief Construct a new object that filters on a message constant. 214 215 You can also specify a #filter_hook, if you want apply custom filter 216 criteria. 217 218 \see BMessageFilter(message_delivery, message_source, filter_hook) 219 \see BMessageFilter(message_delivery, message_source, uint32 what, filter_hook) 220*/ 221 222 223/*! 224 \fn BMessageFilter::BMessageFilter(message_delivery delivery, 225 message_source source, filter_hook func) 226 \brief Construct a new object that filters on delivery method and message 227 source. 228 229 You can also specify a #filter_hook, if you want to apply custom filter 230 criteria. 231 232 \see BMessageFilter(uint32 what,filter_hook) 233 \see BMessageFilter(message_delivery, message_source, uint32 what, filter_hook) 234*/ 235 236 237/*! 238 \fn BMessageFilter::BMessageFilter(message_delivery delivery, 239 message_source source, uint32 inWhat, filter_hook func) 240 \brief Construct a new object that filters on delivery method, message 241 source and specific message constants. 242 243 You can also specify a #filter_hook, if you want to apply custom filter 244 criteria. 245 246 \see BMessageFilter(uint32 what,filter_hook) 247 \see BMessageFilter(message_delivery, message_source, filter_hook) 248*/ 249 250 251/*! 252 \fn BMessageFilter::BMessageFilter(const BMessageFilter& filter) 253 \brief Copy constructor. Copy the criteria from another object. 254*/ 255 256 257/*! 258 \fn BMessageFilter::BMessageFilter(const BMessageFilter* filter) 259 \brief Create a new object based on criteria of another object. 260*/ 261 262 263/*! 264 \fn BMessageFilter::~BMessageFilter() 265 \brief Destructor. Does nothing. 266*/ 267 268 269/*! 270 \fn BMessageFilter &BMessageFilter::operator=(const BMessageFilter& from) 271 \brief Assignment operator. Copies criteria from another filter. 272*/ 273 274 275/*! 276 \fn filter_result BMessageFilter::Filter(BMessage* message, 277 BHandler** target) 278 \brief Filter the message according to custom criteria. 279 280 The default implementation of this method always returns 281 \c B_DISPATCH_MESSAGE. You can override this method in subclasses to 282 suit your own criteria. You receive two arguments. 283 284 \param message The message that needs to be filtered. 285 \param target If you want to, you can specify a handler that should handle 286 this message. Note that you do have to pass a handler that is 287 associated with the looper that received the message. 288 289 \return You should return \c B_DISPATCH_MESSAGE in case the message passes 290 the tests, or \c B_SKIP_MESSAGE in case the message does not pass. 291*/ 292 293 294/*! 295 \fn message_delivery BMessageFilter::MessageDelivery() const 296 \brief Return the message_delivery criterium of this filter. 297*/ 298 299 300/*! 301 \fn message_source BMessageFilter::MessageSource() const 302 \brief Return the message_source criterium of this filter. 303*/ 304 305 306/*! 307 \fn uint32 BMessageFilter::Command() const 308 \brief Return the accepted message constant. 309 310 This method returns zero (0) in case this filter does not filter based on 311 the message constant. 312 313 \see FiltersAnyCommand() const 314*/ 315 316 317/*! 318 \fn bool BMessageFilter::FiltersAnyCommand() const 319 \brief Return whether or not this filter has a message command criterium. 320 321 \see Command() const 322*/ 323 324 325/*! 326 \fn BLooper *BMessageFilter::Looper() const 327 \brief Return the looper this filter is associated with. 328*/ 329 330