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