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