1 /* 2 Open Tracker License 3 4 Terms and Conditions 5 6 Copyright (c) 1991-2000, Be Incorporated. All rights reserved. 7 8 Permission is hereby granted, free of charge, to any person obtaining a copy of 9 this software and associated documentation files (the "Software"), to deal in 10 the Software without restriction, including without limitation the rights to 11 use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 12 of the Software, and to permit persons to whom the Software is furnished to do 13 so, subject to the following conditions: 14 15 The above copyright notice and this permission notice applies to all licensees 16 and shall be included in all copies or substantial portions of the Software. 17 18 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF TITLE, MERCHANTABILITY, 20 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 21 BE INCORPORATED BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 22 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF, OR IN CONNECTION 23 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 25 Except as contained in this notice, the name of Be Incorporated shall not be 26 used in advertising or otherwise to promote the sale, use or other dealings in 27 this Software without prior written authorization from Be Incorporated. 28 29 Tracker(TM), Be(R), BeOS(R), and BeIA(TM) are trademarks or registered 30 trademarks of Be Incorporated in the United States and other countries. Other 31 brand product names are registered trademarks or trademarks of their respective 32 holders. 33 All rights reserved. 34 */ 35 36 37 #include "BarApp.h" 38 39 #include <locale.h> 40 #include <stdlib.h> 41 #include <string.h> 42 43 #include <AppFileInfo.h> 44 #include <Autolock.h> 45 #include <Bitmap.h> 46 #include <Catalog.h> 47 #include <Debug.h> 48 #include <Directory.h> 49 #include <Dragger.h> 50 #include <File.h> 51 #include <FindDirectory.h> 52 #include <Locale.h> 53 #include <Mime.h> 54 #include <Path.h> 55 #include <Roster.h> 56 #include <RosterPrivate.h> 57 58 #include "icons.h" 59 #include "tracker_private.h" 60 #include "BarView.h" 61 #include "BarWindow.h" 62 #include "PreferencesWindow.h" 63 #include "DeskbarUtils.h" 64 #include "FSUtils.h" 65 #include "PublicCommands.h" 66 #include "ResourceSet.h" 67 #include "StatusView.h" 68 #include "Switcher.h" 69 #include "Utilities.h" 70 71 72 BLocker TBarApp::sSubscriberLock; 73 BList TBarApp::sBarTeamInfoList; 74 BList TBarApp::sSubscribers; 75 76 77 const uint32 kShowDeskbarMenu = 'BeMn'; 78 const uint32 kShowTeamMenu = 'TmMn'; 79 80 81 static const color_space kIconColorSpace = B_RGBA32; 82 83 84 int 85 main() 86 { 87 setlocale(LC_ALL, ""); 88 TBarApp app; 89 app.Run(); 90 91 return B_OK; 92 } 93 94 95 TBarApp::TBarApp() 96 : BApplication(kDeskbarSignature), 97 fSettingsFile(NULL), 98 fPreferencesWindow(NULL) 99 { 100 InitSettings(); 101 InitIconPreloader(); 102 103 fBarWindow = new TBarWindow(); 104 fBarView = fBarWindow->BarView(); 105 106 be_roster->StartWatching(this); 107 108 gLocalizedNamePreferred 109 = BLocaleRoster::Default()->IsFilesystemTranslationPreferred(); 110 111 sBarTeamInfoList.MakeEmpty(); 112 113 BList teamList; 114 int32 numTeams; 115 be_roster->GetAppList(&teamList); 116 numTeams = teamList.CountItems(); 117 for (int32 i = 0; i < numTeams; i++) { 118 app_info appInfo; 119 team_id tID = (team_id)teamList.ItemAt(i); 120 if (be_roster->GetRunningAppInfo(tID, &appInfo) == B_OK) { 121 AddTeam(appInfo.team, appInfo.flags, appInfo.signature, 122 &appInfo.ref); 123 } 124 } 125 126 sSubscribers.MakeEmpty(); 127 128 fSwitcherMessenger = BMessenger(new TSwitchManager(fSettings.switcherLoc)); 129 130 fBarWindow->Show(); 131 132 // Call UpdatePlacement() after the window is shown because expanded apps 133 // need to resize the window. 134 if (fBarWindow->Lock()) { 135 fBarView->UpdatePlacement(); 136 fBarWindow->Unlock(); 137 } 138 139 // this messenger now targets the barview instead of the 140 // statusview so that all additions to the tray 141 // follow the same path 142 fStatusViewMessenger = BMessenger(fBarWindow->FindView("BarView")); 143 } 144 145 146 TBarApp::~TBarApp() 147 { 148 be_roster->StopWatching(this); 149 150 int32 teamCount = sBarTeamInfoList.CountItems(); 151 for (int32 i = 0; i < teamCount; i++) { 152 BarTeamInfo* barInfo = (BarTeamInfo*)sBarTeamInfoList.ItemAt(i); 153 delete barInfo; 154 } 155 156 int32 subsCount = sSubscribers.CountItems(); 157 for (int32 i = 0; i < subsCount; i++) { 158 BMessenger* messenger 159 = static_cast<BMessenger*>(sSubscribers.ItemAt(i)); 160 delete messenger; 161 } 162 SaveSettings(); 163 delete fSettingsFile; 164 } 165 166 167 bool 168 TBarApp::QuitRequested() 169 { 170 // don't allow user quitting 171 if (CurrentMessage() && CurrentMessage()->FindBool("shortcut")) { 172 // but allow quitting to hide fPreferencesWindow 173 int32 index = 0; 174 BWindow* window = NULL; 175 while ((window = WindowAt(index++)) != NULL) { 176 if (window == fPreferencesWindow) { 177 if (fPreferencesWindow->Lock()) { 178 if (fPreferencesWindow->IsActive()) 179 fPreferencesWindow->PostMessage(B_QUIT_REQUESTED); 180 fPreferencesWindow->Unlock(); 181 } 182 break; 183 } 184 } 185 return false; 186 } 187 188 // system quitting, call inherited to notify all loopers 189 fBarWindow->SaveSettings(); 190 BApplication::QuitRequested(); 191 return true; 192 } 193 194 195 void 196 TBarApp::SaveSettings() 197 { 198 if (fSettingsFile->InitCheck() == B_OK) { 199 fSettingsFile->Seek(0, SEEK_SET); 200 BMessage storedSettings; 201 storedSettings.AddBool("vertical", fSettings.vertical); 202 storedSettings.AddBool("left", fSettings.left); 203 storedSettings.AddBool("top", fSettings.top); 204 storedSettings.AddInt32("state", fSettings.state); 205 storedSettings.AddFloat("width", fSettings.width); 206 207 storedSettings.AddBool("showSeconds", fSettings.showSeconds); 208 storedSettings.AddBool("showDayOfWeek", fSettings.showDayOfWeek); 209 210 storedSettings.AddPoint("switcherLoc", fSettings.switcherLoc); 211 storedSettings.AddInt32("recentAppsCount", fSettings.recentAppsCount); 212 storedSettings.AddInt32("recentDocsCount", fSettings.recentDocsCount); 213 storedSettings.AddBool("timeShowSeconds", fSettings.timeShowSeconds); 214 storedSettings.AddInt32("recentFoldersCount", 215 fSettings.recentFoldersCount); 216 storedSettings.AddBool("alwaysOnTop", fSettings.alwaysOnTop); 217 storedSettings.AddBool("timeFullDate", fSettings.timeFullDate); 218 storedSettings.AddBool("trackerAlwaysFirst", 219 fSettings.trackerAlwaysFirst); 220 storedSettings.AddBool("sortRunningApps", fSettings.sortRunningApps); 221 storedSettings.AddBool("superExpando", fSettings.superExpando); 222 storedSettings.AddBool("expandNewTeams", fSettings.expandNewTeams); 223 storedSettings.AddBool("hideLabels", fSettings.hideLabels); 224 storedSettings.AddInt32("iconSize", fSettings.iconSize); 225 storedSettings.AddBool("autoRaise", fSettings.autoRaise); 226 storedSettings.AddBool("autoHide", fSettings.autoHide); 227 storedSettings.AddBool("recentAppsEnabled", 228 fSettings.recentAppsEnabled); 229 storedSettings.AddBool("recentDocsEnabled", 230 fSettings.recentDocsEnabled); 231 storedSettings.AddBool("recentFoldersEnabled", 232 fSettings.recentFoldersEnabled); 233 234 storedSettings.Flatten(fSettingsFile); 235 } 236 } 237 238 239 void 240 TBarApp::InitSettings() 241 { 242 desk_settings settings; 243 settings.vertical = true; 244 settings.left = false; 245 settings.top = true; 246 settings.showSeconds = false; 247 settings.showDayOfWeek = false; 248 settings.state = kExpandoState; 249 settings.width = 0; 250 settings.switcherLoc = BPoint(5000, 5000); 251 settings.recentAppsCount = 10; 252 settings.recentDocsCount = 10; 253 settings.timeShowSeconds = false; 254 settings.recentFoldersCount = 10; 255 settings.alwaysOnTop = false; 256 settings.timeFullDate = false; 257 settings.trackerAlwaysFirst = false; 258 settings.sortRunningApps = false; 259 settings.superExpando = false; 260 settings.expandNewTeams = false; 261 settings.hideLabels = false; 262 settings.iconSize = kMinimumIconSize; 263 settings.autoRaise = false; 264 settings.autoHide = false; 265 settings.recentAppsEnabled = true; 266 settings.recentDocsEnabled = true; 267 settings.recentFoldersEnabled = true; 268 269 BPath dirPath; 270 const char* settingsFileName = "Deskbar_settings"; 271 272 find_directory(B_USER_DESKBAR_DIRECTORY, &dirPath, true); 273 // just make it 274 275 if (find_directory (B_USER_SETTINGS_DIRECTORY, &dirPath, true) == B_OK) { 276 BPath filePath = dirPath; 277 filePath.Append(settingsFileName); 278 fSettingsFile = new BFile(filePath.Path(), O_RDWR); 279 if (fSettingsFile->InitCheck() != B_OK) { 280 BDirectory theDir(dirPath.Path()); 281 if (theDir.InitCheck() == B_OK) 282 theDir.CreateFile(settingsFileName, fSettingsFile); 283 } 284 285 BMessage storedSettings; 286 if (fSettingsFile->InitCheck() == B_OK 287 && storedSettings.Unflatten(fSettingsFile) == B_OK) { 288 if (storedSettings.FindBool("vertical", &settings.vertical) 289 != B_OK) { 290 settings.vertical = true; 291 } 292 if (storedSettings.FindBool("left", &settings.left) != B_OK) 293 settings.left = false; 294 if (storedSettings.FindBool("top", &settings.top) != B_OK) 295 settings.top = true; 296 if (storedSettings.FindInt32("state", (int32*)&settings.state) 297 != B_OK) { 298 settings.state = kExpandoState; 299 } 300 if (storedSettings.FindFloat("width", &settings.width) != B_OK) 301 settings.width = 0; 302 if (storedSettings.FindBool("showSeconds", &settings.showSeconds) 303 != B_OK) { 304 settings.showSeconds = false; 305 } 306 if (storedSettings.FindBool("showDayOfWeek", &settings.showDayOfWeek) 307 != B_OK) { 308 settings.showDayOfWeek = false; 309 } 310 if (storedSettings.FindPoint("switcherLoc", &settings.switcherLoc) 311 != B_OK) { 312 settings.switcherLoc = BPoint(5000, 5000); 313 } 314 if (storedSettings.FindInt32("recentAppsCount", 315 &settings.recentAppsCount) != B_OK) { 316 settings.recentAppsCount = 10; 317 } 318 if (storedSettings.FindInt32("recentDocsCount", 319 &settings.recentDocsCount) != B_OK) { 320 settings.recentDocsCount = 10; 321 } 322 if (storedSettings.FindBool("timeShowSeconds", 323 &settings.timeShowSeconds) != B_OK) { 324 settings.timeShowSeconds = false; 325 } 326 if (storedSettings.FindInt32("recentFoldersCount", 327 &settings.recentFoldersCount) != B_OK) { 328 settings.recentFoldersCount = 10; 329 } 330 if (storedSettings.FindBool("alwaysOnTop", &settings.alwaysOnTop) 331 != B_OK) { 332 settings.alwaysOnTop = false; 333 } 334 if (storedSettings.FindBool("timeFullDate", &settings.timeFullDate) 335 != B_OK) { 336 settings.timeFullDate = false; 337 } 338 if (storedSettings.FindBool("trackerAlwaysFirst", 339 &settings.trackerAlwaysFirst) != B_OK) { 340 settings.trackerAlwaysFirst = false; 341 } 342 if (storedSettings.FindBool("sortRunningApps", 343 &settings.sortRunningApps) != B_OK) { 344 settings.sortRunningApps = false; 345 } 346 if (storedSettings.FindBool("superExpando", &settings.superExpando) 347 != B_OK) { 348 settings.superExpando = false; 349 } 350 if (storedSettings.FindBool("expandNewTeams", 351 &settings.expandNewTeams) != B_OK) { 352 settings.expandNewTeams = false; 353 } 354 if (storedSettings.FindBool("hideLabels", &settings.hideLabels) 355 != B_OK) { 356 settings.hideLabels = false; 357 } 358 if (storedSettings.FindInt32("iconSize", (int32*)&settings.iconSize) 359 != B_OK) { 360 settings.iconSize = kMinimumIconSize; 361 } 362 if (storedSettings.FindBool("autoRaise", &settings.autoRaise) 363 != B_OK) { 364 settings.autoRaise = false; 365 } 366 if (storedSettings.FindBool("autoHide", &settings.autoHide) != B_OK) 367 settings.autoHide = false; 368 if (storedSettings.FindBool("recentAppsEnabled", 369 &settings.recentAppsEnabled) != B_OK) { 370 settings.recentAppsEnabled = true; 371 } 372 if (storedSettings.FindBool("recentDocsEnabled", 373 &settings.recentDocsEnabled) != B_OK) { 374 settings.recentDocsEnabled = true; 375 } 376 if (storedSettings.FindBool("recentFoldersEnabled", 377 &settings.recentFoldersEnabled) != B_OK) { 378 settings.recentFoldersEnabled = true; 379 } 380 } 381 } 382 383 fSettings = settings; 384 } 385 386 387 void 388 TBarApp::MessageReceived(BMessage* message) 389 { 390 switch (message->what) { 391 case 'gloc': 392 case 'sloc': 393 case 'gexp': 394 case 'sexp': 395 case 'info': 396 case 'exst': 397 case 'cwnt': 398 case 'icon': 399 case 'remv': 400 case 'adon': 401 // pass any BDeskbar originating messages on to the window 402 fBarWindow->PostMessage(message); 403 break; 404 405 case kConfigShow: 406 ShowPreferencesWindow(); 407 break; 408 409 case kStateChanged: 410 fPreferencesWindow->PostMessage(kStateChanged); 411 break; 412 413 case kShowDeskbarMenu: 414 if (fBarWindow->Lock()) { 415 fBarWindow->ShowDeskbarMenu(); 416 fBarWindow->Unlock(); 417 } 418 break; 419 420 case kShowTeamMenu: 421 if (fBarWindow->Lock()) { 422 fBarWindow->ShowTeamMenu(); 423 fBarWindow->Unlock(); 424 } 425 break; 426 427 case kUpdateRecentCounts: 428 int32 count; 429 bool enabled; 430 431 if (message->FindInt32("applications", &count) == B_OK) 432 fSettings.recentAppsCount = count; 433 if (message->FindBool("applicationsEnabled", &enabled) == B_OK) 434 fSettings.recentAppsEnabled = enabled && count > 0; 435 436 if (message->FindInt32("folders", &count) == B_OK) 437 fSettings.recentFoldersCount = count; 438 if (message->FindBool("foldersEnabled", &enabled) == B_OK) 439 fSettings.recentFoldersEnabled = enabled && count > 0; 440 441 if (message->FindInt32("documents", &count) == B_OK) 442 fSettings.recentDocsCount = count; 443 if (message->FindBool("documentsEnabled", &enabled) == B_OK) 444 fSettings.recentDocsEnabled = enabled && count > 0; 445 break; 446 447 case kConfigClose: 448 fPreferencesWindow = NULL; 449 break; 450 451 case B_SOME_APP_LAUNCHED: 452 { 453 team_id team = -1; 454 message->FindInt32("be:team", &team); 455 456 uint32 flags = 0; 457 message->FindInt32("be:flags", (long*)&flags); 458 459 const char* sig = NULL; 460 message->FindString("be:signature", &sig); 461 462 entry_ref ref; 463 message->FindRef("be:ref", &ref); 464 465 AddTeam(team, flags, sig, &ref); 466 break; 467 } 468 469 case B_SOME_APP_QUIT: 470 { 471 team_id team = -1; 472 message->FindInt32("be:team", &team); 473 RemoveTeam(team); 474 break; 475 } 476 477 case B_ARCHIVED_OBJECT: 478 // TODO: what's this??? 479 message->AddString("special", "Alex Osadzinski"); 480 fStatusViewMessenger.SendMessage(message); 481 break; 482 483 case kToggleDraggers: 484 if (BDragger::AreDraggersDrawn()) 485 BDragger::HideAllDraggers(); 486 else 487 BDragger::ShowAllDraggers(); 488 break; 489 490 case kAlwaysTop: 491 fSettings.alwaysOnTop = !fSettings.alwaysOnTop; 492 fBarWindow->SetFeel(fSettings.alwaysOnTop ? 493 B_FLOATING_ALL_WINDOW_FEEL : B_NORMAL_WINDOW_FEEL); 494 fPreferencesWindow->PostMessage(kStateChanged); 495 break; 496 497 case kAutoRaise: 498 fSettings.autoRaise = fSettings.alwaysOnTop ? false : 499 !fSettings.autoRaise; 500 break; 501 502 case kAutoHide: 503 fSettings.autoHide = !fSettings.autoHide; 504 505 fBarWindow->Lock(); 506 fBarView->HideDeskbar(fSettings.autoHide); 507 fBarWindow->Unlock(); 508 break; 509 510 case kTrackerFirst: 511 fSettings.trackerAlwaysFirst = !fSettings.trackerAlwaysFirst; 512 513 fBarWindow->Lock(); 514 fBarView->PlaceApplicationBar(); 515 fBarWindow->Unlock(); 516 break; 517 518 case kSortRunningApps: 519 fSettings.sortRunningApps = !fSettings.sortRunningApps; 520 521 fBarWindow->Lock(); 522 fBarView->PlaceApplicationBar(); 523 fBarWindow->Unlock(); 524 break; 525 526 case kUnsubscribe: 527 { 528 BMessenger messenger; 529 if (message->FindMessenger("messenger", &messenger) == B_OK) 530 Unsubscribe(messenger); 531 break; 532 } 533 534 case kSuperExpando: 535 fSettings.superExpando = !fSettings.superExpando; 536 537 fBarWindow->Lock(); 538 fBarView->PlaceApplicationBar(); 539 fBarWindow->Unlock(); 540 break; 541 542 case kExpandNewTeams: 543 fSettings.expandNewTeams = !fSettings.expandNewTeams; 544 545 fBarWindow->Lock(); 546 fBarView->PlaceApplicationBar(); 547 fBarWindow->Unlock(); 548 break; 549 550 case kHideLabels: 551 fSettings.hideLabels = !fSettings.hideLabels; 552 553 fBarWindow->Lock(); 554 fBarView->PlaceApplicationBar(); 555 fBarWindow->Unlock(); 556 break; 557 558 case kResizeTeamIcons: 559 { 560 int32 iconSize; 561 562 if (message->FindInt32("be:value", &iconSize) != B_OK) 563 break; 564 565 fSettings.iconSize = iconSize * kIconSizeInterval; 566 567 if (fSettings.iconSize < kMinimumIconSize) 568 fSettings.iconSize = kMinimumIconSize; 569 else if (fSettings.iconSize > kMaximumIconSize) 570 fSettings.iconSize = kMaximumIconSize; 571 572 ResizeTeamIcons(); 573 574 if (fBarView->MiniState()) 575 break; 576 577 fBarWindow->Lock(); 578 if (fBarView->Vertical()) 579 fBarView->PlaceApplicationBar(); 580 else 581 fBarView->UpdatePlacement(); 582 583 fBarWindow->Unlock(); 584 break; 585 } 586 587 case 'TASK': 588 fSwitcherMessenger.SendMessage(message); 589 break; 590 591 case kSuspendSystem: 592 // TODO: Call BRoster? 593 break; 594 595 case kRebootSystem: 596 case kShutdownSystem: 597 { 598 bool reboot = (message->what == kRebootSystem); 599 bool confirm; 600 message->FindBool("confirm", &confirm); 601 602 BRoster roster; 603 BRoster::Private rosterPrivate(roster); 604 status_t error = rosterPrivate.ShutDown(reboot, confirm, false); 605 if (error != B_OK) 606 fprintf(stderr, "Shutdown failed: %s\n", strerror(error)); 607 608 break; 609 } 610 611 case kShowSplash: 612 run_be_about(); 613 break; 614 615 case kRestartTracker: 616 { 617 BRoster roster; 618 roster.Launch(kTrackerSignature); 619 break; 620 } 621 622 case B_LOCALE_CHANGED: 623 { 624 BLocaleRoster::Default()->Refresh(); 625 626 bool localize; 627 if (message->FindBool("filesys", &localize) == B_OK) 628 gLocalizedNamePreferred = localize; 629 630 fStatusViewMessenger.SendMessage(message); 631 // Notify the replicant tray (through BarView) that the time 632 // interval has changed and it should update the time view 633 // and reflow the tray icons. 634 break; 635 } 636 637 default: 638 BApplication::MessageReceived(message); 639 break; 640 } 641 } 642 643 644 void 645 TBarApp::RefsReceived(BMessage* refs) 646 { 647 entry_ref ref; 648 for (int32 i = 0; refs->FindRef("refs", i, &ref) == B_OK; i++) { 649 BMessage refsReceived(B_REFS_RECEIVED); 650 refsReceived.AddRef("refs", &ref); 651 652 BEntry entry(&ref); 653 if (!entry.IsDirectory()) 654 TrackerLaunch(&refsReceived, false); 655 } 656 } 657 658 659 void 660 TBarApp::Subscribe(const BMessenger &subscriber, BList* list) 661 { 662 // called when ExpandoMenuBar, TeamMenu or Switcher are built/rebuilt 663 list->MakeEmpty(); 664 665 BAutolock autolock(sSubscriberLock); 666 if (!autolock.IsLocked()) 667 return; 668 669 int32 numTeams = sBarTeamInfoList.CountItems(); 670 for (int32 i = 0; i < numTeams; i++) { 671 BarTeamInfo* barInfo = (BarTeamInfo*)sBarTeamInfoList.ItemAt(i); 672 BarTeamInfo* newBarInfo = new (std::nothrow) BarTeamInfo(*barInfo); 673 if (newBarInfo != NULL) 674 list->AddItem(newBarInfo); 675 } 676 677 int32 subsCount = sSubscribers.CountItems(); 678 for (int32 i = 0; i < subsCount; i++) { 679 BMessenger* messenger = (BMessenger*)sSubscribers.ItemAt(i); 680 if (*messenger == subscriber) 681 return; 682 } 683 684 sSubscribers.AddItem(new BMessenger(subscriber)); 685 } 686 687 688 void 689 TBarApp::Unsubscribe(const BMessenger &subscriber) 690 { 691 BAutolock autolock(sSubscriberLock); 692 if (!autolock.IsLocked()) 693 return; 694 695 int32 count = sSubscribers.CountItems(); 696 for (int32 i = 0; i < count; i++) { 697 BMessenger* messenger = (BMessenger*)sSubscribers.ItemAt(i); 698 if (*messenger == subscriber) { 699 sSubscribers.RemoveItem(i); 700 delete messenger; 701 break; 702 } 703 } 704 } 705 706 707 void 708 TBarApp::AddTeam(team_id team, uint32 flags, const char* sig, entry_ref* ref) 709 { 710 BAutolock autolock(sSubscriberLock); 711 if (!autolock.IsLocked()) 712 return; 713 714 // have we already seen this team, is this another instance of 715 // a known app? 716 BarTeamInfo* multiLaunchTeam = NULL; 717 int32 teamCount = sBarTeamInfoList.CountItems(); 718 for (int32 i = 0; i < teamCount; i++) { 719 BarTeamInfo* barInfo = (BarTeamInfo*)sBarTeamInfoList.ItemAt(i); 720 if (barInfo->teams->HasItem((void*)team)) 721 return; 722 if (strcasecmp(barInfo->sig, sig) == 0) 723 multiLaunchTeam = barInfo; 724 } 725 726 if (multiLaunchTeam != NULL) { 727 multiLaunchTeam->teams->AddItem((void*)team); 728 729 int32 subsCount = sSubscribers.CountItems(); 730 if (subsCount > 0) { 731 BMessage message(kAddTeam); 732 message.AddInt32("team", team); 733 message.AddString("sig", multiLaunchTeam->sig); 734 735 for (int32 i = 0; i < subsCount; i++) 736 ((BMessenger*)sSubscribers.ItemAt(i))->SendMessage(&message); 737 } 738 return; 739 } 740 741 BFile file(ref, B_READ_ONLY); 742 BAppFileInfo appMime(&file); 743 744 BString name; 745 if (!gLocalizedNamePreferred 746 || BLocaleRoster::Default()->GetLocalizedFileName(name, *ref) 747 != B_OK) { 748 name = ref->name; 749 } 750 751 BarTeamInfo* barInfo = new BarTeamInfo(new BList(), flags, strdup(sig), 752 new BBitmap(IconRect(), kIconColorSpace), strdup(ref->name)); 753 754 if ((barInfo->flags & B_BACKGROUND_APP) == 0 755 && strcasecmp(barInfo->sig, kDeskbarSignature) != 0) { 756 FetchAppIcon(barInfo->sig, barInfo->icon); 757 } 758 759 barInfo->teams->AddItem((void*)team); 760 761 sBarTeamInfoList.AddItem(barInfo); 762 763 if (fSettings.expandNewTeams) 764 fBarView->AddExpandedItem(sig); 765 766 int32 subsCount = sSubscribers.CountItems(); 767 if (subsCount > 0) { 768 for (int32 i = 0; i < subsCount; i++) { 769 BMessenger* messenger = (BMessenger*)sSubscribers.ItemAt(i); 770 BMessage message(B_SOME_APP_LAUNCHED); 771 772 BList* tList = new BList(*(barInfo->teams)); 773 message.AddPointer("teams", tList); 774 775 BBitmap* icon = new BBitmap(barInfo->icon); 776 ASSERT(icon); 777 778 message.AddPointer("icon", icon); 779 780 message.AddInt32("flags", static_cast<int32>(barInfo->flags)); 781 message.AddString("name", barInfo->name); 782 message.AddString("sig", barInfo->sig); 783 784 messenger->SendMessage(&message); 785 } 786 } 787 } 788 789 790 void 791 TBarApp::RemoveTeam(team_id team) 792 { 793 BAutolock autolock(sSubscriberLock); 794 if (!autolock.IsLocked()) 795 return; 796 797 int32 teamCount = sBarTeamInfoList.CountItems(); 798 for (int32 i = 0; i < teamCount; i++) { 799 BarTeamInfo* barInfo = (BarTeamInfo*)sBarTeamInfoList.ItemAt(i); 800 if (barInfo->teams->HasItem((void*)team)) { 801 int32 subsCount = sSubscribers.CountItems(); 802 if (subsCount > 0) { 803 BMessage message((barInfo->teams->CountItems() == 1) 804 ? B_SOME_APP_QUIT : kRemoveTeam); 805 806 message.AddInt32("team", team); 807 for (int32 i = 0; i < subsCount; i++) { 808 BMessenger* messenger = (BMessenger*)sSubscribers.ItemAt(i); 809 messenger->SendMessage(&message); 810 } 811 } 812 813 barInfo->teams->RemoveItem((void*)team); 814 if (barInfo->teams->CountItems() < 1) { 815 delete (BarTeamInfo*)sBarTeamInfoList.RemoveItem(i); 816 return; 817 } 818 } 819 } 820 } 821 822 823 void 824 TBarApp::ResizeTeamIcons() 825 { 826 for (int32 i = 0; i < sBarTeamInfoList.CountItems(); i++) { 827 BarTeamInfo* barInfo = (BarTeamInfo*)sBarTeamInfoList.ItemAt(i); 828 if ((barInfo->flags & B_BACKGROUND_APP) == 0 829 && strcasecmp(barInfo->sig, kDeskbarSignature) != 0) { 830 delete barInfo->icon; 831 barInfo->icon = new BBitmap(IconRect(), kIconColorSpace); 832 FetchAppIcon(barInfo->sig, barInfo->icon); 833 } 834 } 835 } 836 837 838 int32 839 TBarApp::IconSize() 840 { 841 return fSettings.iconSize; 842 } 843 844 845 void 846 TBarApp::ShowPreferencesWindow() 847 { 848 if (fPreferencesWindow) 849 fPreferencesWindow->Activate(); 850 else { 851 fPreferencesWindow = new PreferencesWindow(BRect(0, 0, 320, 240)); 852 fPreferencesWindow->Show(); 853 } 854 } 855 856 857 void 858 TBarApp::FetchAppIcon(const char* signature, BBitmap* icon) 859 { 860 app_info appInfo; 861 icon_size size = icon->Bounds().IntegerHeight() >= 31 862 ? B_LARGE_ICON : B_MINI_ICON; 863 864 if (be_roster->GetAppInfo(signature, &appInfo) == B_OK) { 865 // fetch the app icon 866 BFile file(&appInfo.ref, B_READ_ONLY); 867 BAppFileInfo appMime(&file); 868 if (appMime.GetIcon(icon, size) == B_OK) 869 return; 870 } 871 872 // couldn't find the app icon 873 // fetch the generic 3 boxes icon 874 BMimeType defaultAppMime; 875 defaultAppMime.SetTo(B_APP_MIME_TYPE); 876 if (defaultAppMime.GetIcon(icon, size) == B_OK) 877 return; 878 879 // couldn't find generic 3 boxes icon 880 // fill with transparent 881 uint8* iconBits = (uint8*)icon->Bits(); 882 if (icon->ColorSpace() == B_RGBA32) { 883 int32 i = 0; 884 while (i < icon->BitsLength()) { 885 iconBits[i++] = B_TRANSPARENT_32_BIT.red; 886 iconBits[i++] = B_TRANSPARENT_32_BIT.green; 887 iconBits[i++] = B_TRANSPARENT_32_BIT.blue; 888 iconBits[i++] = B_TRANSPARENT_32_BIT.alpha; 889 } 890 } else { 891 // Assume B_CMAP8 892 for (int32 i = 0; i < icon->BitsLength(); i++) 893 iconBits[i] = B_TRANSPARENT_MAGIC_CMAP8; 894 } 895 } 896 897 898 BRect 899 TBarApp::IconRect() 900 { 901 int32 iconSize = IconSize(); 902 return BRect(0, 0, iconSize - 1, iconSize - 1); 903 } 904 905 906 // #pragma mark - 907 908 909 BarTeamInfo::BarTeamInfo(BList* teams, uint32 flags, char* sig, BBitmap* icon, 910 char* name) 911 : teams(teams), 912 flags(flags), 913 sig(sig), 914 icon(icon), 915 name(name) 916 { 917 } 918 919 920 BarTeamInfo::BarTeamInfo(const BarTeamInfo &info) 921 : teams(new BList(*info.teams)), 922 flags(info.flags), 923 sig(strdup(info.sig)), 924 icon(new BBitmap(*info.icon)), 925 name(strdup(info.name)) 926 { 927 } 928 929 930 BarTeamInfo::~BarTeamInfo() 931 { 932 delete teams; 933 free(sig); 934 delete icon; 935 free(name); 936 } 937