xref: /haiku/src/kits/media/Notifications.cpp (revision 3c08adef21129761f27ae654a1c5d1705786691a)
1 /*
2  * Copyright (c) 2002, 2003 Marcus Overhagen <Marcus@Overhagen.de>
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining
5  * a copy of this software and associated documentation files or portions
6  * thereof (the "Software"), to deal in the Software without restriction,
7  * including without limitation the rights to use, copy, modify, merge,
8  * publish, distribute, sublicense, and/or sell copies of the Software,
9  * and to permit persons to whom the Software is furnished to do so, subject
10  * to the following conditions:
11  *
12  *  * Redistributions of source code must retain the above copyright notice,
13  *    this list of conditions and the following disclaimer.
14  *
15  *  * Redistributions in binary form must reproduce the above copyright notice
16  *    in the  binary, as well as this list of conditions and the following
17  *    disclaimer in the documentation and/or other materials provided with
18  *    the distribution.
19  *
20  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
21  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
23  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
26  * THE SOFTWARE.
27  */
28 
29 
30 /*!	This is a interface class for media kit notifications.
31 	It is private to the media kit which uses it to pass notifications up to
32 	the media_server which will broadcast them.
33 */
34 
35 // TODO: The BeBook, MediaDefs.h and the BeOS R5 do list
36 // different strings for the message data fields of
37 // the notification messages.
38 
39 
40 #include "Notifications.h"
41 
42 #include <Messenger.h>
43 #include <MediaNode.h>
44 
45 #include <AppMisc.h>
46 
47 #include "debug.h"
48 #include "DataExchange.h"
49 
50 
51 namespace BPrivate {
52 namespace media {
53 namespace notifications {
54 
55 
56 status_t
57 Register(const BMessenger& notifyHandler, const media_node& node,
58 	int32 notification)
59 {
60 	CALLED();
61 
62 	if (notification == B_MEDIA_SERVER_STARTED
63 		|| notification == B_MEDIA_SERVER_QUIT) {
64 		BMessage msg(MEDIA_ROSTER_REQUEST_NOTIFICATIONS);
65 		msg.AddInt32(NOTIFICATION_PARAM_WHAT, notification);
66 		msg.AddMessenger(NOTIFICATION_PARAM_MESSENGER, notifyHandler);
67 		return BPrivate::media::dataexchange::SendToRoster(&msg);
68 	}
69 
70 	BMessage msg(MEDIA_SERVER_REQUEST_NOTIFICATIONS);
71 	msg.AddInt32(NOTIFICATION_PARAM_WHAT, notification);
72 	msg.AddInt32(NOTIFICATION_PARAM_TEAM, BPrivate::current_team());
73 	msg.AddMessenger(NOTIFICATION_PARAM_MESSENGER, notifyHandler);
74 	msg.AddData("node", B_RAW_TYPE, &node, sizeof(node));
75 
76 	return BPrivate::media::dataexchange::SendToServer(&msg);
77 }
78 
79 
80 status_t
81 Unregister(const BMessenger& notifyHandler, const media_node& node,
82 	int32 notification)
83 {
84 	CALLED();
85 
86 	if (notification == B_MEDIA_SERVER_STARTED
87 		|| notification == B_MEDIA_SERVER_QUIT) {
88 		BMessage msg(MEDIA_ROSTER_CANCEL_NOTIFICATIONS);
89 		msg.AddInt32(NOTIFICATION_PARAM_WHAT, notification);
90 		msg.AddMessenger(NOTIFICATION_PARAM_MESSENGER, notifyHandler);
91 		return BPrivate::media::dataexchange::SendToRoster(&msg);
92 	}
93 
94 	BMessage msg(MEDIA_SERVER_CANCEL_NOTIFICATIONS);
95 	msg.AddInt32(NOTIFICATION_PARAM_WHAT, notification);
96 	msg.AddInt32(NOTIFICATION_PARAM_TEAM, BPrivate::current_team());
97 	msg.AddMessenger(NOTIFICATION_PARAM_MESSENGER, notifyHandler);
98 	msg.AddData("node", B_RAW_TYPE, &node, sizeof(node));
99 
100 	return BPrivate::media::dataexchange::SendToServer(&msg);
101 }
102 
103 
104 /*!	Transmits the error code specified by \a what to anyone who's receiving
105 	notifications from this node. If \a info isn't \c NULL, it's used as a
106 	model message for the error notification message.
107 	The message field "be:node_id" will contain the node ID.
108 */
109 status_t
110 ReportError(const media_node& node, BMediaNode::node_error what,
111 	const BMessage* info)
112 {
113 	CALLED();
114 	BMessage msg;
115 	if (info != NULL)
116 		msg = *info;
117 
118 	msg.what = MEDIA_SERVER_SEND_NOTIFICATIONS;
119 	msg.AddInt32(NOTIFICATION_PARAM_WHAT, what);
120 	msg.AddInt32("be:node_id", node.node);
121 	msg.AddData("node", B_RAW_TYPE, &node, sizeof(node));
122 
123 	return BPrivate::media::dataexchange::SendToServer(&msg);
124 }
125 
126 
127 void
128 NodesCreated(const media_node_id* ids, int32 count)
129 {
130 	CALLED();
131 	BMessage msg(MEDIA_SERVER_SEND_NOTIFICATIONS);
132 	msg.AddInt32(NOTIFICATION_PARAM_WHAT, B_MEDIA_NODE_CREATED);
133 	for (int32 i = 0; i < count; i++) {
134 		msg.AddInt32("media_node_id", ids[i]);
135 	}
136 
137 	BPrivate::media::dataexchange::SendToServer(&msg);
138 }
139 
140 
141 void
142 NodesDeleted(const media_node_id* ids, int32 count)
143 {
144 	CALLED();
145 	BMessage msg(MEDIA_SERVER_SEND_NOTIFICATIONS);
146 	msg.AddInt32(NOTIFICATION_PARAM_WHAT, B_MEDIA_NODE_DELETED);
147 	for (int32 i = 0; i < count; i++) {
148 		msg.AddInt32("media_node_id", ids[i]);
149 	}
150 
151 	BPrivate::media::dataexchange::SendToServer(&msg);
152 }
153 
154 
155 void
156 ConnectionMade(const media_input& input, const media_output& output,
157 	const media_format& format)
158 {
159 	CALLED();
160 	BMessage msg(MEDIA_SERVER_SEND_NOTIFICATIONS);
161 	msg.AddInt32(NOTIFICATION_PARAM_WHAT, B_MEDIA_CONNECTION_MADE);
162 	msg.AddData("input", B_RAW_TYPE, &input, sizeof(input));
163 	msg.AddData("output", B_RAW_TYPE, &output, sizeof(output));
164 	msg.AddData("format", B_RAW_TYPE, &format, sizeof(format));
165 
166 	BPrivate::media::dataexchange::SendToServer(&msg);
167 }
168 
169 
170 void
171 ConnectionBroken(const media_source& source,
172 	const media_destination& destination)
173 {
174 	CALLED();
175 	BMessage msg(MEDIA_SERVER_SEND_NOTIFICATIONS);
176 	msg.AddInt32(NOTIFICATION_PARAM_WHAT, B_MEDIA_CONNECTION_BROKEN);
177 	msg.AddData("source", B_RAW_TYPE, &source, sizeof(source));
178 	msg.AddData("destination", B_RAW_TYPE, &destination, sizeof(destination));
179 
180 	BPrivate::media::dataexchange::SendToServer(&msg);
181 }
182 
183 
184 void
185 BuffersCreated(area_info* areas, int32 count)
186 {
187 	CALLED();
188 	BMessage msg(MEDIA_SERVER_SEND_NOTIFICATIONS);
189 	msg.AddInt32(NOTIFICATION_PARAM_WHAT, B_MEDIA_BUFFER_CREATED);
190 	for (int32 i = 0; i < count; i++) {
191 		msg.AddData("clone_info", B_RAW_TYPE, &areas[i], sizeof(area_info));
192 	}
193 
194 	BPrivate::media::dataexchange::SendToServer(&msg);
195 }
196 
197 
198 void
199 BuffersDeleted(const media_buffer_id* ids, int32 count)
200 {
201 	CALLED();
202 	BMessage msg(MEDIA_SERVER_SEND_NOTIFICATIONS);
203 	msg.AddInt32(NOTIFICATION_PARAM_WHAT, B_MEDIA_BUFFER_DELETED);
204 	for (int32 i = 0; i < count; i++) {
205 		msg.AddInt32("media_buffer_id", ids[i]);
206 	}
207 
208 	BPrivate::media::dataexchange::SendToServer(&msg);
209 }
210 
211 
212 void
213 FormatChanged(const media_source& source, const media_destination& destination,
214 	const media_format& format)
215 {
216 	CALLED();
217 	BMessage msg(MEDIA_SERVER_SEND_NOTIFICATIONS);
218 	msg.AddInt32(NOTIFICATION_PARAM_WHAT, B_MEDIA_FORMAT_CHANGED);
219 	msg.AddData("source", B_RAW_TYPE, &source, sizeof(source));
220 	msg.AddData("destination", B_RAW_TYPE, &destination, sizeof(destination));
221 	msg.AddData("format", B_RAW_TYPE, &format, sizeof(format));
222 
223 	BPrivate::media::dataexchange::SendToServer(&msg);
224 }
225 
226 
227 status_t
228 ParameterChanged(const media_node& node, int32 parameterID)
229 {
230 	CALLED();
231 	BMessage msg(MEDIA_SERVER_SEND_NOTIFICATIONS);
232 	msg.AddInt32(NOTIFICATION_PARAM_WHAT, B_MEDIA_PARAMETER_CHANGED);
233 	msg.AddData("node", B_RAW_TYPE, &node, sizeof(node));
234 	msg.AddInt32("parameter", parameterID);
235 
236 	return BPrivate::media::dataexchange::SendToServer(&msg);
237 }
238 
239 
240 void
241 WebChanged(const media_node& node)
242 {
243 	CALLED();
244 	BMessage msg(MEDIA_SERVER_SEND_NOTIFICATIONS);
245 	msg.AddInt32(NOTIFICATION_PARAM_WHAT, B_MEDIA_WEB_CHANGED);
246 	msg.AddData("node", B_RAW_TYPE, &node, sizeof(node));
247 
248 	BPrivate::media::dataexchange::SendToServer(&msg);
249 }
250 
251 
252 status_t
253 NewParameterValue(const media_node& node, int32 parameterID, bigtime_t when,
254 	const void* param, size_t paramsize)
255 {
256 	CALLED();
257 	BMessage msg(MEDIA_SERVER_SEND_NOTIFICATIONS);
258 	msg.AddInt32(NOTIFICATION_PARAM_WHAT, B_MEDIA_NEW_PARAMETER_VALUE);
259 	msg.AddData("node", B_RAW_TYPE, &node, sizeof(node));
260 	msg.AddInt32("parameter", parameterID);
261 	msg.AddInt64("when", when);
262 	msg.AddData("value", B_RAW_TYPE, param, paramsize);
263 
264 	return BPrivate::media::dataexchange::SendToServer(&msg);
265 }
266 
267 
268 void
269 FlavorsChanged(media_addon_id addOnID, int32 newCount, int32 goneCount)
270 {
271 	CALLED();
272 	BMessage msg(MEDIA_SERVER_SEND_NOTIFICATIONS);
273 	msg.AddInt32(NOTIFICATION_PARAM_WHAT, B_MEDIA_FLAVORS_CHANGED);
274 	msg.AddInt32("be:addon_id", addOnID);
275 	msg.AddInt32("be:new_count", newCount);
276 	msg.AddInt32("be:gone_count", goneCount);
277 
278 	BPrivate::media::dataexchange::SendToServer(&msg);
279 }
280 
281 
282 void
283 NodeStopped(const media_node& node, bigtime_t when)
284 {
285 	CALLED();
286 	BMessage msg(MEDIA_SERVER_SEND_NOTIFICATIONS);
287 	msg.AddInt32(NOTIFICATION_PARAM_WHAT, B_MEDIA_NODE_STOPPED);
288 	msg.AddData("node", B_RAW_TYPE, &node, sizeof(node));
289 	msg.AddInt64("when", when);
290 
291 	BPrivate::media::dataexchange::SendToServer(&msg);
292 }
293 
294 
295 // TODO: missing: B_MEDIA_TRANSPORT_STATE: "state", "location", "realtime"
296 // TODO: missing: B_MEDIA_DEFAULT_CHANGED: "default", "node"
297 
298 
299 bool
300 IsValidNotificationRequest(bool node_specific, int32 notification)
301 {
302 	switch (notification) {
303 		// valid for normal and node specific watching
304 		case B_MEDIA_WILDCARD:
305 		case B_MEDIA_NODE_CREATED:
306 		case B_MEDIA_NODE_DELETED:
307 		case B_MEDIA_CONNECTION_MADE:
308 		case B_MEDIA_CONNECTION_BROKEN:
309 		case B_MEDIA_BUFFER_CREATED:
310 		case B_MEDIA_BUFFER_DELETED:
311 		case B_MEDIA_TRANSPORT_STATE:
312 		case B_MEDIA_DEFAULT_CHANGED:
313 		case B_MEDIA_FLAVORS_CHANGED:
314 			return true;
315 
316 		// invalid if we watch for a specific node
317 		case B_MEDIA_SERVER_STARTED:
318 		case B_MEDIA_SERVER_QUIT:
319 			return !node_specific;
320 
321 		// only valid for node specific watching
322 		case B_MEDIA_PARAMETER_CHANGED:
323 		case B_MEDIA_FORMAT_CHANGED:
324 		case B_MEDIA_WEB_CHANGED:
325 		case B_MEDIA_NEW_PARAMETER_VALUE:
326 		case B_MEDIA_NODE_STOPPED:
327 			return node_specific;
328 
329 		// everything else is invalid
330 		default:
331 			return false;
332 	}
333 }
334 
335 }	// namespace notifications
336 }	// namespace media
337 }	// namespace BPrivate
338