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 <SpaceLayoutItem.h> 30 #include <StorageKit.h> 31 #include <String.h> 32 #include <TextView.h> 33 34 // Images 35 #include "iconfile.h" 36 37 38 #undef B_TRANSLATE_CONTEXT 39 #define B_TRANSLATE_CONTEXT "Media Window" 40 41 42 const uint32 ML_SELECTED_NODE = 'MlSN'; 43 const uint32 ML_INIT_MEDIA = 'MlIM'; 44 45 // MediaWindow - Constructor 46 MediaWindow::MediaWindow(BRect frame) 47 : 48 BWindow (frame, B_TRANSLATE("Media"), B_TITLED_WINDOW, 49 B_ASYNCHRONOUS_CONTROLS | B_AUTO_UPDATE_SIZE_LIMITS), 50 fCurrentNode(NULL), 51 fParamWeb(NULL), 52 fAlert(NULL), 53 fInitCheck(B_OK) 54 { 55 InitWindow(); 56 } 57 58 59 status_t 60 MediaWindow::InitCheck() 61 { 62 return fInitCheck; 63 } 64 65 66 MediaWindow::~MediaWindow() 67 { 68 for (int i = 0; i < fAudioOutputs.CountItems(); i++) 69 delete static_cast<dormant_node_info*>(fAudioOutputs.ItemAt(i)); 70 for (int i = 0; i < fAudioInputs.CountItems(); i++) 71 delete static_cast<dormant_node_info*>(fAudioInputs.ItemAt(i)); 72 for (int i = 0; i < fVideoOutputs.CountItems(); i++) 73 delete static_cast<dormant_node_info*>(fVideoOutputs.ItemAt(i)); 74 for (int i = 0; i < fVideoInputs.CountItems(); i++) 75 delete static_cast<dormant_node_info*>(fVideoInputs.ItemAt(i)); 76 77 BMediaRoster* roster = BMediaRoster::Roster(); 78 if (roster && fCurrentNode) 79 roster->ReleaseNode(*fCurrentNode); 80 81 char buffer[512]; 82 BRect rect = Frame(); 83 PRINT_OBJECT(rect); 84 sprintf(buffer, "# MediaPrefs Settings\n rect = %i,%i,%i,%i\n", 85 int(rect.left), int(rect.top), int(rect.right), int(rect.bottom)); 86 87 BPath path; 88 if (find_directory(B_USER_SETTINGS_DIRECTORY, &path) == B_OK) { 89 path.Append(SETTINGS_FILE); 90 BFile file(path.Path(), B_READ_WRITE|B_CREATE_FILE|B_ERASE_FILE); 91 if (file.InitCheck()==B_OK) { 92 file.Write(buffer, strlen(buffer)); 93 } 94 } 95 } 96 97 98 void 99 MediaWindow::FindNodes(media_type type, uint64 kind, BList &list) 100 { 101 dormant_node_info node_info[64]; 102 int32 node_info_count = 64; 103 media_format format; 104 media_format* format1 = NULL, *format2 = NULL; 105 BMediaRoster* roster = BMediaRoster::Roster(); 106 format.type = type; 107 108 if (kind & B_PHYSICAL_OUTPUT) 109 format1 = &format; 110 else if (kind & B_PHYSICAL_INPUT) 111 format2 = &format; 112 else 113 return; 114 115 if (roster->GetDormantNodes(node_info, &node_info_count, format1, format2, 116 NULL, kind)!=B_OK) { 117 fprintf(stderr, "error\n"); 118 return; 119 } 120 121 for (int32 i = 0; i<node_info_count; i++) { 122 PRINT(("node : %s, media_addon %i, flavor_id %i\n", 123 node_info[i].name, node_info[i].addon, node_info[i].flavor_id)); 124 dormant_node_info* info = new dormant_node_info(); 125 strcpy(info->name, node_info[i].name); 126 info->flavor_id = node_info[i].flavor_id; 127 info->addon = node_info[i].addon; 128 list.AddItem(info); 129 } 130 } 131 132 133 MediaListItem * 134 MediaWindow::FindMediaListItem(dormant_node_info* info) 135 { 136 for (int32 j = 0; j<fListView->CountItems(); j++) { 137 MediaListItem* item 138 = static_cast<MediaListItem *>(fListView->ItemAt(j)); 139 if (item->fInfo && item->fInfo->addon == info->addon 140 && item->fInfo->flavor_id == info->flavor_id) { 141 return item; 142 break; 143 } 144 } 145 return NULL; 146 } 147 148 149 void 150 MediaWindow::AddNodes(BList &list, bool isVideo) 151 { 152 for (int32 i = 0; i<list.CountItems(); i++) { 153 dormant_node_info* info 154 = static_cast<dormant_node_info*>(list.ItemAt(i)); 155 if (!FindMediaListItem(info)) 156 fListView->AddItem(new MediaListItem(info, 1, isVideo, &fIcons)); 157 } 158 } 159 160 161 void 162 MediaWindow::InitWindow(void) 163 { 164 // Bitmaps 165 BRect iconRect(0, 0, 15, 15); 166 BBitmap* icon = new BBitmap(iconRect, B_CMAP8); 167 icon->SetBits(kDevicesBits, kDevicesWidth * kDevicesHeight, 0, 168 kDevicesColorSpace); 169 fIcons.AddItem(icon); 170 icon = new BBitmap(iconRect, B_CMAP8); 171 icon->SetBits(kMixerBits, kMixerWidth * kMixerHeight, 0, 172 kMixerColorSpace); 173 fIcons.AddItem(icon); 174 icon = new BBitmap(iconRect, B_CMAP8); 175 icon->SetBits(kMicBits, kMicWidth * kMicHeight, 0, kMicColorSpace); 176 fIcons.AddItem(icon); 177 icon = new BBitmap(iconRect, B_CMAP8); 178 icon->SetBits(kSpeakerBits, kSpeakerWidth * kSpeakerHeight, 0, 179 kSpeakerColorSpace); 180 fIcons.AddItem(icon); 181 icon = new BBitmap(iconRect, B_CMAP8); 182 icon->SetBits(kCamBits, kCamWidth * kCamHeight, 0, kCamColorSpace); 183 fIcons.AddItem(icon); 184 icon = new BBitmap(iconRect, B_CMAP8); 185 icon->SetBits(kTVBits, kTVWidth * kTVHeight, 0, kTVColorSpace); 186 fIcons.AddItem(icon); 187 188 const float scrollWidth = 9 * be_plain_font->Size() + 30; 189 190 fListView = new BListView("media_list_view"); 191 fListView->SetSelectionMessage(new BMessage(ML_SELECTED_NODE)); 192 193 // Add ScrollView to Media Menu 194 BScrollView* scrollView = new BScrollView("listscroller", 195 fListView, 0, false, false, B_FANCY_BORDER); 196 scrollView->SetExplicitMinSize(BSize(scrollWidth, B_SIZE_UNSET)); 197 scrollView->SetExplicitMaxSize(BSize(scrollWidth, B_SIZE_UNSET)); 198 199 // Create the Views 200 fBox = new BBox("background", B_WILL_DRAW | B_FRAME_EVENTS, 201 B_PLAIN_BORDER); 202 SetLayout(new BGroupLayout(B_HORIZONTAL)); 203 GetLayout()->AddView(fBox); 204 205 // StringViews 206 rgb_color titleFontColor = { 0, 0, 0, 0 }; 207 fTitleView = new BStringView("AudioSettings", 208 B_TRANSLATE("Audio settings"), B_WILL_DRAW); 209 fTitleView->SetFont(be_bold_font); 210 fTitleView->SetHighColor(titleFontColor); 211 212 fContentView = new BBox("contentView", B_WILL_DRAW | B_FRAME_EVENTS, 213 B_NO_BORDER); 214 215 fAudioView = new SettingsView(false); 216 fVideoView = new SettingsView(true); 217 218 fBar = new BarView(); 219 BGroupView* titleGroupView = new BGroupView(B_HORIZONTAL); 220 titleGroupView->GroupLayout()->AddView(fTitleView); 221 titleGroupView->GroupLayout()->AddItem(BSpaceLayoutItem::CreateGlue()); 222 223 // Layout all views 224 BGroupView* rightView = new BGroupView(B_VERTICAL, 5); 225 rightView->GroupLayout()->SetInsets(14, 0, 0, 0); 226 rightView->GroupLayout()->AddView(titleGroupView); 227 rightView->GroupLayout()->AddView(fBar, 0); 228 rightView->GroupLayout()->AddView(fContentView); 229 230 BGroupLayout* rootLayout = new BGroupLayout(B_HORIZONTAL); 231 rootLayout->SetInsets(14, 14, 14, 14); 232 fBox->SetLayout(rootLayout); 233 234 rootLayout->AddView(scrollView); 235 236 rootLayout->AddView(rightView); 237 238 // Start the window 239 fInitCheck = InitMedia(true); 240 if (fInitCheck != B_OK) { 241 PostMessage(B_QUIT_REQUESTED); 242 } else { 243 if (IsHidden()) 244 Show(); 245 } 246 } 247 248 249 // #pragma mark - 250 251 252 status_t 253 MediaWindow::InitMedia(bool first) 254 { 255 status_t err = B_OK; 256 BMediaRoster* roster = BMediaRoster::Roster(&err); 257 258 if (first && err != B_OK) { 259 BAlert* alert = new BAlert("start_media_server", 260 B_TRANSLATE("Could not connect to the media server.\n" 261 "Would you like to start it ?"), 262 B_TRANSLATE("Quit"), 263 B_TRANSLATE("Start media server"), NULL, 264 B_WIDTH_AS_USUAL, B_WARNING_ALERT); 265 if (alert->Go()==0) 266 return B_ERROR; 267 268 fAlert = new MediaAlert(BRect(0, 0, 300, 60), 269 "restart_alert", B_TRANSLATE( 270 "Restarting media services\nStarting media server" 271 B_UTF8_ELLIPSIS "\n")); 272 fAlert->Show(); 273 274 Show(); 275 276 launch_media_server(); 277 } 278 279 Lock(); 280 281 bool isVideoSelected = true; 282 if (!first && fListView->ItemAt(0) && fListView->ItemAt(0)->IsSelected()) 283 isVideoSelected = false; 284 285 if ((!first || (first && err) ) && fAlert) { 286 BAutolock locker(fAlert); 287 if (locker.IsLocked()) 288 fAlert->TextView()->SetText( 289 B_TRANSLATE("Ready for use" B_UTF8_ELLIPSIS)); 290 } 291 292 void* listItem; 293 while ((listItem = fListView->RemoveItem((int32)0))) 294 delete static_cast<MediaListItem *>(listItem); 295 while ((listItem = fAudioOutputs.RemoveItem((int32)0))) 296 delete static_cast<dormant_node_info *>(listItem); 297 while ((listItem = fAudioInputs.RemoveItem((int32)0))) 298 delete static_cast<dormant_node_info *>(listItem); 299 while ((listItem = fVideoOutputs.RemoveItem((int32)0))) 300 delete static_cast<dormant_node_info *>(listItem); 301 while ((listItem = fVideoInputs.RemoveItem((int32)0))) 302 delete static_cast<dormant_node_info *>(listItem); 303 304 // Grab Media Info 305 FindNodes(B_MEDIA_RAW_AUDIO, B_PHYSICAL_OUTPUT, fAudioOutputs); 306 FindNodes(B_MEDIA_RAW_AUDIO, B_PHYSICAL_INPUT, fAudioInputs); 307 FindNodes(B_MEDIA_ENCODED_AUDIO, B_PHYSICAL_OUTPUT, fAudioOutputs); 308 FindNodes(B_MEDIA_ENCODED_AUDIO, B_PHYSICAL_INPUT, fAudioInputs); 309 FindNodes(B_MEDIA_RAW_VIDEO, B_PHYSICAL_OUTPUT, fVideoOutputs); 310 FindNodes(B_MEDIA_RAW_VIDEO, B_PHYSICAL_INPUT, fVideoInputs); 311 FindNodes(B_MEDIA_ENCODED_VIDEO, B_PHYSICAL_OUTPUT, fVideoOutputs); 312 FindNodes(B_MEDIA_ENCODED_VIDEO, B_PHYSICAL_INPUT, fVideoInputs); 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 AddNodes(fVideoOutputs, true); 317 AddNodes(fVideoInputs, true); 318 AddNodes(fAudioOutputs, false); 319 AddNodes(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->SetText(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 bool barChanged = (item->OutlineLevel() == 0 646 || fParamWeb == NULL || fParamWeb->CountGroups()<2); 647 if (barChanged != fBar->fDisplay) { 648 fBar->fDisplay = barChanged; 649 fBar->Invalidate(); 650 } 651 } 652 break; 653 case B_SOME_APP_LAUNCHED: 654 { 655 PRINT_OBJECT(*message); 656 if (!fAlert) 657 break; 658 659 BString mimeSig; 660 if (message->FindString("be:signature", &mimeSig) == B_OK 661 && (mimeSig == "application/x-vnd.Be.addon-host" 662 || mimeSig == "application/x-vnd.Be.media-server")) { 663 fAlert->Lock(); 664 fAlert->TextView()->SetText( 665 B_TRANSLATE("Starting media server" B_UTF8_ELLIPSIS)); 666 fAlert->Unlock(); 667 } 668 } 669 break; 670 case B_SOME_APP_QUIT: 671 { 672 PRINT_OBJECT(*message); 673 BString mimeSig; 674 if (message->FindString("be:signature", &mimeSig) == B_OK) { 675 if (mimeSig == "application/x-vnd.Be.addon-host" 676 || mimeSig == "application/x-vnd.Be.media-server") { 677 BMediaRoster* roster = BMediaRoster::CurrentRoster(); 678 if (roster && roster->Lock()) 679 roster->Quit(); 680 } 681 } 682 683 } 684 break; 685 default: 686 BWindow::MessageReceived(message); 687 break; 688 } 689 } 690 691 status_t 692 MediaWindow::RestartMediaServices(void* data) 693 { 694 MediaWindow* window = (MediaWindow*)data; 695 window->fAlert = new MediaAlert(BRect(0, 0, 300, 60), 696 "restart_alert", B_TRANSLATE( 697 "Restarting media services\nShutting down media server\n")); 698 699 window->fAlert->Show(); 700 701 shutdown_media_server(B_INFINITE_TIMEOUT, MediaWindow::UpdateProgress, 702 window->fAlert); 703 704 { 705 BAutolock locker(window->fAlert); 706 if (locker.IsLocked()) 707 window->fAlert->TextView()->SetText( 708 B_TRANSLATE("Starting media server" B_UTF8_ELLIPSIS)); 709 } 710 launch_media_server(); 711 712 return window->PostMessage(ML_INIT_MEDIA); 713 } 714 715 716 bool 717 MediaWindow::UpdateProgress(int stage, const char * message, void * cookie) 718 { 719 MediaAlert* alert = static_cast<MediaAlert*>(cookie); 720 PRINT(("stage : %i\n", stage)); 721 const char* string = "Unknown stage"; 722 switch (stage) { 723 case 10: 724 string = B_TRANSLATE("Stopping media server" B_UTF8_ELLIPSIS); 725 break; 726 case 20: 727 string = B_TRANSLATE("Telling media_addon_server to quit."); 728 break; 729 case 40: 730 string = B_TRANSLATE("Waiting for media_server to quit."); 731 break; 732 case 70: 733 string = B_TRANSLATE("Cleaning up."); 734 break; 735 case 100: 736 string = B_TRANSLATE("Done shutting down."); 737 break; 738 } 739 740 BAutolock locker(alert); 741 if (locker.IsLocked()) 742 alert->TextView()->SetText(string); 743 return true; 744 } 745 746