1 /* 2 * Copyright 2008, Axel Dörfler, axeld@pinc-software.de. All rights reserved. 3 * Distributed under the terms of the MIT License. 4 */ 5 6 7 #include "DataSource.h" 8 9 #include <stdio.h> 10 #include <stdint.h> 11 12 #include <OS.h> 13 #include <String.h> 14 15 #include "SystemInfo.h" 16 17 18 const DataSource* kSources[] = { 19 new UsedMemoryDataSource(), 20 new CachedMemoryDataSource(), 21 new SemaphoresDataSource(), 22 new PortsDataSource(), 23 new ThreadsDataSource(), 24 new TeamsDataSource(), 25 new RunningAppsDataSource(), 26 new CPUUsageDataSource(), 27 new CPUCombinedUsageDataSource(), 28 new NetworkUsageDataSource(true), 29 new NetworkUsageDataSource(false), 30 new ClipboardSizeDataSource(false), 31 new ClipboardSizeDataSource(true), 32 new MediaNodesDataSource() 33 }; 34 const size_t kSourcesCount = sizeof(kSources) / sizeof(kSources[0]); 35 36 37 DataSource::DataSource(int64 initialMin, int64 initialMax) 38 : 39 fMinimum(initialMin), 40 fMaximum(initialMax), 41 fInterval(1000000LL), 42 fColor((rgb_color){200, 0, 0}) 43 { 44 } 45 46 47 DataSource::DataSource() 48 : 49 fMinimum(0), 50 fMaximum(100), 51 fInterval(1000000LL), 52 fColor((rgb_color){200, 0, 0}) 53 { 54 } 55 56 57 DataSource::DataSource(const DataSource& other) 58 { 59 fMinimum = other.fMinimum; 60 fMaximum = other.fMaximum; 61 fInterval = other.fInterval; 62 fColor = other.fColor; 63 } 64 65 66 DataSource::~DataSource() 67 { 68 } 69 70 71 DataSource* 72 DataSource::Copy() const 73 { 74 return NULL; 75 // this class cannot be copied 76 } 77 78 79 DataSource* 80 DataSource::CopyForCPU(int32 cpu) const 81 { 82 return Copy(); 83 } 84 85 86 int64 87 DataSource::Minimum() const 88 { 89 return fMinimum; 90 } 91 92 93 int64 94 DataSource::Maximum() const 95 { 96 return fMaximum; 97 } 98 99 100 bigtime_t 101 DataSource::RefreshInterval() const 102 { 103 return fInterval; 104 } 105 106 107 void 108 DataSource::SetLimits(int64 min, int64 max) 109 { 110 fMinimum = min; 111 fMaximum = max; 112 } 113 114 115 void 116 DataSource::SetRefreshInterval(bigtime_t interval) 117 { 118 fInterval = interval; 119 } 120 121 122 void 123 DataSource::SetColor(rgb_color color) 124 { 125 fColor = color; 126 } 127 128 129 int64 130 DataSource::NextValue(SystemInfo& info) 131 { 132 return 0; 133 } 134 135 136 void 137 DataSource::Print(BString& text, int64 value) const 138 { 139 text = ""; 140 text << value; 141 } 142 143 144 const char* 145 DataSource::Name() const 146 { 147 return Label(); 148 } 149 150 151 const char* 152 DataSource::Label() const 153 { 154 return ""; 155 } 156 157 158 const char* 159 DataSource::Unit() const 160 { 161 return ""; 162 } 163 164 165 rgb_color 166 DataSource::Color() const 167 { 168 return fColor; 169 } 170 171 172 bool 173 DataSource::AdaptiveScale() const 174 { 175 return false; 176 } 177 178 179 scale_type 180 DataSource::ScaleType() const 181 { 182 return kNoScale; 183 } 184 185 186 int32 187 DataSource::CPU() const 188 { 189 return 0; 190 } 191 192 193 bool 194 DataSource::PerCPU() const 195 { 196 return false; 197 } 198 199 200 bool 201 DataSource::MultiCPUOnly() const 202 { 203 return false; 204 } 205 206 207 bool 208 DataSource::Primary() const 209 { 210 return false; 211 } 212 213 214 /*static*/ int32 215 DataSource::CountSources() 216 { 217 return kSourcesCount; 218 } 219 220 221 /*static*/ const DataSource* 222 DataSource::SourceAt(int32 index) 223 { 224 if (index >= (int32)kSourcesCount || index < 0) 225 return NULL; 226 227 return kSources[index]; 228 } 229 230 231 /*static*/ const DataSource* 232 DataSource::FindSource(const char* name) 233 { 234 for (uint32 i = 0; i < kSourcesCount; i++) { 235 const DataSource* source = kSources[i]; 236 if (!strcmp(source->Name(), name)) 237 return source; 238 } 239 240 return NULL; 241 } 242 243 244 /*static*/ int32 245 DataSource::IndexOf(const DataSource* source) 246 { 247 const char* name = source->Name(); 248 249 for (uint32 i = 0; i < kSourcesCount; i++) { 250 if (!strcmp(kSources[i]->Name(), name)) 251 return i; 252 } 253 254 return -1; 255 } 256 257 258 // #pragma mark - 259 260 261 MemoryDataSource::MemoryDataSource() 262 { 263 SystemInfo info; 264 265 fMinimum = 0; 266 fMaximum = info.MaxMemory(); 267 } 268 269 270 MemoryDataSource::~MemoryDataSource() 271 { 272 } 273 274 275 void 276 MemoryDataSource::Print(BString& text, int64 value) const 277 { 278 char buffer[32]; 279 snprintf(buffer, sizeof(buffer), "%.1f MB", value / 1048576.0); 280 281 text = buffer; 282 } 283 284 285 const char* 286 MemoryDataSource::Unit() const 287 { 288 return "MB"; 289 } 290 291 292 // #pragma mark - 293 294 295 UsedMemoryDataSource::UsedMemoryDataSource() 296 { 297 } 298 299 300 UsedMemoryDataSource::~UsedMemoryDataSource() 301 { 302 } 303 304 305 DataSource* 306 UsedMemoryDataSource::Copy() const 307 { 308 return new UsedMemoryDataSource(*this); 309 } 310 311 312 int64 313 UsedMemoryDataSource::NextValue(SystemInfo& info) 314 { 315 return info.UsedMemory(); 316 } 317 318 319 const char* 320 UsedMemoryDataSource::Label() const 321 { 322 return "Used Memory"; 323 } 324 325 326 bool 327 UsedMemoryDataSource::Primary() const 328 { 329 return true; 330 } 331 332 333 // #pragma mark - 334 335 336 CachedMemoryDataSource::CachedMemoryDataSource() 337 { 338 fColor = (rgb_color){0, 200, 0}; 339 } 340 341 342 CachedMemoryDataSource::~CachedMemoryDataSource() 343 { 344 } 345 346 347 DataSource* 348 CachedMemoryDataSource::Copy() const 349 { 350 return new CachedMemoryDataSource(*this); 351 } 352 353 354 int64 355 CachedMemoryDataSource::NextValue(SystemInfo& info) 356 { 357 return info.CachedMemory(); 358 } 359 360 361 const char* 362 CachedMemoryDataSource::Label() const 363 { 364 return "Cached Memory"; 365 } 366 367 368 bool 369 CachedMemoryDataSource::Primary() const 370 { 371 return true; 372 } 373 374 375 // #pragma mark - 376 377 378 SemaphoresDataSource::SemaphoresDataSource() 379 { 380 SystemInfo info; 381 382 fMinimum = 0; 383 fMaximum = info.MaxSemaphores(); 384 385 fColor = (rgb_color){100, 200, 100}; 386 } 387 388 389 SemaphoresDataSource::~SemaphoresDataSource() 390 { 391 } 392 393 394 DataSource* 395 SemaphoresDataSource::Copy() const 396 { 397 return new SemaphoresDataSource(*this); 398 } 399 400 401 int64 402 SemaphoresDataSource::NextValue(SystemInfo& info) 403 { 404 return info.UsedSemaphores(); 405 } 406 407 408 const char* 409 SemaphoresDataSource::Label() const 410 { 411 return "Semaphores"; 412 } 413 414 415 bool 416 SemaphoresDataSource::AdaptiveScale() const 417 { 418 return true; 419 } 420 421 422 // #pragma mark - 423 424 425 PortsDataSource::PortsDataSource() 426 { 427 SystemInfo info; 428 429 fMinimum = 0; 430 fMaximum = info.MaxPorts(); 431 432 fColor = (rgb_color){180, 200, 180}; 433 } 434 435 436 PortsDataSource::~PortsDataSource() 437 { 438 } 439 440 441 DataSource* 442 PortsDataSource::Copy() const 443 { 444 return new PortsDataSource(*this); 445 } 446 447 448 int64 449 PortsDataSource::NextValue(SystemInfo& info) 450 { 451 return info.UsedPorts(); 452 } 453 454 455 const char* 456 PortsDataSource::Label() const 457 { 458 return "Ports"; 459 } 460 461 462 bool 463 PortsDataSource::AdaptiveScale() const 464 { 465 return true; 466 } 467 468 469 // #pragma mark - 470 471 472 ThreadsDataSource::ThreadsDataSource() 473 { 474 SystemInfo info; 475 476 fMinimum = 0; 477 fMaximum = info.MaxThreads(); 478 479 fColor = (rgb_color){0, 0, 200}; 480 } 481 482 483 ThreadsDataSource::~ThreadsDataSource() 484 { 485 } 486 487 488 DataSource* 489 ThreadsDataSource::Copy() const 490 { 491 return new ThreadsDataSource(*this); 492 } 493 494 495 int64 496 ThreadsDataSource::NextValue(SystemInfo& info) 497 { 498 return info.UsedThreads(); 499 } 500 501 502 const char* 503 ThreadsDataSource::Label() const 504 { 505 return "Threads"; 506 } 507 508 509 bool 510 ThreadsDataSource::AdaptiveScale() const 511 { 512 return true; 513 } 514 515 516 // #pragma mark - 517 518 519 TeamsDataSource::TeamsDataSource() 520 { 521 SystemInfo info; 522 523 fMinimum = 0; 524 fMaximum = info.MaxTeams(); 525 526 fColor = (rgb_color){0, 150, 255}; 527 } 528 529 530 TeamsDataSource::~TeamsDataSource() 531 { 532 } 533 534 535 DataSource* 536 TeamsDataSource::Copy() const 537 { 538 return new TeamsDataSource(*this); 539 } 540 541 542 int64 543 TeamsDataSource::NextValue(SystemInfo& info) 544 { 545 return info.UsedTeams(); 546 } 547 548 549 const char* 550 TeamsDataSource::Label() const 551 { 552 return "Teams"; 553 } 554 555 556 bool 557 TeamsDataSource::AdaptiveScale() const 558 { 559 return true; 560 } 561 562 563 // #pragma mark - 564 565 566 RunningAppsDataSource::RunningAppsDataSource() 567 { 568 SystemInfo info; 569 570 fMinimum = 0; 571 fMaximum = info.MaxRunningApps(); 572 573 fColor = (rgb_color){100, 150, 255}; 574 } 575 576 577 RunningAppsDataSource::~RunningAppsDataSource() 578 { 579 } 580 581 582 DataSource* 583 RunningAppsDataSource::Copy() const 584 { 585 return new RunningAppsDataSource(*this); 586 } 587 588 589 int64 590 RunningAppsDataSource::NextValue(SystemInfo& info) 591 { 592 return info.UsedRunningApps(); 593 } 594 595 596 const char* 597 RunningAppsDataSource::Label() const 598 { 599 return "Running Applications"; 600 } 601 602 603 bool 604 RunningAppsDataSource::AdaptiveScale() const 605 { 606 return true; 607 } 608 609 610 // #pragma mark - 611 612 613 CPUUsageDataSource::CPUUsageDataSource(int32 cpu) 614 : 615 fPreviousActive(0), 616 fPreviousTime(0) 617 { 618 fMinimum = 0; 619 fMaximum = 1000; 620 621 _SetCPU(cpu); 622 } 623 624 625 CPUUsageDataSource::CPUUsageDataSource(const CPUUsageDataSource& other) 626 : DataSource(other) 627 { 628 fPreviousActive = other.fPreviousActive; 629 fPreviousTime = other.fPreviousTime; 630 fCPU = other.fCPU; 631 fLabel = other.fLabel; 632 } 633 634 635 CPUUsageDataSource::~CPUUsageDataSource() 636 { 637 } 638 639 640 DataSource* 641 CPUUsageDataSource::Copy() const 642 { 643 return new CPUUsageDataSource(*this); 644 } 645 646 647 DataSource* 648 CPUUsageDataSource::CopyForCPU(int32 cpu) const 649 { 650 CPUUsageDataSource* copy = new CPUUsageDataSource(*this); 651 copy->_SetCPU(cpu); 652 653 return copy; 654 } 655 656 657 void 658 CPUUsageDataSource::Print(BString& text, int64 value) const 659 { 660 char buffer[32]; 661 snprintf(buffer, sizeof(buffer), "%.1f%%", value / 10.0); 662 663 text = buffer; 664 } 665 666 667 int64 668 CPUUsageDataSource::NextValue(SystemInfo& info) 669 { 670 bigtime_t active = info.Info().cpu_infos[fCPU].active_time; 671 672 int64 percent = int64(1000.0 * (active - fPreviousActive) 673 / (info.Time() - fPreviousTime)); 674 if (percent < 0) 675 percent = 0; 676 if (percent > 1000) 677 percent = 1000; 678 679 fPreviousActive = active; 680 fPreviousTime = info.Time(); 681 682 return percent; 683 } 684 685 686 const char* 687 CPUUsageDataSource::Label() const 688 { 689 return fLabel.String(); 690 } 691 692 693 const char* 694 CPUUsageDataSource::Name() const 695 { 696 return "CPU Usage"; 697 } 698 699 700 int32 701 CPUUsageDataSource::CPU() const 702 { 703 return fCPU; 704 } 705 706 707 bool 708 CPUUsageDataSource::PerCPU() const 709 { 710 return true; 711 } 712 713 714 bool 715 CPUUsageDataSource::Primary() const 716 { 717 return true; 718 } 719 720 721 void 722 CPUUsageDataSource::_SetCPU(int32 cpu) 723 { 724 fCPU = cpu; 725 fLabel = "CPU"; 726 if (SystemInfo().CPUCount() > 1) 727 fLabel << " " << cpu; 728 729 fLabel << " Usage"; 730 731 const rgb_color kColors[] = { 732 // TODO: find some better defaults... 733 {200, 0, 200}, 734 {0, 200, 200}, 735 {80, 80, 80}, 736 {230, 150, 50}, 737 }; 738 const uint32 kNumColors = sizeof(kColors) / sizeof(kColors[0]); 739 740 fColor = kColors[cpu % kNumColors]; 741 } 742 743 744 // #pragma mark - 745 746 747 CPUCombinedUsageDataSource::CPUCombinedUsageDataSource() 748 : 749 fPreviousActive(0), 750 fPreviousTime(0) 751 { 752 fMinimum = 0; 753 fMaximum = 1000; 754 755 fColor = (rgb_color){200, 200, 0}; 756 } 757 758 759 CPUCombinedUsageDataSource::CPUCombinedUsageDataSource( 760 const CPUCombinedUsageDataSource& other) 761 : DataSource(other) 762 { 763 fPreviousActive = other.fPreviousActive; 764 fPreviousTime = other.fPreviousTime; 765 } 766 767 768 CPUCombinedUsageDataSource::~CPUCombinedUsageDataSource() 769 { 770 } 771 772 773 DataSource* 774 CPUCombinedUsageDataSource::Copy() const 775 { 776 return new CPUCombinedUsageDataSource(*this); 777 } 778 779 780 void 781 CPUCombinedUsageDataSource::Print(BString& text, int64 value) const 782 { 783 char buffer[32]; 784 snprintf(buffer, sizeof(buffer), "%.1f%%", value / 10.0); 785 786 text = buffer; 787 } 788 789 790 int64 791 CPUCombinedUsageDataSource::NextValue(SystemInfo& info) 792 { 793 int32 running = 0; 794 bigtime_t active = 0; 795 796 for (int32 cpu = 0; cpu < info.Info().cpu_count; cpu++) { 797 active += info.Info().cpu_infos[cpu].active_time; 798 running++; 799 // TODO: take disabled CPUs into account 800 } 801 802 int64 percent = int64(1000.0 * (active - fPreviousActive) 803 / (running * (info.Time() - fPreviousTime))); 804 if (percent < 0) 805 percent = 0; 806 if (percent > 1000) 807 percent = 1000; 808 809 fPreviousActive = active; 810 fPreviousTime = info.Time(); 811 812 return percent; 813 } 814 815 816 const char* 817 CPUCombinedUsageDataSource::Label() const 818 { 819 return "CPU Usage"; 820 } 821 822 823 const char* 824 CPUCombinedUsageDataSource::Name() const 825 { 826 return "CPU Usage (combined)"; 827 } 828 829 830 bool 831 CPUCombinedUsageDataSource::MultiCPUOnly() const 832 { 833 return true; 834 } 835 836 837 bool 838 CPUCombinedUsageDataSource::Primary() const 839 { 840 return true; 841 } 842 843 844 // #pragma mark - 845 846 847 NetworkUsageDataSource::NetworkUsageDataSource(bool in) 848 : 849 fIn(in), 850 fPreviousBytes(0), 851 fPreviousTime(0) 852 { 853 SystemInfo info; 854 NextValue(info); 855 856 fMinimum = 0; 857 fMaximum = 1000000000LL; 858 859 fColor = fIn ? (rgb_color){200, 150, 0} : (rgb_color){200, 220, 0}; 860 } 861 862 863 NetworkUsageDataSource::NetworkUsageDataSource( 864 const NetworkUsageDataSource& other) 865 : DataSource(other) 866 { 867 fIn = other.fIn; 868 fPreviousBytes = other.fPreviousBytes; 869 fPreviousTime = other.fPreviousTime; 870 } 871 872 873 NetworkUsageDataSource::~NetworkUsageDataSource() 874 { 875 } 876 877 878 DataSource* 879 NetworkUsageDataSource::Copy() const 880 { 881 return new NetworkUsageDataSource(*this); 882 } 883 884 885 void 886 NetworkUsageDataSource::Print(BString& text, int64 value) const 887 { 888 char buffer[32]; 889 snprintf(buffer, sizeof(buffer), "%.1f KB/s", value / 1024.0); 890 891 text = buffer; 892 } 893 894 895 int64 896 NetworkUsageDataSource::NextValue(SystemInfo& info) 897 { 898 uint64 transferred = fIn ? info.NetworkReceived() : info.NetworkSent(); 899 900 int64 bytesPerSecond = uint64(double(transferred - fPreviousBytes) 901 / (info.Time() - fPreviousTime) * 1000000.0); 902 903 fPreviousBytes = transferred; 904 fPreviousTime = info.Time(); 905 906 return bytesPerSecond; 907 } 908 909 910 const char* 911 NetworkUsageDataSource::Label() const 912 { 913 return fIn ? "Receiving" : "Sending"; 914 } 915 916 917 const char* 918 NetworkUsageDataSource::Name() const 919 { 920 return fIn ? "Network Receive" : "Network Send"; 921 } 922 923 924 bool 925 NetworkUsageDataSource::AdaptiveScale() const 926 { 927 return true; 928 } 929 930 931 bool 932 NetworkUsageDataSource::Primary() const 933 { 934 return true; 935 } 936 937 938 // #pragma mark - 939 940 941 ClipboardSizeDataSource::ClipboardSizeDataSource(bool text) 942 { 943 fMinimum = 0; 944 fMaximum = UINT32_MAX; 945 fText = text; 946 947 fColor = (rgb_color){0, 150, 255}; 948 } 949 950 951 ClipboardSizeDataSource::ClipboardSizeDataSource( 952 const ClipboardSizeDataSource& other) 953 : DataSource(other) 954 { 955 fText = other.fText; 956 } 957 958 959 ClipboardSizeDataSource::~ClipboardSizeDataSource() 960 { 961 } 962 963 964 DataSource* 965 ClipboardSizeDataSource::Copy() const 966 { 967 return new ClipboardSizeDataSource(*this); 968 } 969 970 971 int64 972 ClipboardSizeDataSource::NextValue(SystemInfo& info) 973 { 974 if (fText) 975 return info.ClipboardTextSize()/* / 1024*/; 976 return info.ClipboardSize()/* / 1024*/; 977 } 978 979 980 const char* 981 ClipboardSizeDataSource::Label() const 982 { 983 return fText ? "Text Clipboard Size" : "Raw Clipboard Size"; 984 } 985 986 987 const char* 988 ClipboardSizeDataSource::Unit() const 989 { 990 return "bytes"/*"KB"*/; 991 } 992 993 994 bool 995 ClipboardSizeDataSource::AdaptiveScale() const 996 { 997 return true; 998 } 999 1000 1001 // #pragma mark - 1002 1003 1004 MediaNodesDataSource::MediaNodesDataSource() 1005 { 1006 SystemInfo info; 1007 1008 fMinimum = 0; 1009 fMaximum = INT32_MAX; 1010 1011 fColor = (rgb_color){255, 150, 225}; 1012 } 1013 1014 1015 MediaNodesDataSource::~MediaNodesDataSource() 1016 { 1017 } 1018 1019 1020 DataSource* 1021 MediaNodesDataSource::Copy() const 1022 { 1023 return new MediaNodesDataSource(*this); 1024 } 1025 1026 1027 int64 1028 MediaNodesDataSource::NextValue(SystemInfo& info) 1029 { 1030 return info.MediaNodes(); 1031 } 1032 1033 1034 const char* 1035 MediaNodesDataSource::Label() const 1036 { 1037 return "Media Nodes"; 1038 } 1039 1040 1041 bool 1042 MediaNodesDataSource::AdaptiveScale() const 1043 { 1044 return true; 1045 } 1046 1047 1048