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