1 /* 2 * Copyright 2000, Georges-Edouard Berenger. All rights reserved. 3 * Distributed under the terms of the MIT License. 4 */ 5 6 7 #include "MemoryBarMenu.h" 8 #include "MemoryBarMenuItem.h" 9 #include "KernelMemoryBarMenuItem.h" 10 #include "ProcessController.h" 11 12 #include <Bitmap.h> 13 #include <Roster.h> 14 #include <StringForSize.h> 15 #include <Window.h> 16 17 #include <stdlib.h> 18 19 20 #define EXTRA 10 21 22 float gMemoryTextWidth; 23 24 25 MemoryBarMenu::MemoryBarMenu(const char* name, info_pack* infos, system_info& systemInfo) 26 : BMenu(name), 27 fFirstShow(true) 28 { 29 fTeamCount = systemInfo.used_teams + EXTRA; 30 SetFlags(Flags() | B_PULSE_NEEDED); 31 32 fTeamList = (team_id*)malloc(sizeof (team_id) * fTeamCount); 33 34 unsigned int k; 35 for (k = 0; k < systemInfo.used_teams; k++) { 36 fTeamList[k] = infos[k].team_info.team; 37 } 38 39 while (k < fTeamCount) { 40 fTeamList[k++] = -1; 41 } 42 43 char buffer[64]; 44 string_for_size(99999999.9, buffer, sizeof(buffer)); 45 gMemoryTextWidth = 2 * StringWidth(buffer) + 32; 46 47 fRecycleCount = EXTRA; 48 fRecycleList = (MRecycleItem*)malloc(sizeof(MRecycleItem) * fRecycleCount); 49 SetFont(be_plain_font); 50 AddItem(new KernelMemoryBarMenuItem(systemInfo)); 51 } 52 53 54 MemoryBarMenu::~MemoryBarMenu() 55 { 56 free(fTeamList); 57 free(fRecycleList); 58 } 59 60 61 void 62 MemoryBarMenu::Draw(BRect updateRect) 63 { 64 if (fFirstShow) { 65 Pulse(); 66 fFirstShow = false; 67 } 68 69 BMenu::Draw(updateRect); 70 } 71 72 73 void 74 MemoryBarMenu::Pulse() 75 { 76 system_info sinfo; 77 get_system_info(&sinfo); 78 int64 committedMemory = (int64)sinfo.used_pages * B_PAGE_SIZE / 1024; 79 int64 cachedMemory = (int64)sinfo.cached_pages * B_PAGE_SIZE / 1024; 80 Window()->BeginViewTransaction(); 81 82 // create the list of items to remove, for their team is gone. Update the old teams. 83 int lastRecycle = 0; 84 int firstRecycle = 0; 85 int k; 86 MemoryBarMenuItem* item; 87 int total = 0; 88 for (k = 1; (item = (MemoryBarMenuItem*)ItemAt(k)) != NULL; k++) { 89 int m = item->UpdateSituation(committedMemory); 90 if (m < 0) { 91 if (lastRecycle == fRecycleCount) { 92 fRecycleCount += EXTRA; 93 fRecycleList = (MRecycleItem*)realloc(fRecycleList, 94 sizeof(MRecycleItem) * fRecycleCount); 95 } 96 fRecycleList[lastRecycle].index = k; 97 fRecycleList[lastRecycle++].item = item; 98 } else { 99 if (lastRecycle > 0) { 100 RemoveItems(fRecycleList[0].index, lastRecycle, true); 101 k -= lastRecycle; 102 lastRecycle = 0; 103 } 104 total += m; 105 } 106 } 107 108 // Look new teams that have appeared. Create an item for them, or recycle from the list. 109 int32 cookie = 0; 110 info_pack infos; 111 item = NULL; 112 while (get_next_team_info(&cookie, &infos.team_info) == B_OK) { 113 unsigned int j = 0; 114 while (j < fTeamCount && infos.team_info.team != fTeamList[j]) { 115 j++; 116 } 117 118 if (j == fTeamCount) { 119 // new team 120 team_info info; 121 j = 0; 122 while (j < fTeamCount && fTeamList[j] != -1) { 123 if (get_team_info(fTeamList[j], &info) != B_OK) 124 fTeamList[j] = -1; 125 else 126 j++; 127 } 128 129 if (j == fTeamCount) { 130 fTeamCount += 10; 131 fTeamList = (team_id*)realloc(fTeamList, sizeof(team_id) * fTeamCount); 132 } 133 134 fTeamList[j] = infos.team_info.team; 135 if (!get_team_name_and_icon(infos, true)) { 136 // the team is already gone! 137 fTeamList[j] = -1; 138 } else { 139 if (!item && firstRecycle < lastRecycle) 140 item = fRecycleList[firstRecycle++].item; 141 142 if (item) 143 item->Reset(infos.team_name, infos.team_info.team, infos.team_icon, true); 144 else { 145 AddItem(item = new MemoryBarMenuItem(infos.team_name, 146 infos.team_info.team, infos.team_icon, true, NULL)); 147 } 148 149 int m = item->UpdateSituation(committedMemory); 150 if (m >= 0) { 151 total += m; 152 item = NULL; 153 } else 154 fTeamList[j] = -1; 155 } 156 } 157 } 158 159 if (item) { 160 RemoveItem(item); 161 delete item; 162 } 163 164 // Delete the items that haven't been recycled. 165 if (firstRecycle < lastRecycle) { 166 RemoveItems(IndexOf(fRecycleList[firstRecycle].item), 167 lastRecycle - firstRecycle, true); 168 } 169 170 fLastTotalTime = system_time(); 171 KernelMemoryBarMenuItem *kernelItem; 172 if ((kernelItem = (KernelMemoryBarMenuItem*)ItemAt(0)) != NULL) 173 kernelItem->UpdateSituation(committedMemory, cachedMemory); 174 175 Window()->EndViewTransaction(); 176 Window()->Flush(); 177 } 178