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 576 if (roster->GetParameterWebFor(*fCurrentNode, &fParamWeb)==B_OK 577 && (paramView = BMediaTheme::PreferredTheme()->ViewFor(fParamWeb)) != NULL) { 578 fContentView->AddChild(paramView); 579 paramView->ResizeTo(fContentView->Bounds().Width(), fContentView->Bounds().Height() - 10); 580 581 roster->StartWatching(this, *fCurrentNode, B_MEDIA_WILDCARD); 582 } else { 583 if (fParamWeb) 584 delete fParamWeb; 585 fParamWeb = NULL; 586 BRect bounds = fContentView->Bounds(); 587 BStringView* stringView = new BStringView(bounds, 588 "noControls", "This hardware has no controls.", B_FOLLOW_V_CENTER | B_FOLLOW_H_CENTER); 589 stringView->ResizeToPreferred(); 590 fContentView->AddChild(stringView); 591 stringView->MoveBy((bounds.Width()-stringView->Bounds().Width())/2, 592 (bounds.Height()-stringView->Bounds().Height())/2); 593 } 594 } 595 596 bool barChanged = (item->OutlineLevel() == 0 || fParamWeb == NULL || fParamWeb->CountGroups()<2); 597 if(barChanged != fBar->fDisplay) { 598 fBar->fDisplay = barChanged; 599 fBar->Invalidate(); 600 } 601 } 602 break; 603 case B_SOME_APP_LAUNCHED: 604 { 605 PRINT_OBJECT(*message); 606 const char *mimeSig; 607 if(fAlert && message->FindString("be:signature", &mimeSig)==B_OK 608 && (strcmp(mimeSig, "application/x-vnd.Be.addon-host")==0 609 || strcmp(mimeSig, "application/x-vnd.Be.media-server")==0)) { 610 fAlert->Lock(); 611 fAlert->TextView()->SetText("Starting Media Server..."); 612 fAlert->Unlock(); 613 } 614 } 615 break; 616 case B_SOME_APP_QUIT: 617 { 618 PRINT_OBJECT(*message); 619 const char *mimeSig; 620 if(message->FindString("be:signature", &mimeSig)==B_OK) { 621 if(strcmp(mimeSig, "application/x-vnd.Be.addon-host")==0 622 || strcmp(mimeSig, "application/x-vnd.Be.media-server")==0) { 623 BMediaRoster* roster = BMediaRoster::CurrentRoster(); 624 if(roster&&roster->Lock()) 625 roster->Quit(); 626 } 627 } 628 629 } 630 break; 631 default: 632 BWindow::MessageReceived(message); 633 break; 634 } 635 } 636 637 status_t 638 MediaWindow::RestartMediaServices(void *data) 639 { 640 MediaWindow *window = (MediaWindow *)data; 641 window->fAlert = new MediaAlert(BRect(0,0,300,60), 642 "restart_alert", "Restarting Media Services\nShutting down Media Server\n"); 643 644 window->fAlert->Show(); 645 646 shutdown_media_server(B_INFINITE_TIMEOUT, MediaWindow::UpdateProgress, window->fAlert); 647 648 { 649 BAutolock locker(window->fAlert); 650 if(locker.IsLocked()) 651 window->fAlert->TextView()->SetText("Starting Media Server..."); 652 } 653 launch_media_server(); 654 655 return window->PostMessage(ML_INIT_MEDIA); 656 } 657 658 bool 659 MediaWindow::UpdateProgress(int stage, const char * message, void * cookie) 660 { 661 MediaAlert *alert = static_cast<MediaAlert*>(cookie); 662 PRINT(("stage : %i\n", stage)); 663 char *string = "Unknown stage"; 664 switch (stage) { 665 case 10: 666 string = "Stopping Media Server..."; 667 break; 668 case 20: 669 string = "Telling media_addon_server to quit."; 670 break; 671 case 40: 672 string = "Waiting for media_server to quit."; 673 break; 674 case 70: 675 string = "Cleaning Up."; 676 break; 677 case 100: 678 string = "Done Shutting Down."; 679 break; 680 } 681 682 BAutolock locker(alert); 683 if (locker.IsLocked()) 684 alert->TextView()->SetText(string); 685 return true; 686 } 687 688