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