xref: /haiku/src/servers/media/media_server.cpp (revision 7120e97489acbf17d86d3f33e3b2e68974fd4b23)
1 #include <Application.h>
2 #include <stdio.h>
3 #include <Messenger.h>
4 #include <MediaDefs.h>
5 #include <MediaFormats.h>
6 #include <Autolock.h>
7 #include <string.h>
8 #include "NotificationManager.h"
9 #include "ServerInterface.h"
10 #include "DataExchange.h"
11 #include "BufferManager.h"
12 #include "NodeManager.h"
13 #include "AppManager.h"
14 #include "media_server.h"
15 #include "debug.h"
16 
17 /*
18  *
19  * An implementation of a new media_server for the OpenBeOS MediaKit
20  * Started by Marcus Overhagen <marcus@overhagen.de> on 2001-10-25
21  *
22  * Communication with the OpenBeOS libmedia.so is done using BMessages
23  * sent to the server application, handled in XXX()
24  * functions. A simple BMessage reply is beeing send back.
25  *
26  *
27  * function names and class structure is loosely
28  * based on information acquired using:
29  * nm --demangle /boot/beos/system/servers/media_server | grep Server | sort
30  * nm --demangle /boot/beos/system/servers/media_server | grep Manager | sort
31  *
32  */
33 
34 NotificationManager *gNotificationManager;
35 BufferManager *gBufferManager;
36 AppManager *gAppManager;
37 NodeManager *gNodeManager;
38 
39 
40 #define REPLY_TIMEOUT ((bigtime_t)500000)
41 
42 class ServerApp : BApplication
43 {
44 public:
45 	ServerApp();
46 	~ServerApp();
47 
48 	bool QuitRequested();
49 	void HandleMessage(int32 code, void *data, size_t size);
50 	void ArgvReceived(int32 argc, char **argv);
51 	static int32 controlthread(void *arg);
52 
53 /* functionality not yet implemented
54 00014a00 T _ServerApp::_ServerApp(void)
55 00014e1c T _ServerApp::~_ServerApp(void)
56 00014ff4 T _ServerApp::MessageReceived(BMessage *);
57 00015840 T _ServerApp::QuitRequested(void)
58 00015b50 T _ServerApp::_DoNotify(command_data *)
59 00015d18 T _ServerApp::_UnregisterApp(long, bool)
60 00018e90 T _ServerApp::AddOnHost(void)
61 00019530 T _ServerApp::AboutRequested(void)
62 00019d04 T _ServerApp::AddPurgableBufferGroup(long, long, long, void *)
63 00019db8 T _ServerApp::CancelPurgableBufferGroupCleanup(long)
64 00019e50 T _ServerApp::DirtyWork(void)
65 0001a4bc T _ServerApp::ArgvReceived(long, char **)
66 0001a508 T _ServerApp::CleanupPurgedBufferGroup(_ServerApp::purgable_buffer_group const &, bool)
67 0001a5dc T _ServerApp::DirtyWorkLaunch(void *)
68 0001a634 T _ServerApp::SetQuitMode(bool)
69 0001a648 T _ServerApp::IsQuitMode(void) const
70 0001a658 T _ServerApp::BroadcastCurrentStateTo(BMessenger &)
71 0001adcc T _ServerApp::ReadyToRun(void)
72 */
73 
74 private:
75 	port_id		control_port;
76 	thread_id	control_thread;
77 
78 	BLocker *fLocker;
79 
80 	void MessageReceived(BMessage *msg);
81 	typedef BApplication inherited;
82 };
83 
84 ServerApp::ServerApp()
85  	: BApplication(NEW_MEDIA_SERVER_SIGNATURE),
86 	fLocker(new BLocker("media server locker"))
87 {
88 	//load volume settings from config file
89 	//mVolumeLeft = ???;
90 	//mVolumeRight = ???;
91 
92  	gNotificationManager = new NotificationManager;
93  	gBufferManager = new BufferManager;
94 	gAppManager = new AppManager;
95 	gNodeManager = new NodeManager;
96 
97 	control_port = create_port(64,"media_server port");
98 	control_thread = spawn_thread(controlthread, "media_server control", 105, this);
99 	resume_thread(control_thread);
100 
101 	gAppManager->StartAddonServer();
102 }
103 
104 ServerApp::~ServerApp()
105 {
106 	TRACE("ServerApp::~ServerApp()\n");
107 	delete gNotificationManager;
108 	delete gBufferManager;
109 	delete gAppManager;
110 	delete gNodeManager;
111 	delete fLocker;
112 	delete_port(control_port);
113 	status_t err;
114 	wait_for_thread(control_thread,&err);
115 }
116 
117 void ServerApp::ArgvReceived(int32 argc, char **argv)
118 {
119 	for (int arg = 1; arg < argc; arg++) {
120 		if (strstr(argv[arg], "dump")) {
121 			gAppManager->Dump();
122 			gNodeManager->Dump();
123 			gBufferManager->Dump();
124 			gNotificationManager->Dump();
125 		}
126 		if (strstr(argv[arg], "buffer")) {
127 			gBufferManager->Dump();
128 		}
129 		if (strstr(argv[arg], "node")) {
130 			gNodeManager->Dump();
131 		}
132 		if (strstr(argv[arg], "quit")) {
133 			PostMessage(B_QUIT_REQUESTED);
134 		}
135 	}
136 }
137 
138 bool
139 ServerApp::QuitRequested()
140 {
141 	TRACE("ServerApp::QuitRequested()\n");
142 	gAppManager->TerminateAddonServer();
143 	return true;
144 }
145 
146 void
147 ServerApp::HandleMessage(int32 code, void *data, size_t size)
148 {
149 	status_t rv;
150 	INFO("ServerApp::HandleMessage %#lx\n", code);
151 	switch (code) {
152 		case SERVER_REGISTER_ADDONSERVER:
153 		{
154 			const server_register_addonserver_request *request = reinterpret_cast<const server_register_addonserver_request *>(data);
155 			server_register_addonserver_reply reply;
156 			rv = gAppManager->RegisterAddonServer(request->team);
157 			request->SendReply(rv, &reply, sizeof(reply));
158 			break;
159 		}
160 
161 		case SERVER_REGISTER_APP:
162 		{
163 			const server_register_app_request *request = reinterpret_cast<const server_register_app_request *>(data);
164 			server_register_app_reply reply;
165 			rv = gAppManager->RegisterTeam(request->team, request->messenger);
166 			request->SendReply(rv, &reply, sizeof(reply));
167 			break;
168 		}
169 
170 		case SERVER_UNREGISTER_APP:
171 		{
172 			const server_unregister_app_request *request = reinterpret_cast<const server_unregister_app_request *>(data);
173 			server_unregister_app_reply reply;
174 			rv = gAppManager->UnregisterTeam(request->team);
175 			request->SendReply(rv, &reply, sizeof(reply));
176 			break;
177 		}
178 
179 		case SERVER_GET_MEDIAADDON_REF:
180 		{
181 			server_get_mediaaddon_ref_request *msg = (server_get_mediaaddon_ref_request *)data;
182 			server_get_mediaaddon_ref_reply reply;
183 			entry_ref tempref;
184 			reply.result = gNodeManager->GetAddonRef(&tempref, msg->addonid);
185 			reply.ref = tempref;
186 			write_port(msg->reply_port, 0, &reply, sizeof(reply));
187 			break;
188 		}
189 
190 		case SERVER_NODE_ID_FOR:
191 		{
192 			const server_node_id_for_request *request = reinterpret_cast<const server_node_id_for_request *>(data);
193 			server_node_id_for_reply reply;
194 			rv = gNodeManager->FindNodeId(&reply.nodeid, request->port);
195 			request->SendReply(rv, &reply, sizeof(reply));
196 			break;
197 		}
198 
199 		case SERVER_GET_LIVE_NODE_INFO:
200 		{
201 			const server_get_live_node_info_request *request = reinterpret_cast<const server_get_live_node_info_request *>(data);
202 			server_get_live_node_info_reply reply;
203 			rv = gNodeManager->GetLiveNodeInfo(&reply.live_info, request->node);
204 			request->SendReply(rv, &reply, sizeof(reply));
205 			break;
206 		}
207 
208 		case SERVER_GET_LIVE_NODES:
209 		{
210 			const server_get_live_nodes_request *request = reinterpret_cast<const server_get_live_nodes_request *>(data);
211 			server_get_live_nodes_reply reply;
212 			Stack<live_node_info> livenodes;
213 			rv = gNodeManager->GetLiveNodes(
214 					&livenodes,
215 					request->maxcount,
216 					request->has_input ? &request->inputformat : NULL,
217 					request->has_output ? &request->outputformat : NULL,
218 					request->has_name ? request->name : NULL,
219 					request->require_kinds);
220 			reply.count = livenodes.CountItems();
221 			if (reply.count <= MAX_LIVE_INFO) {
222 				for (int32 index = 0; index < reply.count; index++)
223 					livenodes.Pop(&reply.live_info[index]);
224 				reply.area = -1;
225 			} else {
226 				// we create an area here, and pass it to the library, where it will be deleted.
227 				live_node_info *start_addr;
228 				size_t size;
229 				size = ((reply.count * sizeof(live_node_info)) + B_PAGE_SIZE - 1) & ~(B_PAGE_SIZE - 1);
230 				reply.area = create_area("get live nodes", reinterpret_cast<void **>(&start_addr), B_ANY_ADDRESS, size, B_NO_LOCK, B_READ_AREA | B_WRITE_AREA);
231 				if (reply.area < B_OK) {
232 					FATAL("SERVER_GET_LIVE_NODES: failed to create area, error %#lx\n", reply.area);
233 					reply.count = 0;
234 					rv = B_ERROR;
235 				} else {
236 					for (int32 index = 0; index < reply.count; index++)
237 						livenodes.Pop(&start_addr[index]);
238 				}
239 			}
240 			rv = request->SendReply(rv, &reply, sizeof(reply));
241 			if (rv != B_OK)
242 				delete_area(reply.area); // if we couldn't send the message, delete the area
243 			break;
244 		}
245 
246 		case SERVER_GET_NODE_FOR:
247 		{
248 			const server_get_node_for_request *request = reinterpret_cast<const server_get_node_for_request *>(data);
249 			server_get_node_for_reply reply;
250 			rv = gNodeManager->GetCloneForId(&reply.clone, request->nodeid, request->team);
251 			request->SendReply(rv, &reply, sizeof(reply));
252 			break;
253 		}
254 
255 		case SERVER_RELEASE_NODE:
256 		{
257 			const server_release_node_request *request = reinterpret_cast<const server_release_node_request *>(data);
258 			server_release_node_reply reply;
259 			rv = gNodeManager->ReleaseNode(request->node, request->team);
260 			request->SendReply(rv, &reply, sizeof(reply));
261 			break;
262 		}
263 
264 		case SERVER_REGISTER_NODE:
265 		{
266 			const server_register_node_request *request = reinterpret_cast<const server_register_node_request *>(data);
267 			server_register_node_reply reply;
268 			rv = gNodeManager->RegisterNode(&reply.nodeid, request->addon_id, request->addon_flavor_id, request->name, request->kinds, request->port, request->team);
269 			request->SendReply(rv, &reply, sizeof(reply));
270 			break;
271 		}
272 
273 		case SERVER_UNREGISTER_NODE:
274 		{
275 			const server_unregister_node_request *request = reinterpret_cast<const server_unregister_node_request *>(data);
276 			server_unregister_node_reply reply;
277 			rv = gNodeManager->UnregisterNode(&reply.addon_id, request->nodeid, request->team);
278 			request->SendReply(rv, &reply, sizeof(reply));
279 			break;
280 		}
281 
282 		case SERVER_PUBLISH_INPUTS:
283 		{
284 			const server_publish_inputs_request *request = reinterpret_cast<const server_publish_inputs_request *>(data);
285 			server_publish_inputs_reply reply;
286 			if (request->count <= MAX_INPUTS) {
287 				rv = gNodeManager->PublishInputs(request->node, request->inputs, request->count);
288 			} else {
289 				media_input *inputs;
290 				area_id clone;
291 				clone = clone_area("media_inputs clone", reinterpret_cast<void **>(&inputs), B_ANY_ADDRESS, B_READ_AREA | B_WRITE_AREA, request->area);
292 				if (clone < B_OK) {
293 					FATAL("SERVER_PUBLISH_INPUTS: failed to clone area, error %#lx\n", clone);
294 					rv = B_ERROR;
295 				} else {
296 					rv = gNodeManager->PublishInputs(request->node, inputs, request->count);
297 					delete_area(clone);
298 				}
299 			}
300 			request->SendReply(rv, &reply, sizeof(reply));
301 			break;
302 		}
303 
304 		case SERVER_PUBLISH_OUTPUTS:
305 		{
306 			const server_publish_outputs_request *request = reinterpret_cast<const server_publish_outputs_request *>(data);
307 			server_publish_outputs_reply reply;
308 			if (request->count <= MAX_OUTPUTS) {
309 				rv = gNodeManager->PublishOutputs(request->node, request->outputs, request->count);
310 			} else {
311 				media_output *outputs;
312 				area_id clone;
313 				clone = clone_area("media_outputs clone", reinterpret_cast<void **>(&outputs), B_ANY_ADDRESS, B_READ_AREA | B_WRITE_AREA, request->area);
314 				if (clone < B_OK) {
315 					FATAL("SERVER_PUBLISH_OUTPUTS: failed to clone area, error %#lx\n", clone);
316 					rv = B_ERROR;
317 				} else {
318 					rv = gNodeManager->PublishOutputs(request->node, outputs, request->count);
319 					delete_area(clone);
320 				}
321 			}
322 			request->SendReply(rv, &reply, sizeof(reply));
323 			break;
324 		}
325 
326 		case SERVER_GET_NODE:
327 		{
328 			const server_get_node_request *request = reinterpret_cast<const server_get_node_request *>(data);
329 			server_get_node_reply reply;
330 			rv = gNodeManager->GetClone(&reply.node, reply.input_name, &reply.input_id, request->type, request->team);
331 			request->SendReply(rv, &reply, sizeof(reply));
332 			break;
333 		}
334 
335 		case SERVER_SET_NODE:
336 		{
337 			const server_set_node_request *request = reinterpret_cast<const server_set_node_request *>(data);
338 			server_set_node_reply reply;
339 			// XXX do something here
340 			debugger("SERVER_SET_NODE seems to be needed\n");
341 			request->SendReply(B_OK, &reply, sizeof(reply));
342 			break;
343 		}
344 
345 		case SERVER_GET_DORMANT_NODE_FOR:
346 		{
347 			const server_get_dormant_node_for_request *request = reinterpret_cast<const server_get_dormant_node_for_request *>(data);
348 			server_get_dormant_node_for_reply reply;
349 			rv = gNodeManager->GetDormantNodeInfo(&reply.node_info, request->node);
350 			request->SendReply(rv, &reply, sizeof(reply));
351 			break;
352 		}
353 
354 		case SERVER_GET_INSTANCES_FOR:
355 		{
356 			const server_get_instances_for_request *request = reinterpret_cast<const server_get_instances_for_request *>(data);
357 			server_get_instances_for_reply reply;
358 			rv = gNodeManager->GetInstances(reply.node_id, &reply.count, min_c(request->maxcount, MAX_NODE_ID), request->addon_id, request->addon_flavor_id);
359 			if (reply.count == MAX_NODE_ID && request->maxcount > MAX_NODE_ID) { // XXX might be fixed by using an area
360 				FATAL("SERVER_GET_INSTANCES_FOR: WARNING! returning possibly truncated list of node id's\n");
361 			}
362 			request->SendReply(rv, &reply, sizeof(reply));
363 			break;
364 		}
365 
366 		case SERVER_REGISTER_MEDIAADDON:
367 		{
368 			server_register_mediaaddon_request *msg = (server_register_mediaaddon_request *)data;
369 			server_register_mediaaddon_reply reply;
370 			gNodeManager->RegisterAddon(msg->ref, &reply.addonid);
371 			write_port(msg->reply_port, 0, &reply, sizeof(reply));
372 			break;
373 		}
374 
375 		case SERVER_UNREGISTER_MEDIAADDON:
376 		{
377 			server_unregister_mediaaddon_command *msg = (server_unregister_mediaaddon_command *)data;
378 			gNodeManager->UnregisterAddon(msg->addonid);
379 			break;
380 		}
381 
382 		case SERVER_REGISTER_DORMANT_NODE:
383 		{
384 			xfer_server_register_dormant_node *msg = (xfer_server_register_dormant_node *)data;
385 			dormant_flavor_info dfi;
386 			if (msg->purge_id > 0)
387 				gNodeManager->RemoveDormantFlavorInfo(msg->purge_id);
388 			rv = dfi.Unflatten(msg->dfi_type, &(msg->dfi), msg->dfi_size);
389 			ASSERT(rv == B_OK);
390 			gNodeManager->AddDormantFlavorInfo(dfi);
391 			break;
392 		}
393 
394 		case SERVER_GET_DORMANT_NODES:
395 		{
396 			xfer_server_get_dormant_nodes *msg = (xfer_server_get_dormant_nodes *)data;
397 			xfer_server_get_dormant_nodes_reply reply;
398 			dormant_node_info * infos = new dormant_node_info[msg->maxcount];
399 			reply.count = msg->maxcount;
400 			reply.result = gNodeManager->GetDormantNodes(
401 				infos,
402 				&reply.count,
403 				msg->has_input ? &msg->inputformat : NULL,
404 				msg->has_output ? &msg->outputformat : NULL,
405 				msg->has_name ? msg->name : NULL,
406 				msg->require_kinds,
407 				msg->deny_kinds);
408 			if (reply.result != B_OK)
409 				reply.count = 0;
410 			write_port(msg->reply_port, 0, &reply, sizeof(reply));
411 			if (reply.count > 0)
412 				write_port(msg->reply_port, 0, infos, reply.count * sizeof(dormant_node_info));
413 			delete [] infos;
414 			break;
415 		}
416 
417 		case SERVER_GET_DORMANT_FLAVOR_INFO:
418 		{
419 			xfer_server_get_dormant_flavor_info *msg = (xfer_server_get_dormant_flavor_info *)data;
420 			dormant_flavor_info dfi;
421 			status_t rv;
422 
423 			rv = gNodeManager->GetDormantFlavorInfoFor(msg->addon, msg->flavor_id, &dfi);
424 			if (rv != B_OK) {
425 				xfer_server_get_dormant_flavor_info_reply reply;
426 				reply.result = rv;
427 				write_port(msg->reply_port, 0, &reply, sizeof(reply));
428 			} else {
429 				xfer_server_get_dormant_flavor_info_reply *reply;
430 				int replysize;
431 				replysize = sizeof(xfer_server_get_dormant_flavor_info_reply) + dfi.FlattenedSize();
432 				reply = (xfer_server_get_dormant_flavor_info_reply *)malloc(replysize);
433 
434 				reply->dfi_size = dfi.FlattenedSize();
435 				reply->dfi_type = dfi.TypeCode();
436 				reply->result = dfi.Flatten(reply->dfi, reply->dfi_size);
437 				write_port(msg->reply_port, 0, reply, replysize);
438 				free(reply);
439 			}
440 			break;
441 		}
442 
443 		case SERVER_GET_SHARED_BUFFER_AREA:
444 		{
445 			const server_get_shared_buffer_area_request *request = reinterpret_cast<const server_get_shared_buffer_area_request *>(data);
446 			server_get_shared_buffer_area_reply reply;
447 
448 			reply.area = gBufferManager->SharedBufferListID();
449 			request->SendReply(B_OK, &reply, sizeof(reply));
450 			break;
451 		}
452 
453 		case SERVER_REGISTER_BUFFER:
454 		{
455 			const server_register_buffer_request *request = reinterpret_cast<const server_register_buffer_request *>(data);
456 			server_register_buffer_reply reply;
457 			status_t status;
458 			if (request->info.buffer == 0) {
459 				reply.info = request->info; //size, offset, flags, area is kept
460 				// get a new beuffer id into reply.info.buffer
461 				status = gBufferManager->RegisterBuffer(request->team, request->info.size, request->info.flags, request->info.offset, request->info.area, &reply.info.buffer);
462 			} else {
463 				reply.info = request->info; //buffer id is kept
464 				status = gBufferManager->RegisterBuffer(request->team, request->info.buffer, &reply.info.size, &reply.info.flags, &reply.info.offset, &reply.info.area);
465 			}
466 			request->SendReply(status, &reply, sizeof(reply));
467 			break;
468 		}
469 
470 		case SERVER_UNREGISTER_BUFFER:
471 		{
472 			const server_unregister_buffer_command *cmd = reinterpret_cast<const server_unregister_buffer_command *>(data);
473 
474 			gBufferManager->UnregisterBuffer(cmd->team, cmd->bufferid);
475 			break;
476 		}
477 
478 		default:
479 			printf("media_server: received unknown message code %#08lx\n",code);
480 	}
481 }
482 
483 int32
484 ServerApp::controlthread(void *arg)
485 {
486 	char data[B_MEDIA_MESSAGE_SIZE];
487 	ServerApp *app;
488 	ssize_t size;
489 	int32 code;
490 
491 	app = (ServerApp *)arg;
492 	while ((size = read_port_etc(app->control_port, &code, data, sizeof(data), 0, 0)) > 0)
493 		app->HandleMessage(code, data, size);
494 
495 	return 0;
496 }
497 
498 void ServerApp::MessageReceived(BMessage *msg)
499 {
500 	switch (msg->what) {
501 		case MEDIA_SERVER_REQUEST_NOTIFICATIONS: gNotificationManager->EnqueueMessage(msg); break;
502 		case MEDIA_SERVER_CANCEL_NOTIFICATIONS: gNotificationManager->EnqueueMessage(msg); break;
503 		case MEDIA_SERVER_SEND_NOTIFICATIONS: gNotificationManager->EnqueueMessage(msg); break;
504 		default:
505 			printf("\nnew media server: unknown message received\n");
506 			msg->PrintToStream();
507 	}
508 }
509 
510 int main()
511 {
512 	new ServerApp;
513 	be_app->Run();
514 	delete be_app;
515 	return 0;
516 }
517 
518 
519 /*
520 0001e260 T MBufferManager::MBufferManager(void)
521 0001e47c T MBufferManager::~MBufferManager(void)
522 0001e540 T MBufferManager::PrintToStream(void)
523 0001e6fc T MBufferManager::RecycleBuffersWithOwner(long, long)
524 0001ea00 T MBufferManager::RegisterBuffer(long, buffer_clone_info const *, long *, media_source const &)
525 0001f090 T MBufferManager::AcquireBuffer(long, long, media_source)
526 0001f28c T MBufferManager::ReleaseBuffer(long, long, bool, BMessage *, char const *)
527 0001fd0c T MBufferManager::PurgeTeamBufferGroups(long)
528 0001fdf0 T MBufferManager::RegisterBufferGroup(BMessage *, char const *, long)
529 0002007c T MBufferManager::_RemoveGroupFromClaimants(long, long, void *)
530 00020158 T MBufferManager::UnregisterBufferGroup(BMessage *, char const *, long)
531 0002028c T MBufferManager::_UnregisterBufferGroup(long, long)
532 000206f4 T MBufferManager::AddBuffersTo(BMessage *, char const *)
533 00020cd0 T MBufferManager::ReclaimBuffers(long const *, long, long, long)
534 00020f7c T MBufferManager::CleanupPurgedBufferGroup(long, long, long, void *, bool, BMessage &)
535 00021080 T MBufferManager::LoadState(void)
536 0002108c T MBufferManager::SaveState(void)
537 
538 000210a0 T MDefaultManager::MDefaultManager(void)
539 0002123c T MDefaultManager::~MDefaultManager(void)
540 000212f4 T MDefaultManager::SaveState(void)
541 0002172c T MDefaultManager::LoadState(void)
542 00021de0 T MDefaultManager::SetDefault(long, BMessage &)
543 00022058 T MDefaultManager::SetRunningDefault(long, media_node const &)
544 000221a8 T MDefaultManager::RemoveRunningDefault(media_node const &)
545 000226ec T MDefaultManager::SetRealtimeFlags(unsigned long)
546 00022720 T MDefaultManager::GetRealtimeFlags(void)
547 00022730 T MDefaultManager::GetRunningDefault(long, media_node &)
548 000227d0 T MDefaultManager::RemoveDefault(long)
549 00022830 T MDefaultManager::GetDefault(long, BMessage &)
550 00022890 T MNotifierManager::MNotifierManager(void)
551 00022a5c T MNotifierManager::~MNotifierManager(void)
552 00022b20 T MNotifierManager::RegisterNotifier(long, BMessenger, media_node const *)
553 00022f50 T MNotifierManager::UnregisterNotifier(long, BMessenger, media_node const *)
554 00023f00 T MNotifierManager::BroadcastMessage(BMessage *, long long)
555 0002426c T MNotifierManager::regen_node_list(media_node const &)
556 000249b4 T MNotifierManager::get_node_messenger(media_node const &, get_messenger_a *)
557 00024a90 T MNotifierManager::HandleBroadcastError(BMessage *, BMessenger &, long, long long)
558 00024b34 T MNotifierManager::LoadState(void)
559 00024b40 T MNotifierManager::SaveState(void)
560 00024c5c T MMediaFilesManager::MMediaFilesManager(void)
561 00024dec T MMediaFilesManager::~MMediaFilesManager(void)
562 00024ea4 T MMediaFilesManager::SaveState(void)
563 00025b70 T MMediaFilesManager::LoadState(void)
564 00026668 T MMediaFilesManager::create_default_settings(void)
565 00027130 T MMediaFilesManager::GetTypes(BMessage &, BMessage &)
566 000271f8 T MMediaFilesManager::GetItems(BMessage &, BMessage &)
567 000274f0 T MMediaFilesManager::SetItem(BMessage &, BMessage &)
568 00027bc0 T MMediaFilesManager::ClearItem(BMessage &, BMessage &)
569 000288f4 T MMediaFilesManager::RemoveItem(BMessage &, BMessage &)
570 00028f0c T MMediaFilesManager::AddType(BMessage &, BMessage &)
571 */
572 
573