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