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 <stdio.h> 11 12 #include <Alert.h> 13 #include <Application.h> 14 #include <Autolock.h> 15 #include <Bitmap.h> 16 #include <Button.h> 17 #include <Catalog.h> 18 #include <Debug.h> 19 #include <Deskbar.h> 20 #include <GroupView.h> 21 #include <Locale.h> 22 #include <MediaTheme.h> 23 #include <MediaRoster.h> 24 #include <Roster.h> 25 #include <Screen.h> 26 #include <ScrollView.h> 27 #include <SpaceLayoutItem.h> 28 #include <StorageKit.h> 29 #include <String.h> 30 #include <TextView.h> 31 #include "MediaWindow.h" 32 33 // Images 34 #include "iconfile.h" 35 36 37 #undef B_TRANSLATE_CONTEXT 38 #define B_TRANSLATE_CONTEXT "Media Window" 39 40 41 const uint32 ML_SELECTED_NODE = 'MlSN'; 42 const uint32 ML_INIT_MEDIA = 'MlIM'; 43 44 // MediaWindow - Constructor 45 MediaWindow::MediaWindow(BRect frame) 46 : BWindow (frame, B_TRANSLATE("Media"), B_TITLED_WINDOW, 47 B_ASYNCHRONOUS_CONTROLS | B_AUTO_UPDATE_SIZE_LIMITS), 48 fCurrentNode(NULL), 49 fParamWeb(NULL), 50 fAlert(NULL), 51 fInitCheck(B_OK) 52 { 53 InitWindow(); 54 } 55 56 57 status_t 58 MediaWindow::InitCheck() 59 { 60 return fInitCheck; 61 } 62 63 64 // MediaWindow - Destructor 65 MediaWindow::~MediaWindow() 66 { 67 for (int i = 0; i<fAudioOutputs.CountItems(); i++) 68 delete static_cast<dormant_node_info *>(fAudioOutputs.ItemAt(i)); 69 for (int i = 0; i<fAudioInputs.CountItems(); i++) 70 delete static_cast<dormant_node_info *>(fAudioInputs.ItemAt(i)); 71 for (int i = 0; i<fVideoOutputs.CountItems(); i++) 72 delete static_cast<dormant_node_info *>(fVideoOutputs.ItemAt(i)); 73 for (int i = 0; i<fVideoInputs.CountItems(); i++) 74 delete static_cast<dormant_node_info *>(fVideoInputs.ItemAt(i)); 75 76 BMediaRoster *roster = BMediaRoster::Roster(); 77 if (roster && fCurrentNode) 78 roster->ReleaseNode(*fCurrentNode); 79 80 char buffer[512]; 81 BRect rect = Frame(); 82 PRINT_OBJECT(rect); 83 sprintf(buffer, "# MediaPrefs Settings\n rect = %i,%i,%i,%i\n", 84 int(rect.left), int(rect.top), int(rect.right), int(rect.bottom)); 85 86 BPath path; 87 if (find_directory(B_USER_SETTINGS_DIRECTORY, &path) == B_OK) { 88 path.Append(SETTINGS_FILE); 89 BFile file(path.Path(), B_READ_WRITE|B_CREATE_FILE|B_ERASE_FILE); 90 if (file.InitCheck()==B_OK) { 91 file.Write(buffer, strlen(buffer)); 92 } 93 } 94 } 95 96 97 void 98 MediaWindow::FindNodes(media_type type, uint64 kind, BList &list) 99 { 100 dormant_node_info node_info[64]; 101 int32 node_info_count = 64; 102 media_format format; 103 media_format *format1 = NULL, *format2 = NULL; 104 BMediaRoster *roster = BMediaRoster::Roster(); 105 format.type = type; 106 107 if (kind & B_PHYSICAL_OUTPUT) 108 format1 = &format; 109 else if (kind & B_PHYSICAL_INPUT) 110 format2 = &format; 111 else 112 return; 113 114 if (roster->GetDormantNodes(node_info, &node_info_count, format1, format2, 115 NULL, kind)!=B_OK) { 116 fprintf(stderr, "error\n"); 117 return; 118 } 119 120 for (int32 i = 0; i<node_info_count; i++) { 121 PRINT(("node : %s, media_addon %i, flavor_id %i\n", 122 node_info[i].name, node_info[i].addon, node_info[i].flavor_id)); 123 dormant_node_info *info = new dormant_node_info(); 124 strcpy(info->name, node_info[i].name); 125 info->flavor_id = node_info[i].flavor_id; 126 info->addon = node_info[i].addon; 127 list.AddItem(info); 128 } 129 } 130 131 132 MediaListItem * 133 MediaWindow::FindMediaListItem(dormant_node_info *info) 134 { 135 for (int32 j = 0; j<fListView->CountItems(); j++) { 136 MediaListItem *item 137 = static_cast<MediaListItem *>(fListView->ItemAt(j)); 138 if (item->fInfo && item->fInfo->addon == info->addon 139 && item->fInfo->flavor_id == info->flavor_id) { 140 return item; 141 break; 142 } 143 } 144 return NULL; 145 } 146 147 148 void 149 MediaWindow::AddNodes(BList &list, bool isVideo) 150 { 151 for (int32 i = 0; i<list.CountItems(); i++) { 152 dormant_node_info *info 153 = static_cast<dormant_node_info *>(list.ItemAt(i)); 154 if (!FindMediaListItem(info)) 155 fListView->AddItem(new MediaListItem(info, 1, isVideo, &fIcons)); 156 } 157 } 158 159 160 // MediaWindow::InitWindow -- Initialization Commands here 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 MediaListItem *item, *mixer, *audio, *video; 305 306 // Grab Media Info 307 FindNodes(B_MEDIA_RAW_AUDIO, B_PHYSICAL_OUTPUT, fAudioOutputs); 308 FindNodes(B_MEDIA_RAW_AUDIO, B_PHYSICAL_INPUT, fAudioInputs); 309 FindNodes(B_MEDIA_ENCODED_AUDIO, B_PHYSICAL_OUTPUT, fAudioOutputs); 310 FindNodes(B_MEDIA_ENCODED_AUDIO, B_PHYSICAL_INPUT, fAudioInputs); 311 FindNodes(B_MEDIA_RAW_VIDEO, B_PHYSICAL_OUTPUT, fVideoOutputs); 312 FindNodes(B_MEDIA_RAW_VIDEO, B_PHYSICAL_INPUT, fVideoInputs); 313 FindNodes(B_MEDIA_ENCODED_VIDEO, B_PHYSICAL_OUTPUT, fVideoOutputs); 314 FindNodes(B_MEDIA_ENCODED_VIDEO, B_PHYSICAL_INPUT, fVideoInputs); 315 316 // Add video nodes first. They might have an additional audio 317 // output or input, but still should be listed as video node. 318 AddNodes(fVideoOutputs, true); 319 AddNodes(fVideoInputs, true); 320 AddNodes(fAudioOutputs, false); 321 AddNodes(fAudioInputs, false); 322 323 fAudioView->AddNodes(fAudioOutputs, false); 324 fAudioView->AddNodes(fAudioInputs, true); 325 fVideoView->AddNodes(fVideoOutputs, false); 326 fVideoView->AddNodes(fVideoInputs, true); 327 328 fListView->AddItem(audio = new MediaListItem("Audio settings", 0, false, &fIcons)); 329 fListView->AddItem(video = new MediaListItem("Video settings", 0, true, &fIcons)); 330 331 fListView->AddItem(mixer = new MediaListItem("Audio mixer", 1, false, &fIcons)); 332 mixer->SetAudioMixer(true); 333 334 fListView->SortItems(&MediaListItem::Compare); 335 336 media_node default_node; 337 dormant_node_info node_info; 338 int32 outputID; 339 BString outputName; 340 341 if (roster->GetAudioInput(&default_node)==B_OK) { 342 roster->GetDormantNodeFor(default_node, &node_info); 343 item = FindMediaListItem(&node_info); 344 if (item) 345 item->SetDefault(true, true); 346 fAudioView->SetDefault(node_info, true); 347 } 348 349 if (roster->GetAudioOutput(&default_node, &outputID, &outputName)==B_OK) { 350 roster->GetDormantNodeFor(default_node, &node_info); 351 item = FindMediaListItem(&node_info); 352 if (item) 353 item->SetDefault(true, false); 354 fAudioView->SetDefault(node_info, false, outputID); 355 } 356 357 if (roster->GetVideoInput(&default_node)==B_OK) { 358 roster->GetDormantNodeFor(default_node, &node_info); 359 item = FindMediaListItem(&node_info); 360 if (item) 361 item->SetDefault(true, true); 362 fVideoView->SetDefault(node_info, true); 363 } 364 365 if (roster->GetVideoOutput(&default_node)==B_OK) { 366 roster->GetDormantNodeFor(default_node, &node_info); 367 item = FindMediaListItem(&node_info); 368 if (item) 369 item->SetDefault(true, false); 370 fVideoView->SetDefault(node_info, false); 371 } 372 373 if (first) { 374 fListView->Select(fListView->IndexOf(mixer)); 375 } else { 376 if (!fAudioView->fRestartView->IsHidden()) 377 fAudioView->fRestartView->Hide(); 378 if (!fVideoView->fRestartView->IsHidden()) 379 fVideoView->fRestartView->Hide(); 380 381 if (isVideoSelected) 382 fListView->Select(fListView->IndexOf(video)); 383 else 384 fListView->Select(fListView->IndexOf(audio)); 385 } 386 387 if (fAlert) { 388 snooze(800000); 389 fAlert->PostMessage(B_QUIT_REQUESTED); 390 } 391 fAlert = NULL; 392 393 Unlock(); 394 395 return B_OK; 396 } 397 398 399 // MediaWindow::QuitRequested -- Post a message to the app to quit 400 bool 401 MediaWindow::QuitRequested() 402 { 403 // stop watching the MediaRoster 404 BMediaRoster *roster = BMediaRoster::CurrentRoster(); 405 if (roster && fCurrentNode) { 406 roster->StopWatching(this, *fCurrentNode, B_MEDIA_WILDCARD); 407 } 408 be_app->PostMessage(B_QUIT_REQUESTED); 409 return true; 410 } 411 // ---------------------------------------------------------------------------------------------------------- // 412 413 414 // MediaWindow::FrameResized -- When the main frame is resized fix up the other views 415 void 416 MediaWindow::FrameResized (float width, float height) 417 { 418 // This makes sure our SideBar colours down to the bottom when resized 419 BRect r; 420 r = Bounds(); 421 } 422 // ---------------------------------------------------------------------------------------------------------- // 423 424 // ErrorAlert -- Displays a BAlert Box with a Custom Error or Debug Message 425 void 426 ErrorAlert(char* errorMessage) { 427 printf("%s\n", errorMessage); 428 BAlert *alert = new BAlert("BAlert", errorMessage, B_TRANSLATE("OK"), 429 NULL, NULL, B_WIDTH_AS_USUAL, B_STOP_ALERT); 430 alert->Go(); 431 exit(1); 432 } 433 // ---------------------------------------------------------------------------------------------------------- // 434 435 436 // MediaWindow::MessageReceived -- receives messages 437 void 438 MediaWindow::MessageReceived (BMessage *message) 439 { 440 switch(message->what) 441 { 442 case ML_INIT_MEDIA: 443 InitMedia(false); 444 break; 445 case ML_DEFAULTOUTPUT_CHANGE: 446 { 447 int32 index; 448 if (message->FindInt32("index", &index)!=B_OK) 449 break; 450 Settings2Item *item = static_cast<Settings2Item *>(fAudioView->fMenu3->ItemAt(index)); 451 452 if (item) { 453 BMediaRoster *roster = BMediaRoster::Roster(); 454 roster->SetAudioOutput(*item->fInput); 455 456 if (fAudioView->fRestartView->IsHidden()) 457 fAudioView->fRestartView->Show(); 458 } else 459 fprintf(stderr, "Settings2Item not found\n"); 460 } 461 break; 462 case ML_DEFAULT_CHANGE: 463 { 464 bool isVideo = true; 465 bool isInput = true; 466 if (message->FindBool("isVideo", &isVideo)!=B_OK) 467 break; 468 if (message->FindBool("isInput", &isInput)!=B_OK) 469 break; 470 int32 index; 471 if (message->FindInt32("index", &index)!=B_OK) 472 break; 473 SettingsView *settingsView = isVideo ? fVideoView : fAudioView; 474 BMenu *menu = isInput ? settingsView->fMenu1 : settingsView->fMenu2; 475 SettingsItem *item = static_cast<SettingsItem *>(menu->ItemAt(index)); 476 477 if (item) { 478 PRINT(("isVideo %i isInput %i\n", isVideo, isInput)); 479 BMediaRoster *roster = BMediaRoster::Roster(); 480 if (isVideo) { 481 if (isInput) 482 roster->SetVideoInput(*item->fInfo); 483 else 484 roster->SetVideoOutput(*item->fInfo); 485 } else { 486 if (isInput) 487 roster->SetAudioInput(*item->fInfo); 488 else { 489 roster->SetAudioOutput(*item->fInfo); 490 fAudioView->SetDefault(*item->fInfo, false, 0); 491 } 492 } 493 494 MediaListItem *oldListItem = NULL; 495 for (int32 j = 0; j<fListView->CountItems(); j++) { 496 oldListItem = static_cast<MediaListItem *>(fListView->ItemAt(j)); 497 if (oldListItem->fInfo && oldListItem->IsVideo() == isVideo 498 && oldListItem->IsDefault(isInput)) 499 break; 500 } 501 if (oldListItem) 502 oldListItem->SetDefault(false, isInput); 503 else 504 fprintf(stderr, "oldListItem not found\n"); 505 506 MediaListItem *listItem = FindMediaListItem(item->fInfo); 507 if (listItem) { 508 listItem->SetDefault(true, isInput); 509 } else 510 fprintf(stderr, "MediaListItem not found\n"); 511 fListView->Invalidate(); 512 513 if (settingsView->fRestartView->IsHidden()) 514 settingsView->fRestartView->Show(); 515 } else 516 fprintf(stderr, "SettingsItem not found\n"); 517 } 518 break; 519 case ML_RESTART_MEDIA_SERVER: 520 { 521 thread_id thread = spawn_thread(&MediaWindow::RestartMediaServices, 522 "restart_thread", B_NORMAL_PRIORITY, this); 523 if (thread < B_OK) 524 fprintf(stderr, "couldn't create restart thread\n"); 525 else 526 resume_thread(thread); 527 break; 528 } 529 case ML_SHOW_VOLUME_CONTROL: 530 { 531 BDeskbar deskbar; 532 if (fAudioView->fVolumeCheckBox->Value() == B_CONTROL_ON) { 533 BEntry entry("/bin/desklink", true); 534 int32 id; 535 entry_ref ref; 536 status_t status = entry.GetRef(&ref); 537 if (status == B_OK) 538 status = deskbar.AddItem(&ref, &id); 539 540 if (status != B_OK) { 541 fprintf(stderr, B_TRANSLATE( 542 "Couldn't add volume control in Deskbar: %s\n"), 543 strerror(status)); 544 } 545 } else { 546 status_t status = deskbar.RemoveItem("MediaReplicant"); 547 if (status != B_OK) { 548 fprintf(stderr, B_TRANSLATE( 549 "Couldn't remove volume control in Deskbar: %s\n"), 550 strerror(status)); 551 } 552 } 553 break; 554 } 555 case ML_ENABLE_REAL_TIME: 556 { 557 bool isVideo = true; 558 if (message->FindBool("isVideo", &isVideo)!=B_OK) 559 break; 560 SettingsView *settingsView = isVideo ? fVideoView : fAudioView; 561 uint32 flags; 562 uint32 realtimeFlag = isVideo ? B_MEDIA_REALTIME_VIDEO : B_MEDIA_REALTIME_AUDIO; 563 BMediaRoster *roster = BMediaRoster::Roster(); 564 roster->GetRealtimeFlags(&flags); 565 if (settingsView->fRealtimeCheckBox->Value()==B_CONTROL_ON) 566 flags |= realtimeFlag; 567 else 568 flags &= ~realtimeFlag; 569 roster->SetRealtimeFlags(flags); 570 } 571 break; 572 case B_MEDIA_WEB_CHANGED: 573 case ML_SELECTED_NODE: 574 { 575 PRINT_OBJECT(*message); 576 577 MediaListItem *item = static_cast<MediaListItem *>(fListView->ItemAt(fListView->CurrentSelection())); 578 if (!item) 579 break; 580 BMediaRoster* roster = BMediaRoster::Roster(); 581 if (fCurrentNode) { 582 // stop watching the MediaRoster 583 roster->StopWatching(this, *fCurrentNode, B_MEDIA_WILDCARD); 584 roster->ReleaseNode(*fCurrentNode); 585 } 586 fCurrentNode = NULL; 587 BView *paramView = fContentView->ChildAt(0); 588 if (paramView!=NULL) { 589 fContentView->RemoveChild(paramView); 590 } 591 paramView = NULL; 592 if (fParamWeb) 593 delete fParamWeb; 594 fParamWeb = NULL; 595 596 fTitleView->SetText(item->GetLabel()); 597 598 if (item->OutlineLevel() == 0) { 599 if (item->IsVideo()) 600 fContentView->AddChild(fVideoView); 601 else 602 fContentView->AddChild(fAudioView); 603 } else { 604 605 if (!fCurrentNode) 606 fCurrentNode = new media_node(); 607 media_node_id node_id; 608 if (item->IsAudioMixer()) 609 roster->GetAudioMixer(fCurrentNode); 610 else if (roster->GetInstancesFor(item->fInfo->addon, item->fInfo->flavor_id, &node_id)!=B_OK) 611 roster->InstantiateDormantNode(*(item->fInfo), fCurrentNode, B_FLAVOR_IS_GLOBAL); 612 else 613 roster->GetNodeFor(node_id, fCurrentNode); 614 615 if (roster->GetParameterWebFor(*fCurrentNode, &fParamWeb)==B_OK 616 && (paramView = BMediaTheme::PreferredTheme()->ViewFor(fParamWeb)) != NULL) { 617 fContentView->AddChild(paramView); 618 paramView->ResizeTo(fContentView->Bounds().Width(), fContentView->Bounds().Height() - 10); 619 620 roster->StartWatching(this, *fCurrentNode, B_MEDIA_WILDCARD); 621 } else { 622 if (fParamWeb) 623 delete fParamWeb; 624 fParamWeb = NULL; 625 BRect bounds = fContentView->Bounds(); 626 BStringView* stringView = new BStringView(bounds, 627 "noControls", B_TRANSLATE("This hardware has no controls."), 628 B_FOLLOW_V_CENTER | B_FOLLOW_H_CENTER); 629 stringView->ResizeToPreferred(); 630 fContentView->AddChild(stringView); 631 stringView->MoveBy((bounds.Width()-stringView->Bounds().Width())/2, 632 (bounds.Height()-stringView->Bounds().Height())/2); 633 } 634 } 635 636 bool barChanged = (item->OutlineLevel() == 0 || fParamWeb == NULL || fParamWeb->CountGroups()<2); 637 if (barChanged != fBar->fDisplay) { 638 fBar->fDisplay = barChanged; 639 fBar->Invalidate(); 640 } 641 } 642 break; 643 case B_SOME_APP_LAUNCHED: 644 { 645 PRINT_OBJECT(*message); 646 const char *mimeSig; 647 if (fAlert && message->FindString("be:signature", &mimeSig)==B_OK 648 && (strcmp(mimeSig, "application/x-vnd.Be.addon-host")==0 649 || strcmp(mimeSig, "application/x-vnd.Be.media-server")==0)) { 650 fAlert->Lock(); 651 fAlert->TextView()->SetText( 652 B_TRANSLATE("Starting media server" B_UTF8_ELLIPSIS)); 653 fAlert->Unlock(); 654 } 655 } 656 break; 657 case B_SOME_APP_QUIT: 658 { 659 PRINT_OBJECT(*message); 660 const char *mimeSig; 661 if (message->FindString("be:signature", &mimeSig)==B_OK) { 662 if (strcmp(mimeSig, "application/x-vnd.Be.addon-host")==0 663 || strcmp(mimeSig, "application/x-vnd.Be.media-server")==0) { 664 BMediaRoster* roster = BMediaRoster::CurrentRoster(); 665 if (roster&&roster->Lock()) 666 roster->Quit(); 667 } 668 } 669 670 } 671 break; 672 default: 673 BWindow::MessageReceived(message); 674 break; 675 } 676 } 677 678 status_t 679 MediaWindow::RestartMediaServices(void *data) 680 { 681 MediaWindow *window = (MediaWindow *)data; 682 window->fAlert = new MediaAlert(BRect(0, 0, 300, 60), 683 "restart_alert", B_TRANSLATE( 684 "Restarting media services\nShutting down media server\n")); 685 686 window->fAlert->Show(); 687 688 shutdown_media_server(B_INFINITE_TIMEOUT, MediaWindow::UpdateProgress, window->fAlert); 689 690 { 691 BAutolock locker(window->fAlert); 692 if (locker.IsLocked()) 693 window->fAlert->TextView()->SetText( 694 B_TRANSLATE("Starting media server" B_UTF8_ELLIPSIS)); 695 } 696 launch_media_server(); 697 698 return window->PostMessage(ML_INIT_MEDIA); 699 } 700 701 bool 702 MediaWindow::UpdateProgress(int stage, const char * message, void * cookie) 703 { 704 MediaAlert *alert = static_cast<MediaAlert*>(cookie); 705 PRINT(("stage : %i\n", stage)); 706 const char *string = "Unknown stage"; 707 switch (stage) { 708 case 10: 709 string = B_TRANSLATE("Stopping media server" B_UTF8_ELLIPSIS); 710 break; 711 case 20: 712 string = B_TRANSLATE("Telling media_addon_server to quit."); 713 break; 714 case 40: 715 string = B_TRANSLATE("Waiting for media_server to quit."); 716 break; 717 case 70: 718 string = B_TRANSLATE("Cleaning up."); 719 break; 720 case 100: 721 string = B_TRANSLATE("Done shutting down."); 722 break; 723 } 724 725 BAutolock locker(alert); 726 if (locker.IsLocked()) 727 alert->TextView()->SetText(string); 728 return true; 729 } 730 731