1 /* 2 * Copyright (c) 2003-2005, Haiku, Inc. 3 * Distributed under the terms of the MIT license. 4 * 5 * Authors: 6 * Sikosis, Jérôme Duval 7 */ 8 9 10 #include "MediaWindow.h" 11 12 #include <stdio.h> 13 14 #include <Alert.h> 15 #include <Application.h> 16 #include <Autolock.h> 17 #include <Bitmap.h> 18 #include <Button.h> 19 #include <Catalog.h> 20 #include <Debug.h> 21 #include <Deskbar.h> 22 #include <GroupView.h> 23 #include <Locale.h> 24 #include <MediaRoster.h> 25 #include <MediaTheme.h> 26 #include <Roster.h> 27 #include <Screen.h> 28 #include <ScrollView.h> 29 #include <SeparatorView.h> 30 #include <SpaceLayoutItem.h> 31 #include <StorageKit.h> 32 #include <String.h> 33 #include <TextView.h> 34 35 // Images 36 #include "iconfile.h" 37 38 39 #undef B_TRANSLATE_CONTEXT 40 #define B_TRANSLATE_CONTEXT "Media Window" 41 42 43 const uint32 ML_SELECTED_NODE = 'MlSN'; 44 const uint32 ML_INIT_MEDIA = 'MlIM'; 45 46 // MediaWindow - Constructor 47 MediaWindow::MediaWindow(BRect frame) 48 : 49 BWindow (frame, B_TRANSLATE("Media"), B_TITLED_WINDOW, 50 B_ASYNCHRONOUS_CONTROLS | B_AUTO_UPDATE_SIZE_LIMITS), 51 fCurrentNode(NULL), 52 fParamWeb(NULL), 53 fAudioInputs(5, true), 54 fAudioOutputs(5, true), 55 fVideoInputs(5, true), 56 fVideoOutputs(5, true), 57 fAlert(NULL), 58 fInitCheck(B_OK) 59 { 60 InitWindow(); 61 } 62 63 64 status_t 65 MediaWindow::InitCheck() 66 { 67 return fInitCheck; 68 } 69 70 71 MediaWindow::~MediaWindow() 72 { 73 _EmptyNodeLists(); 74 75 BMediaRoster* roster = BMediaRoster::Roster(); 76 if (roster && fCurrentNode) 77 roster->ReleaseNode(*fCurrentNode); 78 79 char buffer[512]; 80 BRect rect = Frame(); 81 PRINT_OBJECT(rect); 82 sprintf(buffer, "# MediaPrefs Settings\n rect = %i,%i,%i,%i\n", 83 int(rect.left), int(rect.top), int(rect.right), int(rect.bottom)); 84 85 BPath path; 86 if (find_directory(B_USER_SETTINGS_DIRECTORY, &path) == B_OK) { 87 path.Append(SETTINGS_FILE); 88 BFile file(path.Path(), B_READ_WRITE|B_CREATE_FILE|B_ERASE_FILE); 89 if (file.InitCheck()==B_OK) { 90 file.Write(buffer, strlen(buffer)); 91 } 92 } 93 } 94 95 96 void 97 MediaWindow::_FindNodes() 98 { 99 _FindNodes(B_MEDIA_RAW_AUDIO, B_PHYSICAL_OUTPUT, fAudioOutputs); 100 _FindNodes(B_MEDIA_RAW_AUDIO, B_PHYSICAL_INPUT, fAudioInputs); 101 _FindNodes(B_MEDIA_ENCODED_AUDIO, B_PHYSICAL_OUTPUT, fAudioOutputs); 102 _FindNodes(B_MEDIA_ENCODED_AUDIO, B_PHYSICAL_INPUT, fAudioInputs); 103 _FindNodes(B_MEDIA_RAW_VIDEO, B_PHYSICAL_OUTPUT, fVideoOutputs); 104 _FindNodes(B_MEDIA_RAW_VIDEO, B_PHYSICAL_INPUT, fVideoInputs); 105 _FindNodes(B_MEDIA_ENCODED_VIDEO, B_PHYSICAL_OUTPUT, fVideoOutputs); 106 _FindNodes(B_MEDIA_ENCODED_VIDEO, B_PHYSICAL_INPUT, fVideoInputs); 107 } 108 109 110 void 111 MediaWindow::_FindNodes(media_type type, uint64 kind, NodeList& into) 112 { 113 dormant_node_info node_info[64]; 114 int32 node_info_count = 64; 115 media_format format; 116 media_format* format1 = NULL, *format2 = NULL; 117 BMediaRoster* roster = BMediaRoster::Roster(); 118 format.type = type; 119 120 if (kind & B_PHYSICAL_OUTPUT) 121 format1 = &format; 122 else if (kind & B_PHYSICAL_INPUT) 123 format2 = &format; 124 else 125 return; 126 127 if (roster->GetDormantNodes(node_info, &node_info_count, format1, format2, 128 NULL, kind)!=B_OK) { 129 // TODO: better error reporting! 130 fprintf(stderr, "error\n"); 131 return; 132 } 133 134 for (int32 i = 0; i < node_info_count; i++) { 135 PRINT(("node : %s, media_addon %i, flavor_id %i\n", 136 node_info[i].name, node_info[i].addon, node_info[i].flavor_id)); 137 138 dormant_node_info* info = new dormant_node_info(); 139 strncpy(info->name, node_info[i].name, B_MEDIA_NAME_LENGTH); 140 info->flavor_id = node_info[i].flavor_id; 141 info->addon = node_info[i].addon; 142 into.AddItem(info); 143 } 144 } 145 146 147 MediaListItem * 148 MediaWindow::FindMediaListItem(dormant_node_info* info) 149 { 150 for (int32 j = 0; j<fListView->CountItems(); j++) { 151 MediaListItem* item 152 = static_cast<MediaListItem *>(fListView->ItemAt(j)); 153 if (item->fInfo && item->fInfo->addon == info->addon 154 && item->fInfo->flavor_id == info->flavor_id) { 155 return item; 156 break; 157 } 158 } 159 return NULL; 160 } 161 162 163 void 164 MediaWindow::_AddNodeItems(NodeList &list, bool isVideo) 165 { 166 int32 count = list.CountItems(); 167 for (int32 i = 0; i < count; i++) { 168 dormant_node_info* info = list.ItemAt(i); 169 if (!FindMediaListItem(info)) 170 fListView->AddItem(new MediaListItem(info, 1, isVideo, &fIcons)); 171 } 172 } 173 174 175 void 176 MediaWindow::_EmptyNodeLists() 177 { 178 fAudioOutputs.MakeEmpty(); 179 fAudioInputs.MakeEmpty(); 180 fVideoOutputs.MakeEmpty(); 181 fVideoInputs.MakeEmpty(); 182 } 183 184 185 void 186 MediaWindow::InitWindow(void) 187 { 188 // Bitmaps 189 BRect iconRect(0, 0, 15, 15); 190 BBitmap* icon = new BBitmap(iconRect, B_CMAP8); 191 icon->SetBits(kDevicesBits, kDevicesWidth * kDevicesHeight, 0, 192 kDevicesColorSpace); 193 fIcons.AddItem(icon); 194 icon = new BBitmap(iconRect, B_CMAP8); 195 icon->SetBits(kMixerBits, kMixerWidth * kMixerHeight, 0, 196 kMixerColorSpace); 197 fIcons.AddItem(icon); 198 icon = new BBitmap(iconRect, B_CMAP8); 199 icon->SetBits(kMicBits, kMicWidth * kMicHeight, 0, kMicColorSpace); 200 fIcons.AddItem(icon); 201 icon = new BBitmap(iconRect, B_CMAP8); 202 icon->SetBits(kSpeakerBits, kSpeakerWidth * kSpeakerHeight, 0, 203 kSpeakerColorSpace); 204 fIcons.AddItem(icon); 205 icon = new BBitmap(iconRect, B_CMAP8); 206 icon->SetBits(kCamBits, kCamWidth * kCamHeight, 0, kCamColorSpace); 207 fIcons.AddItem(icon); 208 icon = new BBitmap(iconRect, B_CMAP8); 209 icon->SetBits(kTVBits, kTVWidth * kTVHeight, 0, kTVColorSpace); 210 fIcons.AddItem(icon); 211 212 const float scrollWidth = 9 * be_plain_font->Size() + 30; 213 214 fListView = new BListView("media_list_view"); 215 fListView->SetSelectionMessage(new BMessage(ML_SELECTED_NODE)); 216 217 // Add ScrollView to Media Menu 218 BScrollView* scrollView = new BScrollView("listscroller", 219 fListView, 0, false, false, B_FANCY_BORDER); 220 scrollView->SetExplicitMinSize(BSize(scrollWidth, B_SIZE_UNSET)); 221 scrollView->SetExplicitMaxSize(BSize(scrollWidth, B_SIZE_UNSET)); 222 223 // Create the Views 224 fBox = new BBox("background", B_WILL_DRAW | B_FRAME_EVENTS, 225 B_PLAIN_BORDER); 226 SetLayout(new BGroupLayout(B_HORIZONTAL)); 227 GetLayout()->AddView(fBox); 228 229 // StringViews 230 fTitleView = new BSeparatorView(B_HORIZONTAL, B_FANCY_BORDER); 231 fTitleView->SetLabel(B_TRANSLATE("Audio settings")); 232 fTitleView->SetFont(be_bold_font); 233 234 fContentView = new BBox("contentView", B_WILL_DRAW | B_FRAME_EVENTS, 235 B_NO_BORDER); 236 237 fAudioView = new SettingsView(false); 238 fVideoView = new SettingsView(true); 239 240 241 // Layout all views 242 BGroupView* rightView = new BGroupView(B_VERTICAL, 5); 243 rightView->GroupLayout()->SetInsets(14, 0, 0, 0); 244 rightView->GroupLayout()->AddView(fTitleView); 245 rightView->GroupLayout()->AddView(fContentView); 246 247 BGroupLayout* rootLayout = new BGroupLayout(B_HORIZONTAL); 248 rootLayout->SetInsets(14, 14, 14, 14); 249 fBox->SetLayout(rootLayout); 250 251 rootLayout->AddView(scrollView); 252 253 rootLayout->AddView(rightView); 254 255 // Start the window 256 fInitCheck = InitMedia(true); 257 if (fInitCheck != B_OK) { 258 PostMessage(B_QUIT_REQUESTED); 259 } else { 260 if (IsHidden()) 261 Show(); 262 } 263 } 264 265 266 // #pragma mark - 267 268 269 status_t 270 MediaWindow::InitMedia(bool first) 271 { 272 status_t err = B_OK; 273 BMediaRoster* roster = BMediaRoster::Roster(&err); 274 275 if (first && err != B_OK) { 276 BAlert* alert = new BAlert("start_media_server", 277 B_TRANSLATE("Could not connect to the media server.\n" 278 "Would you like to start it ?"), 279 B_TRANSLATE("Quit"), 280 B_TRANSLATE("Start media server"), NULL, 281 B_WIDTH_AS_USUAL, B_WARNING_ALERT); 282 if (alert->Go()==0) 283 return B_ERROR; 284 285 fAlert = new MediaAlert(BRect(0, 0, 300, 60), 286 "restart_alert", B_TRANSLATE( 287 "Restarting media services\nStarting media server" 288 B_UTF8_ELLIPSIS "\n")); 289 fAlert->Show(); 290 291 Show(); 292 293 launch_media_server(); 294 } 295 296 Lock(); 297 298 bool isVideoSelected = true; 299 if (!first && fListView->ItemAt(0) && fListView->ItemAt(0)->IsSelected()) 300 isVideoSelected = false; 301 302 if ((!first || (first && err) ) && fAlert) { 303 BAutolock locker(fAlert); 304 if (locker.IsLocked()) 305 fAlert->TextView()->SetText( 306 B_TRANSLATE("Ready for use" B_UTF8_ELLIPSIS)); 307 } 308 309 _EmptyNodeLists(); 310 311 // Grab Media Info 312 _FindNodes(); 313 314 // Add video nodes first. They might have an additional audio 315 // output or input, but still should be listed as video node. 316 _AddNodeItems(fVideoOutputs, true); 317 _AddNodeItems(fVideoInputs, true); 318 _AddNodeItems(fAudioOutputs, false); 319 _AddNodeItems(fAudioInputs, false); 320 321 fAudioView->AddNodes(fAudioOutputs, false); 322 fAudioView->AddNodes(fAudioInputs, true); 323 fVideoView->AddNodes(fVideoOutputs, false); 324 fVideoView->AddNodes(fVideoInputs, true); 325 326 // build our list view 327 MediaListItem* audio = new MediaListItem(B_TRANSLATE("Audio settings"), 0, 328 false, &fIcons); 329 fListView->AddItem(audio); 330 331 MediaListItem* video = new MediaListItem(B_TRANSLATE("Video settings"), 0, 332 true, &fIcons); 333 fListView->AddItem(video); 334 335 MediaListItem* mixer = new MediaListItem(B_TRANSLATE("Audio mixer"), 336 1, false, &fIcons); 337 fListView->AddItem(mixer); 338 mixer->SetAudioMixer(true); 339 340 fListView->SortItems(&MediaListItem::Compare); 341 342 // Set default nodes for our setting views 343 media_node default_node; 344 dormant_node_info node_info; 345 int32 outputID; 346 BString outputName; 347 348 if (roster->GetAudioInput(&default_node) == B_OK) { 349 roster->GetDormantNodeFor(default_node, &node_info); 350 MediaListItem* item = FindMediaListItem(&node_info); 351 if (item) 352 item->SetDefault(true, true); 353 fAudioView->SetDefault(node_info, true); 354 } 355 356 if (roster->GetAudioOutput(&default_node, &outputID, &outputName)==B_OK) { 357 roster->GetDormantNodeFor(default_node, &node_info); 358 MediaListItem* item = FindMediaListItem(&node_info); 359 if (item) 360 item->SetDefault(true, false); 361 fAudioView->SetDefault(node_info, false, outputID); 362 } 363 364 if (roster->GetVideoInput(&default_node)==B_OK) { 365 roster->GetDormantNodeFor(default_node, &node_info); 366 MediaListItem* item = FindMediaListItem(&node_info); 367 if (item) 368 item->SetDefault(true, true); 369 fVideoView->SetDefault(node_info, true); 370 } 371 372 if (roster->GetVideoOutput(&default_node)==B_OK) { 373 roster->GetDormantNodeFor(default_node, &node_info); 374 MediaListItem* item = FindMediaListItem(&node_info); 375 if (item) 376 item->SetDefault(true, false); 377 fVideoView->SetDefault(node_info, false); 378 } 379 380 if (first) { 381 fListView->Select(fListView->IndexOf(mixer)); 382 } else { 383 if (!fAudioView->fRestartView->IsHidden()) 384 fAudioView->fRestartView->Hide(); 385 if (!fVideoView->fRestartView->IsHidden()) 386 fVideoView->fRestartView->Hide(); 387 388 if (isVideoSelected) 389 fListView->Select(fListView->IndexOf(video)); 390 else 391 fListView->Select(fListView->IndexOf(audio)); 392 } 393 394 if (fAlert) { 395 snooze(800000); 396 fAlert->PostMessage(B_QUIT_REQUESTED); 397 } 398 fAlert = NULL; 399 400 Unlock(); 401 402 return B_OK; 403 } 404 405 406 bool 407 MediaWindow::QuitRequested() 408 { 409 // stop watching the MediaRoster 410 BMediaRoster* roster = BMediaRoster::CurrentRoster(); 411 if (roster && fCurrentNode) { 412 roster->StopWatching(this, *fCurrentNode, B_MEDIA_WILDCARD); 413 } 414 be_app->PostMessage(B_QUIT_REQUESTED); 415 return true; 416 } 417 418 419 void 420 MediaWindow::FrameResized (float width, float height) 421 { 422 // This makes sure our SideBar colours down to the bottom when resized 423 BRect r; 424 r = Bounds(); 425 } 426 427 428 // ErrorAlert -- Displays a BAlert Box with a Custom Error or Debug Message 429 void 430 ErrorAlert(char* errorMessage) { 431 printf("%s\n", errorMessage); 432 BAlert* alert = new BAlert("BAlert", errorMessage, B_TRANSLATE("OK"), 433 NULL, NULL, B_WIDTH_AS_USUAL, B_STOP_ALERT); 434 alert->Go(); 435 exit(1); 436 } 437 438 439 void 440 MediaWindow::MessageReceived(BMessage* message) 441 { 442 switch(message->what) 443 { 444 case ML_INIT_MEDIA: 445 InitMedia(false); 446 break; 447 case ML_DEFAULTOUTPUT_CHANGE: 448 { 449 int32 index; 450 if (message->FindInt32("index", &index)!=B_OK) 451 break; 452 Settings2Item* item = static_cast<Settings2Item*>( 453 fAudioView->fMenu3->ItemAt(index)); 454 455 if (item) { 456 BMediaRoster* roster = BMediaRoster::Roster(); 457 roster->SetAudioOutput(*item->fInput); 458 459 if (fAudioView->fRestartView->IsHidden()) 460 fAudioView->fRestartView->Show(); 461 } else 462 fprintf(stderr, "Settings2Item not found\n"); 463 } 464 break; 465 case ML_DEFAULT_CHANGE: 466 { 467 bool isVideo = true; 468 bool isInput = true; 469 if (message->FindBool("isVideo", &isVideo)!=B_OK) 470 break; 471 if (message->FindBool("isInput", &isInput)!=B_OK) 472 break; 473 int32 index; 474 if (message->FindInt32("index", &index)!=B_OK) 475 break; 476 SettingsView* settingsView = isVideo ? fVideoView : fAudioView; 477 BMenu* menu = isInput ? settingsView->fMenu1 478 : settingsView->fMenu2; 479 SettingsItem* item = static_cast<SettingsItem*>( 480 menu->ItemAt(index)); 481 482 if (item) { 483 PRINT(("isVideo %i isInput %i\n", isVideo, isInput)); 484 BMediaRoster* roster = BMediaRoster::Roster(); 485 if (isVideo) { 486 if (isInput) 487 roster->SetVideoInput(*item->fInfo); 488 else 489 roster->SetVideoOutput(*item->fInfo); 490 } else { 491 if (isInput) 492 roster->SetAudioInput(*item->fInfo); 493 else { 494 roster->SetAudioOutput(*item->fInfo); 495 fAudioView->SetDefault(*item->fInfo, false, 0); 496 } 497 } 498 499 MediaListItem* oldListItem = NULL; 500 for (int32 j = 0; j < fListView->CountItems(); j++) { 501 oldListItem = static_cast<MediaListItem*>( 502 fListView->ItemAt(j)); 503 if (oldListItem->fInfo 504 && oldListItem->IsVideo() == isVideo 505 && oldListItem->IsDefault(isInput)) 506 break; 507 } 508 if (oldListItem) 509 oldListItem->SetDefault(false, isInput); 510 else 511 fprintf(stderr, "oldListItem not found\n"); 512 513 MediaListItem* listItem = FindMediaListItem(item->fInfo); 514 if (listItem) { 515 listItem->SetDefault(true, isInput); 516 } else 517 fprintf(stderr, "MediaListItem not found\n"); 518 fListView->Invalidate(); 519 520 if (settingsView->fRestartView->IsHidden()) 521 settingsView->fRestartView->Show(); 522 } else 523 fprintf(stderr, "SettingsItem not found\n"); 524 } 525 break; 526 case ML_RESTART_MEDIA_SERVER: 527 { 528 thread_id thread = spawn_thread(&MediaWindow::RestartMediaServices, 529 "restart_thread", B_NORMAL_PRIORITY, this); 530 if (thread < B_OK) 531 fprintf(stderr, "couldn't create restart thread\n"); 532 else 533 resume_thread(thread); 534 break; 535 } 536 case ML_SHOW_VOLUME_CONTROL: 537 { 538 BDeskbar deskbar; 539 if (fAudioView->fVolumeCheckBox->Value() == B_CONTROL_ON) { 540 BEntry entry("/bin/desklink", true); 541 int32 id; 542 entry_ref ref; 543 status_t status = entry.GetRef(&ref); 544 if (status == B_OK) 545 status = deskbar.AddItem(&ref, &id); 546 547 if (status != B_OK) { 548 fprintf(stderr, B_TRANSLATE( 549 "Couldn't add volume control in Deskbar: %s\n"), 550 strerror(status)); 551 } 552 } else { 553 status_t status = deskbar.RemoveItem("MediaReplicant"); 554 if (status != B_OK) { 555 fprintf(stderr, B_TRANSLATE( 556 "Couldn't remove volume control in Deskbar: %s\n"), 557 strerror(status)); 558 } 559 } 560 break; 561 } 562 case ML_ENABLE_REAL_TIME: 563 { 564 bool isVideo = true; 565 if (message->FindBool("isVideo", &isVideo)!=B_OK) 566 break; 567 SettingsView* settingsView = isVideo ? fVideoView : fAudioView; 568 uint32 flags; 569 uint32 realtimeFlag = isVideo 570 ? B_MEDIA_REALTIME_VIDEO : B_MEDIA_REALTIME_AUDIO; 571 BMediaRoster* roster = BMediaRoster::Roster(); 572 roster->GetRealtimeFlags(&flags); 573 if (settingsView->fRealtimeCheckBox->Value() == B_CONTROL_ON) 574 flags |= realtimeFlag; 575 else 576 flags &= ~realtimeFlag; 577 roster->SetRealtimeFlags(flags); 578 } 579 break; 580 case B_MEDIA_WEB_CHANGED: 581 case ML_SELECTED_NODE: 582 { 583 PRINT_OBJECT(*message); 584 585 MediaListItem* item = static_cast<MediaListItem*>( 586 fListView->ItemAt(fListView->CurrentSelection())); 587 if (!item) 588 break; 589 BMediaRoster* roster = BMediaRoster::Roster(); 590 if (fCurrentNode) { 591 // stop watching the MediaRoster 592 roster->StopWatching(this, *fCurrentNode, B_MEDIA_WILDCARD); 593 roster->ReleaseNode(*fCurrentNode); 594 } 595 fCurrentNode = NULL; 596 BView* paramView = fContentView->ChildAt(0); 597 if (paramView!=NULL) { 598 fContentView->RemoveChild(paramView); 599 } 600 paramView = NULL; 601 if (fParamWeb) 602 delete fParamWeb; 603 fParamWeb = NULL; 604 605 fTitleView->SetLabel(item->GetLabel()); 606 607 if (item->OutlineLevel() == 0) { 608 if (item->IsVideo()) 609 fContentView->AddChild(fVideoView); 610 else 611 fContentView->AddChild(fAudioView); 612 } else { 613 614 if (!fCurrentNode) 615 fCurrentNode = new media_node(); 616 media_node_id node_id; 617 if (item->IsAudioMixer()) 618 roster->GetAudioMixer(fCurrentNode); 619 else if (roster->GetInstancesFor(item->fInfo->addon, item->fInfo->flavor_id, &node_id)!=B_OK) 620 roster->InstantiateDormantNode(*(item->fInfo), fCurrentNode, B_FLAVOR_IS_GLOBAL); 621 else 622 roster->GetNodeFor(node_id, fCurrentNode); 623 624 if (roster->GetParameterWebFor(*fCurrentNode, &fParamWeb)==B_OK 625 && (paramView = BMediaTheme::PreferredTheme()->ViewFor(fParamWeb)) != NULL) { 626 fContentView->AddChild(paramView); 627 paramView->ResizeTo(fContentView->Bounds().Width(), fContentView->Bounds().Height() - 10); 628 629 roster->StartWatching(this, *fCurrentNode, B_MEDIA_WILDCARD); 630 } else { 631 delete fParamWeb; 632 fParamWeb = NULL; 633 634 BRect bounds = fContentView->Bounds(); 635 BStringView* stringView = new BStringView(bounds, 636 "noControls", B_TRANSLATE("This hardware has no controls."), 637 B_FOLLOW_V_CENTER | B_FOLLOW_H_CENTER); 638 stringView->ResizeToPreferred(); 639 fContentView->AddChild(stringView); 640 stringView->MoveBy((bounds.Width()-stringView->Bounds().Width())/2, 641 (bounds.Height()-stringView->Bounds().Height())/2); 642 } 643 } 644 } 645 break; 646 case B_SOME_APP_LAUNCHED: 647 { 648 PRINT_OBJECT(*message); 649 if (!fAlert) 650 break; 651 652 BString mimeSig; 653 if (message->FindString("be:signature", &mimeSig) == B_OK 654 && (mimeSig == "application/x-vnd.Be.addon-host" 655 || mimeSig == "application/x-vnd.Be.media-server")) { 656 fAlert->Lock(); 657 fAlert->TextView()->SetText( 658 B_TRANSLATE("Starting media server" B_UTF8_ELLIPSIS)); 659 fAlert->Unlock(); 660 } 661 } 662 break; 663 case B_SOME_APP_QUIT: 664 { 665 PRINT_OBJECT(*message); 666 BString mimeSig; 667 if (message->FindString("be:signature", &mimeSig) == B_OK) { 668 if (mimeSig == "application/x-vnd.Be.addon-host" 669 || mimeSig == "application/x-vnd.Be.media-server") { 670 BMediaRoster* roster = BMediaRoster::CurrentRoster(); 671 if (roster && roster->Lock()) 672 roster->Quit(); 673 } 674 } 675 676 } 677 break; 678 default: 679 BWindow::MessageReceived(message); 680 break; 681 } 682 } 683 684 status_t 685 MediaWindow::RestartMediaServices(void* data) 686 { 687 MediaWindow* window = (MediaWindow*)data; 688 window->fAlert = new MediaAlert(BRect(0, 0, 300, 60), 689 "restart_alert", B_TRANSLATE( 690 "Restarting media services\nShutting down media server\n")); 691 692 window->fAlert->Show(); 693 694 shutdown_media_server(B_INFINITE_TIMEOUT, MediaWindow::UpdateProgress, 695 window->fAlert); 696 697 { 698 BAutolock locker(window->fAlert); 699 if (locker.IsLocked()) 700 window->fAlert->TextView()->SetText( 701 B_TRANSLATE("Starting media server" B_UTF8_ELLIPSIS)); 702 } 703 launch_media_server(); 704 705 return window->PostMessage(ML_INIT_MEDIA); 706 } 707 708 709 bool 710 MediaWindow::UpdateProgress(int stage, const char * message, void * cookie) 711 { 712 MediaAlert* alert = static_cast<MediaAlert*>(cookie); 713 PRINT(("stage : %i\n", stage)); 714 const char* string = "Unknown stage"; 715 switch (stage) { 716 case 10: 717 string = B_TRANSLATE("Stopping media server" B_UTF8_ELLIPSIS); 718 break; 719 case 20: 720 string = B_TRANSLATE("Telling media_addon_server to quit."); 721 break; 722 case 40: 723 string = B_TRANSLATE("Waiting for media_server to quit."); 724 break; 725 case 70: 726 string = B_TRANSLATE("Cleaning up."); 727 break; 728 case 100: 729 string = B_TRANSLATE("Done shutting down."); 730 break; 731 } 732 733 BAutolock locker(alert); 734 if (locker.IsLocked()) 735 alert->TextView()->SetText(string); 736 return true; 737 } 738 739