2 * Copyright 2007-2014 Haiku, Inc. All rights reserved.
3 * Distributed under the terms of the MIT License.
6 * Niels Sascha Reedijk, niels.reedijk@gmail.com
7 * John Scipione, jscipione@gmail.com
10 * headers/os/app/MessageFilter.h hrev47355
11 * src/kits/app/MessageFilter.cpp hrev47355
19 \brief Provides BMessageFilter class.
25 \brief Return Codes and Protocol of the #filter_hook.
27 These return codes should be used in your own filter_hook function, or by
28 your overridden BMessageFilter::Filter() method.
36 \brief The message does not pass the filter criteria and should not be
44 \var B_DISPATCH_MESSAGE
45 \brief The message passes the filter criteria and should be dispatched to
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
58 This hook can be used when you are constructing a new BMessageFilter
59 object. It is a custom filter function you can use.
61 This hook should handle the following parameters:
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.
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.
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)
83 \enum message_delivery
84 \brief BMessageFilter filter criteria on how a message was delivered.
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.
100 \brief Accept both delivery methods.
107 \var B_DROPPED_DELIVERY
108 \brief Only accept messages that were dropped by the user in the GUI.
115 \var B_PROGRAMMED_DELIVERY
116 \brief Only accept messages that were delivered using the
117 BLooper::PostMessage() method.
125 \brief BMessageFilter filter criteria on the source of a message.
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.
133 You use these constants in the constructors of the BMessageFilter class.
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.
145 \brief Accept both local and remote messages.
153 \brief Only accept messages from a remote source, so from other
162 \brief Only accept messages from your own local application.
169 \class BMessageFilter
172 \brief Describes a message filter for BLooper and BHandler.
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.
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.
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.
201 An example of a filter that selects on the default criteria:
203 // Our window does not handle drop events.
204 BMessageFilter *filter = new BMessageFilter(B_PROGRAMMED_DELIVERY, B_ANY_SOURCE);
205 window->AddCommonFilter(filter);
208 An example of a filter that only allows one type of message:
210 BMessageFilter *filter = new BMessageFilter(kHappyMessages);
211 handler->AddFilter(filter);
214 An example of a #filter_hook:
216 // The handler depends on the what code of a message
218 ScreenMessage(BMessage* message, BHandler** target, BMessageFilter* filter)
220 switch (message->what) {
222 target = &fTcpHandler;
223 return B_DISPATCH_MESSAGE;
225 target = &fUdpHandler;
226 return B_DISPATCH_MESSAGE;
229 return B_SKIP_MESSAGE;
232 BMessageFilter *filter = new BMessageFilter(B_ANY_DELIVERY, B_ANY_SOURCE, ScreenMessage);
233 looper->AddCommonFilter(filter);
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".
246 \fn BMessageFilter::BMessageFilter(uint32 inWhat, filter_hook func)
247 \brief Construct a new object that filters on a message constant.
249 You can also specify a #filter_hook, if you want apply custom filter
252 \see BMessageFilter(message_delivery, message_source, filter_hook)
253 \see BMessageFilter(message_delivery, message_source, uint32 what, filter_hook)
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
265 You can also specify a #filter_hook, if you want to apply custom filter
268 \see BMessageFilter(uint32 what,filter_hook)
269 \see BMessageFilter(message_delivery, message_source, uint32 what, filter_hook)
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.
281 You can also specify a #filter_hook, if you want to apply custom filter
284 \see BMessageFilter(uint32 what,filter_hook)
285 \see BMessageFilter(message_delivery, message_source, filter_hook)
292 \fn BMessageFilter::BMessageFilter(const BMessageFilter& filter)
293 \brief Copy constructor. Copy the criteria from another object.
300 \fn BMessageFilter::BMessageFilter(const BMessageFilter* filter)
301 \brief Create a new object based on criteria of another object.
308 \fn BMessageFilter::~BMessageFilter()
309 \brief Destructor. Does nothing.
316 \fn BMessageFilter& BMessageFilter::operator=(const BMessageFilter& from)
317 \brief Assignment operator. Copies criteria from another filter.
324 \fn filter_result BMessageFilter::Filter(BMessage* message,
326 \brief Filter the message according to custom criteria.
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.
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.
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.
345 \fn message_delivery BMessageFilter::MessageDelivery() const
346 \brief Return the message_delivery criterium of this filter.
353 \fn message_source BMessageFilter::MessageSource() const
354 \brief Return the message_source criterium of this filter.
361 \fn uint32 BMessageFilter::Command() const
362 \brief Return the accepted message constant.
364 This method returns zero (0) in case this filter does not filter based on
365 the message constant.
367 \see FiltersAnyCommand() const
374 \fn bool BMessageFilter::FiltersAnyCommand() const
375 \brief Return whether or not this filter has a message command criterium.
384 \fn BLooper* BMessageFilter::Looper() const
385 \brief Return the looper this filter is associated with.