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