xref: /haiku/src/apps/activitymonitor/DataSource.cpp (revision 9e25244c5e9051f6cd333820d6332397361abd6c)
1 /*
2  * Copyright 2008-2009, Axel Dörfler, axeld@pinc-software.de.
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 <Catalog.h>
13 #include <OS.h>
14 #include <String.h>
15 #include <StringForRate.h>
16 
17 #include "SystemInfo.h"
18 
19 #undef B_TRANSLATION_CONTEXT
20 #define B_TRANSLATION_CONTEXT "DataSource"
21 
22 
23 const DataSource* kSources[] = {
24 	new UsedMemoryDataSource(),
25 	new CachedMemoryDataSource(),
26 	new SwapSpaceDataSource(),
27 	new PageFaultsDataSource(),
28 	new CPUFrequencyDataSource(),
29 	new CPUUsageDataSource(),
30 	new CPUCombinedUsageDataSource(),
31 	new NetworkUsageDataSource(true),
32 	new NetworkUsageDataSource(false),
33 	new BlockCacheDataSource(),
34 	new SemaphoresDataSource(),
35 	new PortsDataSource(),
36 	new ThreadsDataSource(),
37 	new TeamsDataSource(),
38 	new RunningAppsDataSource(),
39 	new ClipboardSizeDataSource(false),
40 	new ClipboardSizeDataSource(true),
41 	new MediaNodesDataSource()
42 };
43 const size_t kSourcesCount = sizeof(kSources) / sizeof(kSources[0]);
44 
45 
46 DataSource::DataSource(int64 initialMin, int64 initialMax)
47 	:
48 	fMinimum(initialMin),
49 	fMaximum(initialMax),
50 	fInterval(1000000LL),
51 	fColor((rgb_color){200, 0, 0})
52 {
53 }
54 
55 
56 DataSource::DataSource()
57 	:
58 	fMinimum(0),
59 	fMaximum(100),
60 	fInterval(1000000LL),
61 	fColor((rgb_color){200, 0, 0})
62 {
63 }
64 
65 
66 DataSource::DataSource(const DataSource& other)
67 {
68 	fMinimum = other.fMinimum;
69 	fMaximum = other.fMaximum;
70 	fInterval = other.fInterval;
71 	fColor = other.fColor;
72 }
73 
74 
75 DataSource::~DataSource()
76 {
77 }
78 
79 
80 DataSource*
81 DataSource::Copy() const
82 {
83 	return NULL;
84 		// this class cannot be copied
85 }
86 
87 
88 DataSource*
89 DataSource::CopyForCPU(int32 cpu) const
90 {
91 	return Copy();
92 }
93 
94 
95 int64
96 DataSource::Minimum() const
97 {
98 	return fMinimum;
99 }
100 
101 
102 int64
103 DataSource::Maximum() const
104 {
105 	return fMaximum;
106 }
107 
108 
109 bigtime_t
110 DataSource::RefreshInterval() const
111 {
112 	return fInterval;
113 }
114 
115 
116 void
117 DataSource::SetLimits(int64 min, int64 max)
118 {
119 	fMinimum = min;
120 	fMaximum = max;
121 }
122 
123 
124 void
125 DataSource::SetRefreshInterval(bigtime_t interval)
126 {
127 	fInterval = interval;
128 }
129 
130 
131 void
132 DataSource::SetColor(rgb_color color)
133 {
134 	fColor = color;
135 }
136 
137 
138 int64
139 DataSource::NextValue(SystemInfo& info)
140 {
141 	return 0;
142 }
143 
144 
145 void
146 DataSource::Print(BString& text, int64 value) const
147 {
148 	text = "";
149 	text << value;
150 }
151 
152 
153 const char*
154 DataSource::ShortLabel() const
155 {
156 	return Label();
157 }
158 
159 
160 const char*
161 DataSource::Name() const
162 {
163 	return Label();
164 }
165 
166 
167 const char*
168 DataSource::Label() const
169 {
170 	return "";
171 }
172 
173 
174 const char*
175 DataSource::Unit() const
176 {
177 	return "";
178 }
179 
180 
181 rgb_color
182 DataSource::Color() const
183 {
184 	return fColor;
185 }
186 
187 
188 bool
189 DataSource::AdaptiveScale() const
190 {
191 	return false;
192 }
193 
194 
195 scale_type
196 DataSource::ScaleType() const
197 {
198 	return kNoScale;
199 }
200 
201 
202 int32
203 DataSource::CPU() const
204 {
205 	return 0;
206 }
207 
208 
209 bool
210 DataSource::PerCPU() const
211 {
212 	return false;
213 }
214 
215 
216 bool
217 DataSource::MultiCPUOnly() const
218 {
219 	return false;
220 }
221 
222 
223 bool
224 DataSource::Primary() const
225 {
226 	return false;
227 }
228 
229 
230 /*static*/ int32
231 DataSource::CountSources()
232 {
233 	return kSourcesCount;
234 }
235 
236 
237 /*static*/ const DataSource*
238 DataSource::SourceAt(int32 index)
239 {
240 	if (index >= (int32)kSourcesCount || index < 0)
241 		return NULL;
242 
243 	return kSources[index];
244 }
245 
246 
247 /*static*/ const DataSource*
248 DataSource::FindSource(const char* internalName)
249 {
250 	for (uint32 i = 0; i < kSourcesCount; i++) {
251 		const DataSource* source = kSources[i];
252 		if (!strcmp(source->InternalName(), internalName))
253 			return source;
254 	}
255 
256 	return NULL;
257 }
258 
259 
260 /*static*/ int32
261 DataSource::IndexOf(const DataSource* source)
262 {
263 	const char* name = source->Name();
264 
265 	for (uint32 i = 0; i < kSourcesCount; i++) {
266 		if (!strcmp(kSources[i]->Name(), name))
267 			return i;
268 	}
269 
270 	return -1;
271 }
272 
273 
274 //	#pragma mark -
275 
276 
277 MemoryDataSource::MemoryDataSource()
278 {
279 	SystemInfo info;
280 
281 	fMinimum = 0;
282 	fMaximum = info.MaxMemory();
283 }
284 
285 
286 MemoryDataSource::~MemoryDataSource()
287 {
288 }
289 
290 
291 void
292 MemoryDataSource::Print(BString& text, int64 value) const
293 {
294 	char buffer[32];
295 	snprintf(buffer, sizeof(buffer), B_TRANSLATE("%.1f MiB"), value / 1048576.0);
296 
297 	text = buffer;
298 }
299 
300 
301 const char*
302 MemoryDataSource::Unit() const
303 {
304 	return B_TRANSLATE("MiB");
305 }
306 
307 
308 //	#pragma mark -
309 
310 
311 UsedMemoryDataSource::UsedMemoryDataSource()
312 {
313 }
314 
315 
316 UsedMemoryDataSource::~UsedMemoryDataSource()
317 {
318 }
319 
320 
321 DataSource*
322 UsedMemoryDataSource::Copy() const
323 {
324 	return new UsedMemoryDataSource(*this);
325 }
326 
327 
328 int64
329 UsedMemoryDataSource::NextValue(SystemInfo& info)
330 {
331 	return info.UsedMemory();
332 }
333 
334 
335 const char*
336 UsedMemoryDataSource::InternalName() const
337 {
338 	return "Used memory";
339 }
340 
341 
342 const char*
343 UsedMemoryDataSource::Label() const
344 {
345 	return B_TRANSLATE("Used memory");
346 }
347 
348 
349 const char*
350 UsedMemoryDataSource::ShortLabel() const
351 {
352 	return B_TRANSLATE("Memory");
353 }
354 
355 
356 bool
357 UsedMemoryDataSource::Primary() const
358 {
359 	return true;
360 }
361 
362 
363 //	#pragma mark -
364 
365 
366 CachedMemoryDataSource::CachedMemoryDataSource()
367 {
368 	fColor = (rgb_color){0, 200, 0};
369 }
370 
371 
372 CachedMemoryDataSource::~CachedMemoryDataSource()
373 {
374 }
375 
376 
377 DataSource*
378 CachedMemoryDataSource::Copy() const
379 {
380 	return new CachedMemoryDataSource(*this);
381 }
382 
383 
384 int64
385 CachedMemoryDataSource::NextValue(SystemInfo& info)
386 {
387 	return info.CachedMemory();
388 }
389 
390 
391 const char*
392 CachedMemoryDataSource::InternalName() const
393 {
394 	return "Cached memory";
395 }
396 
397 
398 const char*
399 CachedMemoryDataSource::Label() const
400 {
401 	return B_TRANSLATE("Cached memory");
402 }
403 
404 
405 const char*
406 CachedMemoryDataSource::ShortLabel() const
407 {
408 	return B_TRANSLATE("Cache");
409 }
410 
411 
412 bool
413 CachedMemoryDataSource::Primary() const
414 {
415 	return true;
416 }
417 
418 
419 //	#pragma mark -
420 
421 
422 SwapSpaceDataSource::SwapSpaceDataSource()
423 {
424 	SystemInfo info;
425 
426 	fColor = (rgb_color){0, 120, 0};
427 	fMaximum = info.MaxSwapSpace();
428 }
429 
430 
431 SwapSpaceDataSource::~SwapSpaceDataSource()
432 {
433 }
434 
435 
436 DataSource*
437 SwapSpaceDataSource::Copy() const
438 {
439 	return new SwapSpaceDataSource(*this);
440 }
441 
442 
443 int64
444 SwapSpaceDataSource::NextValue(SystemInfo& info)
445 {
446 	return info.UsedSwapSpace();
447 }
448 
449 
450 const char*
451 SwapSpaceDataSource::InternalName() const
452 {
453 	return "Swap space";
454 }
455 
456 
457 const char*
458 SwapSpaceDataSource::Label() const
459 {
460 	return B_TRANSLATE("Swap space");
461 }
462 
463 
464 const char*
465 SwapSpaceDataSource::ShortLabel() const
466 {
467 	return B_TRANSLATE("Swap");
468 }
469 
470 
471 bool
472 SwapSpaceDataSource::Primary() const
473 {
474 	return true;
475 }
476 
477 
478 //	#pragma mark -
479 
480 
481 BlockCacheDataSource::BlockCacheDataSource()
482 {
483 	fColor = (rgb_color){0, 0, 120};
484 }
485 
486 
487 BlockCacheDataSource::~BlockCacheDataSource()
488 {
489 }
490 
491 
492 DataSource*
493 BlockCacheDataSource::Copy() const
494 {
495 	return new BlockCacheDataSource(*this);
496 }
497 
498 
499 int64
500 BlockCacheDataSource::NextValue(SystemInfo& info)
501 {
502 	return info.BlockCacheMemory();
503 }
504 
505 
506 const char*
507 BlockCacheDataSource::InternalName() const
508 {
509 	return "Block cache memory";
510 }
511 
512 
513 const char*
514 BlockCacheDataSource::Label() const
515 {
516 	return B_TRANSLATE("Block cache memory");
517 }
518 
519 
520 const char*
521 BlockCacheDataSource::ShortLabel() const
522 {
523 	return B_TRANSLATE("Block cache");
524 }
525 
526 
527 //	#pragma mark -
528 
529 
530 SemaphoresDataSource::SemaphoresDataSource()
531 {
532 	SystemInfo info;
533 
534 	fMinimum = 0;
535 	fMaximum = info.MaxSemaphores();
536 
537 	fColor = (rgb_color){100, 200, 100};
538 }
539 
540 
541 SemaphoresDataSource::~SemaphoresDataSource()
542 {
543 }
544 
545 
546 DataSource*
547 SemaphoresDataSource::Copy() const
548 {
549 	return new SemaphoresDataSource(*this);
550 }
551 
552 
553 int64
554 SemaphoresDataSource::NextValue(SystemInfo& info)
555 {
556 	return info.UsedSemaphores();
557 }
558 
559 
560 const char*
561 SemaphoresDataSource::InternalName() const
562 {
563 	return "Semaphores";
564 }
565 
566 
567 const char*
568 SemaphoresDataSource::Label() const
569 {
570 	return B_TRANSLATE("Semaphores");
571 }
572 
573 
574 const char*
575 SemaphoresDataSource::ShortLabel() const
576 {
577 	return B_TRANSLATE("Sems");
578 }
579 
580 
581 bool
582 SemaphoresDataSource::AdaptiveScale() const
583 {
584 	return true;
585 }
586 
587 
588 //	#pragma mark -
589 
590 
591 PortsDataSource::PortsDataSource()
592 {
593 	SystemInfo info;
594 
595 	fMinimum = 0;
596 	fMaximum = info.MaxPorts();
597 
598 	fColor = (rgb_color){180, 200, 180};
599 }
600 
601 
602 PortsDataSource::~PortsDataSource()
603 {
604 }
605 
606 
607 DataSource*
608 PortsDataSource::Copy() const
609 {
610 	return new PortsDataSource(*this);
611 }
612 
613 
614 int64
615 PortsDataSource::NextValue(SystemInfo& info)
616 {
617 	return info.UsedPorts();
618 }
619 
620 
621 const char*
622 PortsDataSource::InternalName() const
623 {
624 	return "Ports";
625 }
626 
627 
628 const char*
629 PortsDataSource::Label() const
630 {
631 	return B_TRANSLATE("Ports");
632 }
633 
634 
635 bool
636 PortsDataSource::AdaptiveScale() const
637 {
638 	return true;
639 }
640 
641 
642 //	#pragma mark -
643 
644 
645 ThreadsDataSource::ThreadsDataSource()
646 {
647 	SystemInfo info;
648 
649 	fMinimum = 0;
650 	fMaximum = info.MaxThreads();
651 
652 	fColor = (rgb_color){0, 0, 200};
653 }
654 
655 
656 ThreadsDataSource::~ThreadsDataSource()
657 {
658 }
659 
660 
661 DataSource*
662 ThreadsDataSource::Copy() const
663 {
664 	return new ThreadsDataSource(*this);
665 }
666 
667 
668 int64
669 ThreadsDataSource::NextValue(SystemInfo& info)
670 {
671 	return info.UsedThreads();
672 }
673 
674 
675 const char*
676 ThreadsDataSource::InternalName() const
677 {
678 	return "Threads";
679 }
680 
681 
682 const char*
683 ThreadsDataSource::Label() const
684 {
685 	return B_TRANSLATE("Threads");
686 }
687 
688 
689 bool
690 ThreadsDataSource::AdaptiveScale() const
691 {
692 	return true;
693 }
694 
695 
696 //	#pragma mark -
697 
698 
699 TeamsDataSource::TeamsDataSource()
700 {
701 	SystemInfo info;
702 
703 	fMinimum = 0;
704 	fMaximum = info.MaxTeams();
705 
706 	fColor = (rgb_color){0, 150, 255};
707 }
708 
709 
710 TeamsDataSource::~TeamsDataSource()
711 {
712 }
713 
714 
715 DataSource*
716 TeamsDataSource::Copy() const
717 {
718 	return new TeamsDataSource(*this);
719 }
720 
721 
722 int64
723 TeamsDataSource::NextValue(SystemInfo& info)
724 {
725 	return info.UsedTeams();
726 }
727 
728 
729 const char*
730 TeamsDataSource::InternalName() const
731 {
732 	return "Teams";
733 }
734 
735 
736 const char*
737 TeamsDataSource::Label() const
738 {
739 	return B_TRANSLATE("Teams");
740 }
741 
742 
743 bool
744 TeamsDataSource::AdaptiveScale() const
745 {
746 	return true;
747 }
748 
749 
750 //	#pragma mark -
751 
752 
753 RunningAppsDataSource::RunningAppsDataSource()
754 {
755 	SystemInfo info;
756 
757 	fMinimum = 0;
758 	fMaximum = info.MaxRunningApps();
759 
760 	fColor = (rgb_color){100, 150, 255};
761 }
762 
763 
764 RunningAppsDataSource::~RunningAppsDataSource()
765 {
766 }
767 
768 
769 DataSource*
770 RunningAppsDataSource::Copy() const
771 {
772 	return new RunningAppsDataSource(*this);
773 }
774 
775 
776 int64
777 RunningAppsDataSource::NextValue(SystemInfo& info)
778 {
779 	return info.UsedRunningApps();
780 }
781 
782 
783 const char*
784 RunningAppsDataSource::InternalName() const
785 {
786 	return "Running applications";
787 }
788 
789 
790 const char*
791 RunningAppsDataSource::Label() const
792 {
793 	return B_TRANSLATE("Running applications");
794 }
795 
796 
797 const char*
798 RunningAppsDataSource::ShortLabel() const
799 {
800 	return B_TRANSLATE("Apps");
801 }
802 
803 
804 bool
805 RunningAppsDataSource::AdaptiveScale() const
806 {
807 	return true;
808 }
809 
810 
811 //	#pragma mark -
812 
813 
814 CPUFrequencyDataSource::CPUFrequencyDataSource(int32 cpu)
815 {
816 	fMinimum = 0;
817 	fMaximum = 1000000000ll;
818 		// Maximum initially set at 1GHz, will be automatically raised if the actual frequency gets
819 		// higher than that
820 
821 	_SetCPU(cpu);
822 }
823 
824 
825 CPUFrequencyDataSource::CPUFrequencyDataSource(const CPUFrequencyDataSource& other)
826 	: DataSource(other)
827 {
828 	fCPU = other.fCPU;
829 	fLabel = other.fLabel;
830 	fShortLabel = other.fShortLabel;
831 }
832 
833 
834 CPUFrequencyDataSource::~CPUFrequencyDataSource()
835 {
836 }
837 
838 
839 DataSource*
840 CPUFrequencyDataSource::Copy() const
841 {
842 	return new CPUFrequencyDataSource(*this);
843 }
844 
845 
846 DataSource*
847 CPUFrequencyDataSource::CopyForCPU(int32 cpu) const
848 {
849 	CPUFrequencyDataSource* copy = new CPUFrequencyDataSource(*this);
850 	copy->_SetCPU(cpu);
851 
852 	return copy;
853 }
854 
855 
856 void
857 CPUFrequencyDataSource::Print(BString& text, int64 value) const
858 {
859 	text.SetToFormat("%" PRId64 " MHz", value / 1000000);
860 }
861 
862 
863 int64
864 CPUFrequencyDataSource::NextValue(SystemInfo& info)
865 {
866 	int64 value = info.CPUCurrentFrequency(fCPU);
867 
868 	if (value > fMaximum)
869 		SetLimits(0, value);
870 
871 	return value;
872 }
873 
874 
875 const char*
876 CPUFrequencyDataSource::Label() const
877 {
878 	return fLabel.String();
879 }
880 
881 
882 const char*
883 CPUFrequencyDataSource::ShortLabel() const
884 {
885 	return fShortLabel.String();
886 }
887 
888 
889 const char*
890 CPUFrequencyDataSource::InternalName() const
891 {
892 	return "CPU speed";
893 }
894 
895 
896 const char*
897 CPUFrequencyDataSource::Name() const
898 {
899 	return B_TRANSLATE("CPU speed");
900 }
901 
902 
903 int32
904 CPUFrequencyDataSource::CPU() const
905 {
906 	return fCPU;
907 }
908 
909 
910 bool
911 CPUFrequencyDataSource::PerCPU() const
912 {
913 	return true;
914 }
915 
916 
917 bool
918 CPUFrequencyDataSource::Primary() const
919 {
920 	return true;
921 }
922 
923 
924 void
925 CPUFrequencyDataSource::_SetCPU(int32 cpu)
926 {
927 	fCPU = cpu;
928 
929 	if (SystemInfo().CPUCount() > 1) {
930 		fLabel.SetToFormat(B_TRANSLATE("CPU %d speed"), cpu + 1);
931 		fShortLabel.SetToFormat(B_TRANSLATE("CPU %d"), cpu + 1);
932 	} else {
933 		fLabel = B_TRANSLATE("CPU usage");
934 		fShortLabel = B_TRANSLATE("CPU");
935 	}
936 
937 	const rgb_color kColors[] = {
938 		// TODO: find some better defaults...
939 		{200, 0, 200},
940 		{0, 200, 200},
941 		{80, 80, 80},
942 		{230, 150, 50},
943 		{255, 0, 0},
944 		{0, 255, 0},
945 		{0, 0, 255},
946 		{0, 150, 230}
947 	};
948 	const uint32 kNumColors = B_COUNT_OF(kColors);
949 
950 	fColor = kColors[cpu % kNumColors];
951 }
952 
953 
954 //	#pragma mark -
955 
956 
957 CPUUsageDataSource::CPUUsageDataSource(int32 cpu)
958 	:
959 	fPreviousActive(0),
960 	fPreviousTime(0)
961 {
962 	fMinimum = 0;
963 	fMaximum = 1000;
964 
965 	_SetCPU(cpu);
966 }
967 
968 
969 CPUUsageDataSource::CPUUsageDataSource(const CPUUsageDataSource& other)
970 	: DataSource(other)
971 {
972 	fPreviousActive = other.fPreviousActive;
973 	fPreviousTime = other.fPreviousTime;
974 	fCPU = other.fCPU;
975 	fLabel = other.fLabel;
976 	fShortLabel = other.fShortLabel;
977 }
978 
979 
980 CPUUsageDataSource::~CPUUsageDataSource()
981 {
982 }
983 
984 
985 DataSource*
986 CPUUsageDataSource::Copy() const
987 {
988 	return new CPUUsageDataSource(*this);
989 }
990 
991 
992 DataSource*
993 CPUUsageDataSource::CopyForCPU(int32 cpu) const
994 {
995 	CPUUsageDataSource* copy = new CPUUsageDataSource(*this);
996 	copy->_SetCPU(cpu);
997 
998 	return copy;
999 }
1000 
1001 
1002 void
1003 CPUUsageDataSource::Print(BString& text, int64 value) const
1004 {
1005 	char buffer[32];
1006 	snprintf(buffer, sizeof(buffer), "%.1f%%", value / 10.0);
1007 
1008 	text = buffer;
1009 }
1010 
1011 
1012 int64
1013 CPUUsageDataSource::NextValue(SystemInfo& info)
1014 {
1015 	bigtime_t active = info.CPUActiveTime(fCPU);
1016 
1017 	int64 percent = int64(1000.0 * (active - fPreviousActive)
1018 		/ (info.Time() - fPreviousTime));
1019 	if (percent < 0)
1020 		percent = 0;
1021 	if (percent > 1000)
1022 		percent = 1000;
1023 
1024 	fPreviousActive = active;
1025 	fPreviousTime = info.Time();
1026 
1027 	return percent;
1028 }
1029 
1030 
1031 const char*
1032 CPUUsageDataSource::Label() const
1033 {
1034 	return fLabel.String();
1035 }
1036 
1037 
1038 const char*
1039 CPUUsageDataSource::ShortLabel() const
1040 {
1041 	return fShortLabel.String();
1042 }
1043 
1044 
1045 const char*
1046 CPUUsageDataSource::InternalName() const
1047 {
1048 	return "CPU usage";
1049 }
1050 
1051 
1052 const char*
1053 CPUUsageDataSource::Name() const
1054 {
1055 	return B_TRANSLATE("CPU usage");
1056 }
1057 
1058 
1059 int32
1060 CPUUsageDataSource::CPU() const
1061 {
1062 	return fCPU;
1063 }
1064 
1065 
1066 bool
1067 CPUUsageDataSource::PerCPU() const
1068 {
1069 	return true;
1070 }
1071 
1072 
1073 bool
1074 CPUUsageDataSource::Primary() const
1075 {
1076 	return true;
1077 }
1078 
1079 
1080 void
1081 CPUUsageDataSource::_SetCPU(int32 cpu)
1082 {
1083 	fCPU = cpu;
1084 
1085 	if (SystemInfo().CPUCount() > 1) {
1086 		fLabel.SetToFormat(B_TRANSLATE("CPU %d usage"), cpu + 1);
1087 		fShortLabel.SetToFormat(B_TRANSLATE("CPU %d"), cpu + 1);
1088 
1089 	} else {
1090 		fLabel = B_TRANSLATE("CPU usage");
1091 		fShortLabel = B_TRANSLATE("CPU");
1092 	}
1093 
1094 	const rgb_color kColors[] = {
1095 		// TODO: find some better defaults...
1096 		{200, 0, 200},
1097 		{0, 200, 200},
1098 		{80, 80, 80},
1099 		{230, 150, 50},
1100 		{255, 0, 0},
1101 		{0, 255, 0},
1102 		{0, 0, 255},
1103 		{0, 150, 230}
1104 	};
1105 	const uint32 kNumColors = B_COUNT_OF(kColors);
1106 
1107 	fColor = kColors[cpu % kNumColors];
1108 }
1109 
1110 
1111 //	#pragma mark -
1112 
1113 
1114 CPUCombinedUsageDataSource::CPUCombinedUsageDataSource()
1115 	:
1116 	fPreviousActive(0),
1117 	fPreviousTime(0)
1118 {
1119 	fMinimum = 0;
1120 	fMaximum = 1000;
1121 
1122 	fColor = (rgb_color){200, 200, 0};
1123 }
1124 
1125 
1126 CPUCombinedUsageDataSource::CPUCombinedUsageDataSource(
1127 		const CPUCombinedUsageDataSource& other)
1128 	: DataSource(other)
1129 {
1130 	fPreviousActive = other.fPreviousActive;
1131 	fPreviousTime = other.fPreviousTime;
1132 }
1133 
1134 
1135 CPUCombinedUsageDataSource::~CPUCombinedUsageDataSource()
1136 {
1137 }
1138 
1139 
1140 DataSource*
1141 CPUCombinedUsageDataSource::Copy() const
1142 {
1143 	return new CPUCombinedUsageDataSource(*this);
1144 }
1145 
1146 
1147 void
1148 CPUCombinedUsageDataSource::Print(BString& text, int64 value) const
1149 {
1150 	char buffer[32];
1151 	snprintf(buffer, sizeof(buffer), "%.1f%%", value / 10.0);
1152 
1153 	text = buffer;
1154 }
1155 
1156 
1157 int64
1158 CPUCombinedUsageDataSource::NextValue(SystemInfo& info)
1159 {
1160 	int32 running = 0;
1161 	bigtime_t active = 0;
1162 
1163 	for (uint32 cpu = 0; cpu < info.CPUCount(); cpu++) {
1164 		active += info.CPUActiveTime(cpu);
1165 		running++;
1166 			// TODO: take disabled CPUs into account
1167 	}
1168 
1169 	int64 percent = int64(1000.0 * (active - fPreviousActive)
1170 		/ (running * (info.Time() - fPreviousTime)));
1171 	if (percent < 0)
1172 		percent = 0;
1173 	if (percent > 1000)
1174 		percent = 1000;
1175 
1176 	fPreviousActive = active;
1177 	fPreviousTime = info.Time();
1178 
1179 	return percent;
1180 }
1181 
1182 
1183 const char*
1184 CPUCombinedUsageDataSource::Label() const
1185 {
1186 	return B_TRANSLATE("CPU usage");
1187 }
1188 
1189 
1190 const char*
1191 CPUCombinedUsageDataSource::ShortLabel() const
1192 {
1193 	return B_TRANSLATE("CPU");
1194 }
1195 
1196 
1197 const char*
1198 CPUCombinedUsageDataSource::InternalName() const
1199 {
1200 	return "CPU usage (combined)";
1201 }
1202 
1203 
1204 const char*
1205 CPUCombinedUsageDataSource::Name() const
1206 {
1207 	return B_TRANSLATE("CPU usage (combined)");
1208 }
1209 
1210 
1211 bool
1212 CPUCombinedUsageDataSource::MultiCPUOnly() const
1213 {
1214 	return true;
1215 }
1216 
1217 
1218 bool
1219 CPUCombinedUsageDataSource::Primary() const
1220 {
1221 	return true;
1222 }
1223 
1224 
1225 //	#pragma mark -
1226 
1227 
1228 PageFaultsDataSource::PageFaultsDataSource()
1229 	:
1230 	fPreviousFaults(0),
1231 	fPreviousTime(0)
1232 {
1233 	SystemInfo info;
1234 	NextValue(info);
1235 
1236 	fMinimum = 0;
1237 	fMaximum = 1000000000LL;
1238 
1239 	fColor = (rgb_color){200, 0, 150, 0};
1240 }
1241 
1242 
1243 PageFaultsDataSource::PageFaultsDataSource(const PageFaultsDataSource& other)
1244 	: DataSource(other)
1245 {
1246 	fPreviousFaults = other.fPreviousFaults;
1247 	fPreviousTime = other.fPreviousTime;
1248 }
1249 
1250 
1251 PageFaultsDataSource::~PageFaultsDataSource()
1252 {
1253 }
1254 
1255 
1256 DataSource*
1257 PageFaultsDataSource::Copy() const
1258 {
1259 	return new PageFaultsDataSource(*this);
1260 }
1261 
1262 
1263 void
1264 PageFaultsDataSource::Print(BString& text, int64 value) const
1265 {
1266 	char buffer[32];
1267 	snprintf(buffer, sizeof(buffer), B_TRANSLATE("%.1f faults/s"),
1268 		value / 1024.0);
1269 
1270 	text = buffer;
1271 }
1272 
1273 
1274 int64
1275 PageFaultsDataSource::NextValue(SystemInfo& info)
1276 {
1277 	uint64 faults = info.PageFaults();
1278 
1279 	int64 faultsPerSecond = uint64(1024 * double(faults - fPreviousFaults)
1280 		/ (info.Time() - fPreviousTime) * 1000000.0);
1281 
1282 	fPreviousFaults = faults;
1283 	fPreviousTime = info.Time();
1284 
1285 	return faultsPerSecond;
1286 }
1287 
1288 
1289 const char*
1290 PageFaultsDataSource::Label() const
1291 {
1292 	return B_TRANSLATE("Page faults");
1293 }
1294 
1295 
1296 const char*
1297 PageFaultsDataSource::ShortLabel() const
1298 {
1299 	return B_TRANSLATE("P-faults");
1300 }
1301 
1302 
1303 const char*
1304 PageFaultsDataSource::InternalName() const
1305 {
1306 	return "Page faults";
1307 }
1308 
1309 
1310 const char*
1311 PageFaultsDataSource::Name() const
1312 {
1313 	return B_TRANSLATE("Page faults");
1314 }
1315 
1316 
1317 bool
1318 PageFaultsDataSource::AdaptiveScale() const
1319 {
1320 	return true;
1321 }
1322 
1323 
1324 bool
1325 PageFaultsDataSource::Primary() const
1326 {
1327 	return false;
1328 }
1329 
1330 
1331 //	#pragma mark -
1332 
1333 
1334 NetworkUsageDataSource::NetworkUsageDataSource(bool in)
1335 	:
1336 	fIn(in),
1337 	fPreviousBytes(0),
1338 	fPreviousTime(0)
1339 {
1340 	SystemInfo info;
1341 	NextValue(info);
1342 
1343 	fMinimum = 0;
1344 	fMaximum = 1000000000LL;
1345 
1346 	fColor = fIn ? (rgb_color){200, 150, 0} : (rgb_color){200, 220, 0};
1347 }
1348 
1349 
1350 NetworkUsageDataSource::NetworkUsageDataSource(
1351 		const NetworkUsageDataSource& other)
1352 	: DataSource(other)
1353 {
1354 	fIn = other.fIn;
1355 	fPreviousBytes = other.fPreviousBytes;
1356 	fPreviousTime = other.fPreviousTime;
1357 }
1358 
1359 
1360 NetworkUsageDataSource::~NetworkUsageDataSource()
1361 {
1362 }
1363 
1364 
1365 DataSource*
1366 NetworkUsageDataSource::Copy() const
1367 {
1368 	return new NetworkUsageDataSource(*this);
1369 }
1370 
1371 
1372 void
1373 NetworkUsageDataSource::Print(BString& text, int64 value) const
1374 {
1375 	char buffer[32];
1376 	string_for_rate(value, buffer, sizeof(buffer));
1377 
1378 	text = buffer;
1379 }
1380 
1381 
1382 int64
1383 NetworkUsageDataSource::NextValue(SystemInfo& info)
1384 {
1385 	uint64 transferred = fIn ? info.NetworkReceived() : info.NetworkSent();
1386 
1387 	int64 bytesPerSecond = uint64(double(transferred - fPreviousBytes)
1388 		/ (info.Time() - fPreviousTime) * 1000000.0);
1389 
1390 	fPreviousBytes = transferred;
1391 	fPreviousTime = info.Time();
1392 
1393 	return bytesPerSecond;
1394 }
1395 
1396 
1397 const char*
1398 NetworkUsageDataSource::Label() const
1399 {
1400 	return fIn ? B_TRANSLATE("Receiving") : B_TRANSLATE("Sending");
1401 }
1402 
1403 
1404 const char*
1405 NetworkUsageDataSource::ShortLabel() const
1406 {
1407 	return fIn ? B_TRANSLATE_COMMENT("RX", "Shorter version for Receiving.") :
1408 		B_TRANSLATE_COMMENT("TX", "Shorter version for Sending");
1409 }
1410 
1411 
1412 const char*
1413 NetworkUsageDataSource::InternalName() const
1414 {
1415 	return fIn ? "Network receive" : "Network send";
1416 }
1417 
1418 
1419 const char*
1420 NetworkUsageDataSource::Name() const
1421 {
1422 	return fIn ? B_TRANSLATE("Network receive") : B_TRANSLATE("Network send");
1423 }
1424 
1425 
1426 bool
1427 NetworkUsageDataSource::AdaptiveScale() const
1428 {
1429 	return true;
1430 }
1431 
1432 
1433 scale_type
1434 NetworkUsageDataSource::ScaleType() const
1435 {
1436 	return kBytePerSecondScale;
1437 }
1438 
1439 
1440 bool
1441 NetworkUsageDataSource::Primary() const
1442 {
1443 	return true;
1444 }
1445 
1446 
1447 //	#pragma mark -
1448 
1449 
1450 ClipboardSizeDataSource::ClipboardSizeDataSource(bool text)
1451 {
1452 	fMinimum = 0;
1453 	fMaximum = UINT32_MAX;
1454 	fText = text;
1455 
1456 	fColor = (rgb_color){0, 150, 255};
1457 }
1458 
1459 
1460 ClipboardSizeDataSource::ClipboardSizeDataSource(
1461 		const ClipboardSizeDataSource& other)
1462 	: DataSource(other)
1463 {
1464 	fText = other.fText;
1465 }
1466 
1467 
1468 ClipboardSizeDataSource::~ClipboardSizeDataSource()
1469 {
1470 }
1471 
1472 
1473 DataSource*
1474 ClipboardSizeDataSource::Copy() const
1475 {
1476 	return new ClipboardSizeDataSource(*this);
1477 }
1478 
1479 
1480 int64
1481 ClipboardSizeDataSource::NextValue(SystemInfo& info)
1482 {
1483 	if (fText)
1484 		return info.ClipboardTextSize()/* / 1024*/;
1485 	return info.ClipboardSize()/* / 1024*/;
1486 }
1487 
1488 
1489 const char*
1490 ClipboardSizeDataSource::InternalName() const
1491 {
1492 	return fText ? "Text clipboard size" : "Raw clipboard size";
1493 }
1494 
1495 
1496 const char*
1497 ClipboardSizeDataSource::Label() const
1498 {
1499 	return fText ? B_TRANSLATE("Text clipboard")
1500 		: B_TRANSLATE("Raw clipboard");
1501 }
1502 
1503 
1504 const char*
1505 ClipboardSizeDataSource::Unit() const
1506 {
1507 	return "bytes"/*"KB"*/;
1508 }
1509 
1510 
1511 bool
1512 ClipboardSizeDataSource::AdaptiveScale() const
1513 {
1514 	return true;
1515 }
1516 
1517 
1518 //	#pragma mark -
1519 
1520 
1521 MediaNodesDataSource::MediaNodesDataSource()
1522 {
1523 	SystemInfo info;
1524 
1525 	fMinimum = 0;
1526 	fMaximum = INT32_MAX;
1527 
1528 	fColor = (rgb_color){255, 150, 225};
1529 }
1530 
1531 
1532 MediaNodesDataSource::~MediaNodesDataSource()
1533 {
1534 }
1535 
1536 
1537 DataSource*
1538 MediaNodesDataSource::Copy() const
1539 {
1540 	return new MediaNodesDataSource(*this);
1541 }
1542 
1543 
1544 int64
1545 MediaNodesDataSource::NextValue(SystemInfo& info)
1546 {
1547 	return info.MediaNodes();
1548 }
1549 
1550 
1551 const char*
1552 MediaNodesDataSource::InternalName() const
1553 {
1554 	return "Media nodes";
1555 }
1556 
1557 
1558 const char*
1559 MediaNodesDataSource::Label() const
1560 {
1561 	return B_TRANSLATE("Media nodes");
1562 }
1563 
1564 
1565 bool
1566 MediaNodesDataSource::AdaptiveScale() const
1567 {
1568 	return true;
1569 }
1570 
1571 
1572