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 "MediaDebug.h"
48 #include "DataExchange.h"
49
50
51 namespace BPrivate {
52 namespace media {
53 namespace notifications {
54
55
56 status_t
Register(const BMessenger & notifyHandler,const media_node & node,int32 notification)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
Unregister(const BMessenger & notifyHandler,const media_node & node,int32 notification)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
ReportError(const media_node & node,BMediaNode::node_error what,const BMessage * info)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
NodesCreated(const media_node_id * ids,int32 count)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
NodesDeleted(const media_node_id * ids,int32 count)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
ConnectionMade(const media_input & input,const media_output & output,const media_format & format)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
ConnectionBroken(const media_source & source,const media_destination & destination)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
BuffersCreated(area_info * areas,int32 count)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
BuffersDeleted(const media_buffer_id * ids,int32 count)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
FormatChanged(const media_source & source,const media_destination & destination,const media_format & format)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
ParameterChanged(const media_node & node,int32 parameterID)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
WebChanged(const media_node & node)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
NewParameterValue(const media_node & node,int32 parameterID,bigtime_t when,const void * param,size_t paramsize)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
FlavorsChanged(media_addon_id addOnID,int32 newCount,int32 goneCount)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
NodeStopped(const media_node & node,bigtime_t when)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
IsValidNotificationRequest(bool node_specific,int32 notification)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