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