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