status_t launch_media_server(bigtime_t timeout, bool (*progress)(int stage, const char* message, void* cookie), void* cookie, uint32 flags) { if (BMediaRoster::IsRunning()) return B_ALREADY_RUNNING; status_t err = B_MEDIA_SYSTEM_FAILURE; BMediaRoster* roster = BMediaRoster::Roster(&err); if (roster == NULL || err != B_OK) return err; if (progress == NULL && roster->Lock()) { MediaRosterEx(roster)->EnableLaunchNotification(true, true); roster->Unlock(); } // The media_server crashed if (be_roster->IsRunning(B_MEDIA_ADDON_SERVER_SIGNATURE)) { progress_startup(10, progress, cookie); kill_team(be_roster->TeamFor(B_MEDIA_ADDON_SERVER_SIGNATURE)); } // The media_addon_server crashed if (be_roster->IsRunning(B_MEDIA_SERVER_SIGNATURE)) { progress_startup(20, progress, cookie); kill_team(be_roster->TeamFor(B_MEDIA_SERVER_SIGNATURE)); } progress_startup(50, progress, cookie); err = BLaunchRoster().Start(B_MEDIA_SERVER_SIGNATURE); if (err != B_OK) progress_startup(90, progress, cookie); else if (progress != NULL) { progress_startup(100, progress, cookie); err = B_OK; } return err; }
void VolumeControl::MessageReceived(BMessage* msg) { switch (msg->what) { case B_MOUSE_WHEEL_CHANGED: { if (!fMixerControl->Connected()) return; // Even though the volume bar is horizontal, we use the more common // vertical mouse wheel change float deltaY = 0.0f; msg->FindFloat("be:wheel_delta_y", &deltaY); if (deltaY == 0.0f) return; int32 currentValue = Value(); int32 newValue = currentValue - int32(deltaY) * 3; if (newValue != currentValue) { SetValue(newValue); InvokeNotify(ModificationMessage(), B_CONTROL_MODIFIED); } break; } case B_MEDIA_NEW_PARAMETER_VALUE: if (IsTracking()) break; SetValue((int32)fMixerControl->Volume()); break; case B_SOME_APP_LAUNCHED: case B_SOME_APP_QUIT: { const char* signature; if (msg->FindString("be:signature", &signature) != B_OK) break; bool isMediaServer = !strcmp(signature, kMediaServerSignature); bool isAddOnServer = !strcmp(signature, kAddOnServerSignature); if (!isMediaServer && !isAddOnServer) break; if (isMediaServer) fMediaServerRunning = msg->what == B_SOME_APP_LAUNCHED; if (isAddOnServer) fAddOnServerRunning = msg->what == B_SOME_APP_LAUNCHED; if (!fMediaServerRunning && !fAddOnServerRunning) { // No media server around SetLabel(B_TRANSLATE("No media server running")); SetEnabled(false); } else if (fMediaServerRunning && fAddOnServerRunning) { // HACK! // quit our now invalid instance of the media roster // so that before new nodes are created, // we get a new roster BMediaRoster* roster = BMediaRoster::CurrentRoster(); if (roster != NULL) { roster->Lock(); roster->Quit(); } BMessage reconnect(kMsgReconnectVolume); BMessageRunner::StartSending(this, &reconnect, 1000000LL, 1); fConnectRetries = 3; } break; } case B_QUIT_REQUESTED: Window()->MessageReceived(msg); break; case kMsgReconnectVolume: _ConnectVolume(); if (!fMixerControl->Connected() && --fConnectRetries > 1) { BMessage reconnect(kMsgReconnectVolume); BMessageRunner::StartSending(this, &reconnect, 6000000LL / fConnectRetries, 1); } break; default: return BView::MessageReceived(msg); } }
void MainApp::MessageReceived(BMessage* message) { switch (message->what) { case M_NEW_PLAYER: { MainWin* window = NewWindow(); if (window != NULL) window->Show(); break; } case M_PLAYER_QUIT: { // store the window settings of this instance MainWin* window = NULL; bool audioOnly = false; BRect windowFrame; bigtime_t creationTime; if (message->FindPointer("instance", (void**)&window) == B_OK && message->FindBool("audio only", &audioOnly) == B_OK && message->FindRect("window frame", &windowFrame) == B_OK && message->FindInt64("creation time", &creationTime) == B_OK) { if (audioOnly && (!fAudioWindowFrameSaved || creationTime < fLastSavedAudioWindowCreationTime)) { fAudioWindowFrameSaved = true; fLastSavedAudioWindowCreationTime = creationTime; Settings::Default()->SetAudioPlayerWindowFrame(windowFrame); } } // Store the playlist if there is one. Since the app is doing // this, it is "atomic". If the user has multiple instances // playing audio at the same time, the last instance which is // quit wins. BMessage playlistArchive; if (message->FindMessage("playlist", &playlistArchive) == B_OK) _StoreCurrentPlaylist(&playlistArchive); // quit if this was the last player window fPlayerCount--; if (fPlayerCount == 0) PostMessage(B_QUIT_REQUESTED); break; } case B_SOME_APP_LAUNCHED: case B_SOME_APP_QUIT: { const char* mimeSig; if (message->FindString("be:signature", &mimeSig) < B_OK) break; bool isMediaServer = strcmp(mimeSig, kMediaServerSig) == 0; bool isAddonServer = strcmp(mimeSig, kMediaServerAddOnSig) == 0; if (!isMediaServer && !isAddonServer) break; bool running = (message->what == B_SOME_APP_LAUNCHED); if (isMediaServer) fMediaServerRunning = running; if (isAddonServer) fMediaAddOnServerRunning = running; if (!fMediaServerRunning && !fMediaAddOnServerRunning) { fprintf(stderr, "media server has quit.\n"); // trigger closing of media nodes BMessage broadcast(M_MEDIA_SERVER_QUIT); _BroadcastMessage(broadcast); } else if (fMediaServerRunning && fMediaAddOnServerRunning) { fprintf(stderr, "media server has launched.\n"); // HACK! // quit our now invalid instance of the media roster // so that before new nodes are created, // we get a new roster (it is a normal looper) // TODO: This functionality could become part of // BMediaRoster. It could detect the start/quit of // the servers like it is done here, and either quit // itself, or re-establish the connection, and send some // notification to the app... something along those lines. BMediaRoster* roster = BMediaRoster::CurrentRoster(); if (roster) { roster->Lock(); roster->Quit(); } // give the servers some time to init... snooze(3000000); // trigger re-init of media nodes BMessage broadcast(M_MEDIA_SERVER_STARTED); _BroadcastMessage(broadcast); } break; } case M_SETTINGS: _ShowSettingsWindow(); break; case M_SHOW_OPEN_PANEL: _ShowOpenFilePanel(message); break; case M_SHOW_SAVE_PANEL: _ShowSaveFilePanel(message); break; case M_OPEN_PANEL_RESULT: _HandleOpenPanelResult(message); break; case M_SAVE_PANEL_RESULT: _HandleSavePanelResult(message); break; case B_CANCEL: { // The user canceled a file panel, but store at least the current // file panel folder. uint32 oldWhat; if (message->FindInt32("old_what", (int32*)&oldWhat) != B_OK) break; if (oldWhat == M_OPEN_PANEL_RESULT && fOpenFilePanel != NULL) fOpenFilePanel->GetPanelDirectory(&fLastFilePanelFolder); else if (oldWhat == M_SAVE_PANEL_RESULT && fSaveFilePanel != NULL) fSaveFilePanel->GetPanelDirectory(&fLastFilePanelFolder); break; } default: BApplication::MessageReceived(message); break; } }
void MediaWindow::MessageReceived(BMessage* message) { switch (message->what) { case ML_INIT_MEDIA: _InitMedia(false); break; case ML_RESTART_MEDIA_SERVER: { thread_id thread = spawn_thread(&MediaWindow::_RestartMediaServices, "restart_thread", B_NORMAL_PRIORITY, this); if (thread < 0) fprintf(stderr, "couldn't create restart thread\n"); else resume_thread(thread); break; } case B_MEDIA_WEB_CHANGED: case ML_SELECTED_NODE: { PRINT_OBJECT(*message); MediaListItem* item = static_cast<MediaListItem*>( fListView->ItemAt(fListView->CurrentSelection())); if (item == NULL) break; fCurrentNode.SetTo(NULL); _ClearParamView(); item->AlterWindow(this); break; } case B_SOME_APP_LAUNCHED: { PRINT_OBJECT(*message); BString mimeSig; if (message->FindString("be:signature", &mimeSig) == B_OK && (mimeSig == "application/x-vnd.Be.addon-host" || mimeSig == "application/x-vnd.Be.media-server")) { _Notify(0.75, B_TRANSLATE("Starting media server" B_UTF8_ELLIPSIS)); } break; } case B_SOME_APP_QUIT: { PRINT_OBJECT(*message); BString mimeSig; if (message->FindString("be:signature", &mimeSig) == B_OK) { if (mimeSig == "application/x-vnd.Be.addon-host" || mimeSig == "application/x-vnd.Be.media-server") { BMediaRoster* roster = BMediaRoster::CurrentRoster(); if (roster != NULL && roster->Lock()) roster->Quit(); } } break; } default: BWindow::MessageReceived(message); break; } }
status_t shutdown_media_server(bigtime_t timeout, bool (*progress)(int stage, const char* message, void* cookie), void* cookie) { BMessage msg(B_QUIT_REQUESTED); status_t err = B_MEDIA_SYSTEM_FAILURE; bool shutdown = false; BMediaRoster* roster = BMediaRoster::Roster(&err); if (roster == NULL || err != B_OK) return err; if (progress == NULL && roster->Lock()) { MediaRosterEx(roster)->EnableLaunchNotification(true, true); roster->Unlock(); } if ((err = msg.AddBool("be:_user_request", true)) != B_OK) return err; team_id mediaServer = be_roster->TeamFor(B_MEDIA_SERVER_SIGNATURE); team_id addOnServer = be_roster->TeamFor(B_MEDIA_ADDON_SERVER_SIGNATURE); if (mediaServer != B_ERROR) { BMessage reply; BMessenger messenger(B_MEDIA_SERVER_SIGNATURE, mediaServer); progress_shutdown(10, progress, cookie); err = messenger.SendMessage(&msg, &reply, 2000000, 2000000); reply.FindBool("_shutdown", &shutdown); if (err == B_TIMED_OUT || shutdown == false) { if (messenger.IsValid()) kill_team(mediaServer); } else if (err != B_OK) return err; progress_shutdown(20, progress, cookie); int32 rv; if (reply.FindInt32("error", &rv) == B_OK && rv != B_OK) return rv; } if (addOnServer != B_ERROR) { shutdown = false; BMessage reply; BMessenger messenger(B_MEDIA_ADDON_SERVER_SIGNATURE, addOnServer); progress_shutdown(40, progress, cookie); // The media_server usually shutdown the media_addon_server, // if not let's do something. if (messenger.IsValid()) { err = messenger.SendMessage(&msg, &reply, 2000000, 2000000); reply.FindBool("_shutdown", &shutdown); if (err == B_TIMED_OUT || shutdown == false) { if (messenger.IsValid()) kill_team(addOnServer); } else if (err != B_OK) return err; progress_shutdown(50, progress, cookie); int32 rv; if (reply.FindInt32("error", &rv) == B_OK && rv != B_OK) return rv; } } progress_shutdown(100, progress, cookie); return B_OK; }