btrfs: Attempt to fix GCC2 build.
[haiku.git] / src / apps / processcontroller / MemoryBarMenu.cpp
blob125189dee003ffc72ee19cfed457d69d326bb20f
1 /*
2 ProcessController © 2000, Georges-Edouard Berenger, All Rights Reserved.
3 Copyright (C) 2004 beunited.org
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public
16 License along with this library; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 #include "MemoryBarMenu.h"
22 #include "MemoryBarMenuItem.h"
23 #include "KernelMemoryBarMenuItem.h"
24 #include "ProcessController.h"
26 #include <Bitmap.h>
27 #include <Roster.h>
28 #include <StringForSize.h>
29 #include <Window.h>
31 #include <stdlib.h>
34 #define EXTRA 10
36 float gMemoryTextWidth;
39 MemoryBarMenu::MemoryBarMenu(const char* name, info_pack* infos, system_info& systemInfo)
40 : BMenu(name),
41 fFirstShow(true)
43 fTeamCount = systemInfo.used_teams + EXTRA;
44 SetFlags(Flags() | B_PULSE_NEEDED);
46 fTeamList = (team_id*)malloc(sizeof (team_id) * fTeamCount);
48 unsigned int k;
49 for (k = 0; k < systemInfo.used_teams; k++) {
50 fTeamList[k] = infos[k].team_info.team;
53 while (k < fTeamCount) {
54 fTeamList[k++] = -1;
57 char buffer[64];
58 string_for_size(99999999.9, buffer, sizeof(buffer));
59 gMemoryTextWidth = 2 * StringWidth(buffer) + 32;
61 fRecycleCount = EXTRA;
62 fRecycleList = (MRecycleItem*)malloc(sizeof(MRecycleItem) * fRecycleCount);
63 SetFont(be_plain_font);
64 AddItem(new KernelMemoryBarMenuItem(systemInfo));
68 MemoryBarMenu::~MemoryBarMenu()
70 free(fTeamList);
71 free(fRecycleList);
75 void
76 MemoryBarMenu::Draw(BRect updateRect)
78 if (fFirstShow) {
79 Pulse();
80 fFirstShow = false;
83 BMenu::Draw(updateRect);
87 void
88 MemoryBarMenu::Pulse()
90 system_info sinfo;
91 get_system_info(&sinfo);
92 int64 committedMemory = (int64)sinfo.used_pages * B_PAGE_SIZE / 1024;
93 int64 cachedMemory = (int64)sinfo.cached_pages * B_PAGE_SIZE / 1024;
94 Window()->BeginViewTransaction();
96 // create the list of items to remove, for their team is gone. Update the old teams.
97 int lastRecycle = 0;
98 int firstRecycle = 0;
99 int k;
100 MemoryBarMenuItem* item;
101 int total = 0;
102 for (k = 1; (item = (MemoryBarMenuItem*)ItemAt(k)) != NULL; k++) {
103 int m = item->UpdateSituation(committedMemory);
104 if (m < 0) {
105 if (lastRecycle == fRecycleCount) {
106 fRecycleCount += EXTRA;
107 fRecycleList = (MRecycleItem*)realloc(fRecycleList,
108 sizeof(MRecycleItem) * fRecycleCount);
110 fRecycleList[lastRecycle].index = k;
111 fRecycleList[lastRecycle++].item = item;
112 } else {
113 if (lastRecycle > 0) {
114 RemoveItems(fRecycleList[0].index, lastRecycle, true);
115 k -= lastRecycle;
116 lastRecycle = 0;
118 total += m;
122 // Look new teams that have appeared. Create an item for them, or recycle from the list.
123 int32 cookie = 0;
124 info_pack infos;
125 item = NULL;
126 while (get_next_team_info(&cookie, &infos.team_info) == B_OK) {
127 unsigned int j = 0;
128 while (j < fTeamCount && infos.team_info.team != fTeamList[j]) {
129 j++;
132 if (j == fTeamCount) {
133 // new team
134 team_info info;
135 j = 0;
136 while (j < fTeamCount && fTeamList[j] != -1) {
137 if (get_team_info(fTeamList[j], &info) != B_OK)
138 fTeamList[j] = -1;
139 else
140 j++;
143 if (j == fTeamCount) {
144 fTeamCount += 10;
145 fTeamList = (team_id*)realloc(fTeamList, sizeof(team_id) * fTeamCount);
148 fTeamList[j] = infos.team_info.team;
149 if (!get_team_name_and_icon(infos, true)) {
150 // the team is already gone!
151 delete infos.team_icon;
152 fTeamList[j] = -1;
153 } else {
154 if (!item && firstRecycle < lastRecycle)
155 item = fRecycleList[firstRecycle++].item;
157 if (item)
158 item->Reset(infos.team_name, infos.team_info.team, infos.team_icon, true);
159 else {
160 AddItem(item = new MemoryBarMenuItem(infos.team_name,
161 infos.team_info.team, infos.team_icon, true, NULL));
164 int m = item->UpdateSituation(committedMemory);
165 if (m >= 0) {
166 total += m;
167 item = NULL;
168 } else
169 fTeamList[j] = -1;
174 if (item) {
175 RemoveItem(item);
176 delete item;
179 // Delete the items that haven't been recycled.
180 if (firstRecycle < lastRecycle) {
181 RemoveItems(IndexOf(fRecycleList[firstRecycle].item),
182 lastRecycle - firstRecycle, true);
185 fLastTotalTime = system_time();
186 KernelMemoryBarMenuItem *kernelItem;
187 if ((kernelItem = (KernelMemoryBarMenuItem*)ItemAt(0)) != NULL)
188 kernelItem->UpdateSituation(committedMemory, cachedMemory);
190 Window()->EndViewTransaction();
191 Window()->Flush();