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