Ticket #1746: virtualmemory-changes.diff
File virtualmemory-changes.diff, 18.2 KB (added by , 13 years ago) |
---|
-
src/preferences/virtualmemory/Settings.cpp
1 1 /* 2 * Copyright 2005, Axel Dörfler, axeld@pinc-software.de. All rights reserved. 3 * Distributed under the terms of the MIT License. 2 * Copyright 2005, Axel Dörfler, axeld@pinc-software.de 3 * Copyright 2010-2011, Hamish Morrison, hamish@lavabit.com 4 * All rights reserved. Distributed under the terms of the MIT License. 4 5 */ 5 6 6 7 … … 21 22 22 23 static const char* kWindowSettingsFile = "VM_data"; 23 24 static const char* kVirtualMemorySettings = "virtual_memory"; 25 static const int64 kMegaByte = 1048576; 24 26 25 27 26 28 Settings::Settings() 27 29 : 28 fPositionUpdated(false), 29 fSwapUpdated(false) 30 fPositionUpdated(false) 30 31 { 31 32 ReadWindowSettings(); 32 33 ReadSwapSettings(); … … 50 51 path.Append(kWindowSettingsFile); 51 52 BFile file; 52 53 if (file.SetTo(path.Path(), B_READ_ONLY) == B_OK) 53 // Now read in the data54 54 if (file.Read(&fWindowPosition, sizeof(BPoint)) == sizeof(BPoint)) 55 55 success = true; 56 56 } … … 92 92 void 93 93 Settings::ReadSwapSettings() 94 94 { 95 // read current swap settings from disk 96 void* settings = load_driver_settings("virtual_memory"); 95 void* settings = load_driver_settings(kVirtualMemorySettings); 97 96 if (settings != NULL) { 98 fSwapEnabled = get_driver_boolean_parameter(settings, "vm", false, false); 99 100 const char* string = get_driver_parameter(settings, "swap_size", NULL, NULL); 101 fSwapSize = string ? atoll(string) : 0; 102 103 if (fSwapSize <= 0) { 104 fSwapEnabled = false; 105 fSwapSize = 0; 106 } 97 SetSwapEnabled(get_driver_boolean_parameter(settings, "vm", false, false)); 98 const char* swapSize = get_driver_parameter(settings, "swap_size", NULL, NULL); 99 SetSwapSize(swapSize ? atoll(swapSize) : 0); 100 101 #ifdef SWAP_VOLUME_IMPLEMENTED 102 // we need to hang onto this one 103 fBadVolName = strdup(get_driver_parameter(settings, "swap_volume", NULL, NULL)); 104 105 BVolumeRoster volumeRoster; 106 BVolume temporaryVolume; 107 108 if (fBadVolName != NULL) { 109 status_t result = volumeRoster.GetNextVolume(&temporaryVolume); 110 char volumeName[B_FILE_NAME_LENGTH]; 111 while (result != B_BAD_VALUE) { 112 temporaryVolume.GetName(volumeName); 113 if (strcmp(volumeName, fBadVolName) == 0 114 && temporaryVolume.IsPersistent() && volumeName[0]) { 115 SetSwapVolume(temporaryVolume); 116 break; 117 } 118 result = volumeRoster.GetNextVolume(&temporaryVolume); 119 } 120 } 121 #endif 107 122 unload_driver_settings(settings); 108 } else { 109 // settings are not available, try to find out what the kernel is up to 110 // ToDo: introduce a kernel call for this! 111 fSwapSize = 0; 123 } else 124 SetSwapNull(); 112 125 113 BPath path; 114 if (find_directory(B_COMMON_VAR_DIRECTORY, &path) == B_OK) { 115 path.Append("swap"); 116 BEntry swap(path.Path()); 117 if (swap.GetSize(&fSwapSize) != B_OK) 118 fSwapSize = 0; 119 } 120 121 fSwapEnabled = fSwapSize != 0; 122 } 123 124 // ToDo: read those as well 126 #ifndef SWAP_VOLUME_IMPLEMENTED 125 127 BVolumeRoster volumeRoster; 126 128 volumeRoster.GetBootVolume(&fSwapVolume); 129 #endif 127 130 128 131 fInitialSwapEnabled = fSwapEnabled; 129 132 fInitialSwapSize = fSwapSize; … … 133 136 134 137 void 135 138 Settings::WriteSwapSettings() 136 { 137 if (! SwapChanged())139 { 140 if (!IsRevertible()) 138 141 return; 139 142 140 143 BPath path; … … 145 148 path.Append(kVirtualMemorySettings); 146 149 147 150 BFile file; 148 if (file.SetTo(path.Path(), B_WRITE_ONLY | B_CREATE_FILE | B_ERASE_FILE) != B_OK) 151 if (file.SetTo(path.Path(), B_WRITE_ONLY | B_CREATE_FILE | B_ERASE_FILE) 152 != B_OK) 149 153 return; 150 154 151 155 char buffer[256]; 156 #ifdef SWAP_VOLUME_IMPLEMENTED 157 char volumeName[B_FILE_NAME_LENGTH] = {0}; 158 if (SwapVolume().InitCheck() != B_NO_INIT) 159 SwapVolume().GetName(volumeName); 160 else if (fBadVolName) 161 strcpy(volumeName, fBadVolName); 162 snprintf(buffer, sizeof(buffer), "vm %s\nswap_size %Ld\nswap_volume %s\n", 163 SwapEnabled() ? "on" : "off", SwapSize(), 164 volumeName[0] ? volumeName : NULL); 165 #else 152 166 snprintf(buffer, sizeof(buffer), "vm %s\nswap_size %Ld\n", 153 167 fSwapEnabled ? "on" : "off", fSwapSize); 168 #endif 154 169 155 170 file.Write(buffer, strlen(buffer)); 156 171 } … … 173 188 void 174 189 Settings::SetSwapVolume(BVolume &volume) 175 190 { 176 if (volume.Device() == fSwapVolume.Device()191 if (volume.Device() == SwapVolume().Device() 177 192 || volume.InitCheck() != B_OK) 178 193 return; 179 194 … … 182 197 183 198 184 199 void 185 Settings::SetSwap Defaults()200 Settings::SetSwapNull() 186 201 { 187 fSwapEnabled = true; 188 202 SetSwapEnabled(false); 189 203 BVolumeRoster volumeRoster; 190 volumeRoster.GetBootVolume(&fSwapVolume); 191 192 system_info info; 193 get_system_info(&info); 194 fSwapSize = (off_t)info.max_pages * B_PAGE_SIZE; 204 BVolume temporaryVolume; 205 volumeRoster.GetBootVolume(&temporaryVolume); 206 SetSwapVolume(temporaryVolume); 207 SetSwapSize(0); 195 208 } 196 209 197 210 … … 205 218 206 219 207 220 bool 208 Settings::Is Defaultable()221 Settings::IsRevertible() 209 222 { 210 223 return fSwapEnabled != fInitialSwapEnabled 211 || fSwapSize != fInitialSwapSize;212 }213 214 215 bool216 Settings::SwapChanged()217 {218 return fSwapEnabled != fInitialSwapEnabled219 224 || fSwapSize != fInitialSwapSize 220 225 || fSwapVolume.Device() != fInitialSwapVolume; 221 226 } 222 -
src/preferences/virtualmemory/Settings.h
25 25 void SetSwapSize(off_t size); 26 26 void SetSwapVolume(BVolume& volume); 27 27 28 void SetSwapDefaults();29 28 void RevertSwapChanges(); 30 bool IsDefaultable(); 31 bool SwapChanged(); 29 bool IsRevertible(); 32 30 33 31 private: 32 void SetSwapNull(); 34 33 void ReadWindowSettings(); 35 34 void WriteWindowSettings(); 36 35 … … 47 46 off_t fInitialSwapSize; 48 47 dev_t fInitialSwapVolume; 49 48 50 bool fPositionUpdated, fSwapUpdated; 49 bool fPositionUpdated; 50 const char* fBadVolName; 51 51 }; 52 52 53 53 #endif /* SETTINGS_H */ -
src/preferences/virtualmemory/SettingsWindow.cpp
1 1 /* 2 * Copyright 2005-2009, Axel Dörfler, axeld@pinc-software.de. All rights reserved. 3 * Distributed under the terms of the MIT License. 2 * Copyright 2005-2009, Axel Dörfler, axeld@pinc-software.de 3 * Copyright 2010-2011, Hamish Morrison, hamish@lavabit.com 4 * All rights reserved. Distributed under the terms of the MIT License. 4 5 */ 5 6 6 7 … … 39 40 static const uint32 kMsgRevert = 'rvrt'; 40 41 static const uint32 kMsgSliderUpdate = 'slup'; 41 42 static const uint32 kMsgSwapEnabledUpdate = 'swen'; 43 static const uint32 kMsgVolumeSelected = 'vlsl'; 44 static const int64 kMegaByte = 1048576; 42 45 43 46 44 47 class SizeSlider : public BSlider { … … 54 57 }; 55 58 56 59 57 static const int64 kMegaByte = 1048576; 60 SizeSlider::SizeSlider(const char* name, const char* label, 61 BMessage* message, int32 min, int32 max, uint32 flags) 62 : BSlider(name, label, message, min, max, B_HORIZONTAL, B_BLOCK_THUMB, flags) 63 { 64 rgb_color color = ui_color(B_CONTROL_HIGHLIGHT_COLOR); 65 UseFillColor(true, &color); 66 } 58 67 59 68 60 const char * 69 SizeSlider::~SizeSlider() 70 { 71 } 72 73 74 const char* 61 75 byte_string(int64 size) 62 76 { 63 77 double value = 1. * size; … … 80 94 } while (value >= 1024 && units[i + 1]); 81 95 82 96 off_t rounded = off_t(value * 100LL); 83 s printf(string, "%g %s", rounded / 100.0,97 snprintf(string, sizeof(string), "%g %s", rounded / 100.0, 84 98 B_TRANSLATE_NOCOLLECT(units[i])); 85 99 } 86 100 … … 88 102 } 89 103 90 104 91 // #pragma mark - 92 93 94 SizeSlider::SizeSlider(const char* name, const char* label, 95 BMessage* message, int32 min, int32 max, uint32 flags) 96 : BSlider(name, label, message, min, max, B_HORIZONTAL, B_BLOCK_THUMB, flags) 105 const char* 106 SizeSlider::UpdateText() const 97 107 { 98 rgb_color color = ui_color(B_CONTROL_HIGHLIGHT_COLOR);99 UseFillColor(true, &color);108 fText = byte_string(Value() * kMegaByte); 109 return fText.String(); 100 110 } 101 111 102 112 103 SizeSlider::~SizeSlider() 113 class VolumeMenuItem : public BMenuItem { 114 public: 115 VolumeMenuItem(const char* label, BMessage* message, BVolume* volume); 116 virtual ~VolumeMenuItem(); 117 BVolume* fVolume; 118 }; 119 120 121 VolumeMenuItem::VolumeMenuItem(const char* label, BMessage* message, 122 BVolume* volume) 123 : BMenuItem(label, message) 104 124 { 125 fVolume = volume; 105 126 } 106 127 107 128 108 const char * 109 SizeSlider::UpdateText() const 129 VolumeMenuItem::~VolumeMenuItem() 110 130 { 111 fText = byte_string(Value() * kMegaByte);112 113 return fText.String();114 131 } 115 132 116 133 117 // #pragma mark -118 119 120 134 SettingsWindow::SettingsWindow() 121 : BWindow(BRect(0, 0, 269, 172), B_TRANSLATE("VirtualMemory"), 135 : 136 BWindow(BRect(0, 0, 269, 172), B_TRANSLATE("VirtualMemory"), 122 137 B_TITLED_WINDOW, B_NOT_RESIZABLE | B_ASYNCHRONOUS_CONTROLS 123 | B_NOT_ZOOMABLE | B_AUTO_UPDATE_SIZE_LIMITS) 138 | B_NOT_ZOOMABLE | B_AUTO_UPDATE_SIZE_LIMITS), 139 fLocked(false) 140 124 141 { 125 142 BView* view = new BGroupView(); 126 143 … … 142 159 string << byte_string(fSettings.SwapSize()); 143 160 BStringView* swapfileView = new BStringView("current swap size", string.String()); 144 161 145 BPopUpMenu* menu = new BPopUpMenu(" volumes");162 BPopUpMenu* menu = new BPopUpMenu("invalid"); 146 163 147 164 // collect volumes 148 165 // TODO: listen to volume changes! 149 166 // TODO: accept dropped volumes 150 167 151 168 BVolumeRoster volumeRoster; 152 BVolume volume;153 while (volumeRoster.GetNextVolume(&volume) == B_OK) {154 char name[B_FILE_NAME_LENGTH];155 if (!volume .IsPersistent() || volume.GetName(name) != B_OK || !name[0])169 BVolume* volume = new BVolume(); 170 char name[B_FILE_NAME_LENGTH]; 171 while (volumeRoster.GetNextVolume(volume) == B_OK) { 172 if (!volume->IsPersistent() || volume->GetName(name) != B_OK || !name[0]) 156 173 continue; 157 158 BMenuItem* item = new BMenuItem(name, NULL);174 VolumeMenuItem* item = new VolumeMenuItem(name, 175 new BMessage(kMsgVolumeSelected), volume); 159 176 menu->AddItem(item); 160 161 if (volume.Device() == fSettings.SwapVolume().Device()) 162 item->SetMarked(true); 177 volume = new BVolume(); 163 178 } 164 179 165 fVolumeMenuField = new BMenuField(" devices", B_TRANSLATE("Use volume:"), menu);180 fVolumeMenuField = new BMenuField("volumes", B_TRANSLATE("Use volume:"), menu); 166 181 167 // When swap volume changing support is implemeneted, remove me: 182 #ifndef SWAP_VOLUME_IMPLEMENTED 168 183 fVolumeMenuField->SetEnabled(false); 184 #endif 169 185 170 186 fSizeSlider = new SizeSlider("size slider", 171 187 B_TRANSLATE("Requested swap file size:"), new BMessage(kMsgSliderUpdate), 172 0, 0, B_WILL_DRAW | B_FRAME_EVENTS);188 1, 1, B_WILL_DRAW | B_FRAME_EVENTS); 173 189 fSizeSlider->SetViewColor(255, 0, 255); 174 190 175 191 fWarningStringView = new BStringView("", ""); … … 195 211 ); 196 212 box->AddChild(view); 197 213 198 // Add "Defaults" and "Revert" buttons199 200 214 fDefaultsButton = new BButton("defaults", B_TRANSLATE("Defaults"), 201 215 new BMessage(kMsgDefaults)); 202 fDefaultsButton->SetEnabled(fSettings.IsDefaultable());203 216 204 217 fRevertButton = new BButton("revert", B_TRANSLATE("Revert"), 205 218 new BMessage(kMsgRevert)); … … 216 229 .SetInsets(10, 10, 10, 10) 217 230 ); 218 231 219 _Update();220 221 232 BScreen screen; 222 233 BRect screenFrame = screen.Frame(); 223 224 234 if (!screenFrame.Contains(fSettings.WindowPosition())) 225 235 CenterOnScreen(); 226 236 else 227 237 MoveTo(fSettings.WindowPosition()); 238 239 #ifdef SWAP_VOLUME_IMPLEMENTED 240 // Validate the volume specified in settings file 241 status_t result = fSettings.SwapVolume().InitCheck(); 242 243 if (result == B_NO_INIT) { 244 int32 choice = (new BAlert("VirtualMemory", B_TRANSLATE( 245 "The device specified in the settings file is invalid.\n" 246 "You can keep the current setting or switch to the " 247 "default swap device."), 248 B_TRANSLATE("Keep"), B_TRANSLATE("Switch"), NULL, 249 B_WIDTH_AS_USUAL, B_WARNING_ALERT))->Go(); 250 if (choice == 1) { 251 BVolumeRoster volumeRoster; 252 BVolume bootVolume; 253 volumeRoster.GetBootVolume(&bootVolume); 254 fSettings.SetSwapVolume(bootVolume); 255 } 256 } 257 #endif 258 259 _Update(); 228 260 } 229 261 230 262 … … 238 270 { 239 271 if ((fSwapEnabledCheckBox->Value() != 0) != fSettings.SwapEnabled()) 240 272 fSwapEnabledCheckBox->SetValue(fSettings.SwapEnabled()); 241 242 if (fSizeSlider->IsEnabled() != fSettings.SwapEnabled()) 243 fSizeSlider->SetEnabled(fSettings.SwapEnabled()); 244 273 245 274 #ifdef SWAP_VOLUME_IMPLEMENTED 246 275 if (fVolumeMenuField->IsEnabled() != fSettings.SwapEnabled()) 247 276 fVolumeMenuField->SetEnabled(fSettings.SwapEnabled()); 277 VolumeMenuItem* selectedVolumeItem = 278 (VolumeMenuItem*)fVolumeMenuField->Menu()->FindMarked(); 279 if (selectedVolumeItem == NULL) { 280 VolumeMenuItem* currentVolumeItem; 281 int32 items = fVolumeMenuField->Menu()->CountItems(); 282 for (int32 index = 0; index < items; ++index) { 283 currentVolumeItem = ((VolumeMenuItem*)fVolumeMenuField->Menu()->ItemAt(index)); 284 if (*(currentVolumeItem->fVolume) == fSettings.SwapVolume()) { 285 currentVolumeItem->SetMarked(true); 286 break; 287 } 288 } 289 } else if (*selectedVolumeItem->fVolume != fSettings.SwapVolume()) { 290 VolumeMenuItem* currentVolumeItem; 291 int32 items = fVolumeMenuField->Menu()->CountItems(); 292 for (int32 index = 0; index < items; ++index) { 293 currentVolumeItem = ((VolumeMenuItem*)fVolumeMenuField->Menu()->ItemAt(index)); 294 if (*(currentVolumeItem->fVolume) == fSettings.SwapVolume()) { 295 currentVolumeItem->SetMarked(true); 296 break; 297 } 298 } 299 } 248 300 #endif 249 301 302 fWarningStringView->SetText(""); 303 fLocked = false; 304 305 if (fSettings.IsRevertible()) 306 fWarningStringView->SetText( 307 B_TRANSLATE("Changes will take effect on restart!")); 308 if (fRevertButton->IsEnabled() != fSettings.IsRevertible()) 309 fRevertButton->SetEnabled(fSettings.IsRevertible()); 310 250 311 off_t minSize, maxSize; 251 312 if (_GetSwapFileLimits(minSize, maxSize) == B_OK) { 313 // round to nearest MB -- slider steps in whole MBs 314 (minSize >>= 20) <<= 20; 315 (maxSize >>= 20) <<= 20; 252 316 BString minLabel, maxLabel; 253 317 minLabel << byte_string(minSize); 254 318 maxLabel << byte_string(maxSize); 255 319 if (minLabel != fSizeSlider->MinLimitLabel() 256 320 || maxLabel != fSizeSlider->MaxLimitLabel()) { 257 321 fSizeSlider->SetLimitLabels(minLabel.String(), maxLabel.String()); 258 #ifdef __HAIKU__259 322 fSizeSlider->SetLimits(minSize / kMegaByte, maxSize / kMegaByte); 260 #endif261 323 } 262 263 if (fSizeSlider->Value() != fSettings.SwapSize() / kMegaByte) 264 fSizeSlider->SetValue(fSettings.SwapSize() / kMegaByte); 265 } else { 266 // Not enough space on volume for a swap file. Make UI inoperable. 324 } else if (fSettings.SwapEnabled()) { 267 325 fWarningStringView->SetText( 268 326 B_TRANSLATE("Insufficient space for a swap file.")); 269 fSwapEnabledCheckBox->SetEnabled(false); 270 fSizeSlider->SetEnabled(false); 271 // When swap volume is implemented, we'll want to keep the volume 272 // menu field enabled so the user can get around the space issue 273 // by selecting a different volume. 274 #ifdef SWAP_VOLUME_IMPLEMENTED 275 fVolumeMenuField->SetEnabled(true); 276 #endif 327 fLocked = true; 277 328 } 278 279 // ToDo: set volume 280 281 fDefaultsButton->SetEnabled(fSettings.IsDefaultable()); 282 283 bool changed = fSettings.SwapChanged(); 284 if (fRevertButton->IsEnabled() != changed) { 285 fRevertButton->SetEnabled(changed); 286 if (changed) 287 fWarningStringView->SetText( 288 B_TRANSLATE("Changes will take effect on restart!")); 289 else 290 fWarningStringView->SetText(""); 329 if (fSizeSlider->Value() != fSettings.SwapSize() / kMegaByte) 330 fSizeSlider->SetValue(fSettings.SwapSize() / kMegaByte); 331 if (fSizeSlider->IsEnabled() != fSettings.SwapEnabled() || fLocked) 332 { 333 fSizeSlider->SetEnabled(fSettings.SwapEnabled() && !fLocked); 334 fSettings.SetSwapSize((off_t)fSizeSlider->Value() * kMegaByte); 291 335 } 292 336 } 293 337 … … 308 352 // adjust the free space accordingly 309 353 BPath path; 310 354 if (find_directory(B_COMMON_VAR_DIRECTORY, &path, false, 311 355 &fSettings.SwapVolume()) == B_OK) { 312 356 path.Append("swap"); 313 357 BEntry swap(path.Path()); 314 358 … … 333 377 334 378 335 379 void 380 SettingsWindow::SetSwapDefaults() 381 { 382 fSettings.SetSwapEnabled(true); 383 384 BVolumeRoster volumeRoster; 385 BVolume temporaryVolume; 386 volumeRoster.GetBootVolume(&temporaryVolume); 387 fSettings.SetSwapVolume(temporaryVolume); 388 389 system_info info; 390 get_system_info(&info); 391 392 off_t defaultSize = (off_t)info.max_pages * B_PAGE_SIZE; 393 off_t minSize, maxSize; 394 _GetSwapFileLimits(minSize, maxSize); 395 396 if (defaultSize > maxSize / 2) 397 defaultSize = maxSize / 2; 398 399 fSettings.SetSwapSize(defaultSize); 400 } 401 402 403 void 336 404 SettingsWindow::MessageReceived(BMessage* message) 337 405 { 338 406 switch (message->what) { … … 341 409 _Update(); 342 410 break; 343 411 case kMsgDefaults: 344 fSettings.SetSwapDefaults();412 SetSwapDefaults(); 345 413 _Update(); 346 414 break; 347 415 case kMsgSliderUpdate: 348 416 fSettings.SetSwapSize((off_t)fSizeSlider->Value() * kMegaByte); 349 417 _Update(); 350 418 break; 419 case kMsgVolumeSelected: 420 fSettings.SetSwapVolume(*((VolumeMenuItem*)fVolumeMenuField->Menu() 421 ->FindMarked())->fVolume); 422 _Update(); 423 break; 351 424 case kMsgSwapEnabledUpdate: 352 425 { 353 426 int32 value; … … 374 447 } 375 448 } 376 449 377 bool enabled = value != 0; 378 fSettings.SetSwapEnabled(enabled); 379 if (enabled && fSettings.SwapSize() == 0) { 380 off_t min; 381 off_t max; 382 _GetSwapFileLimits(min, max); 383 fSettings.SetSwapSize(min); 384 } 450 fSettings.SetSwapEnabled(value != 0); 385 451 _Update(); 386 452 break; 387 453 } -
src/preferences/virtualmemory/SettingsWindow.h
27 27 private: 28 28 void _Update(); 29 29 status_t _GetSwapFileLimits(off_t& minSize, off_t& maxSize); 30 void SetSwapDefaults(); 30 31 31 32 BCheckBox* fSwapEnabledCheckBox; 32 33 BSlider* fSizeSlider; … … 35 36 BStringView* fWarningStringView; 36 37 BMenuField* fVolumeMenuField; 37 38 Settings fSettings; 39 40 bool fLocked; 38 41 }; 39 42 40 43 #endif /* SETTINGS_WINDOW_H */