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