xref: /haiku/docs/user/app/MessageFilter.dox (revision 922e7ba1f3228e6f28db69b0ded8f86eb32dea17)
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