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