Ticket #3723: vm_preflet_17082011.patch
File vm_preflet_17082011.patch, 36.9 KB (added by , 13 years ago) |
---|
-
src/preferences/virtualmemory/VirtualMemory.cpp
8 8 #include "SettingsWindow.h" 9 9 10 10 #include <Alert.h> 11 #include <Catalog.h> 11 12 #include <TextView.h> 12 13 13 14 -
src/preferences/virtualmemory/Settings.cpp
7 7 8 8 #include "Settings.h" 9 9 10 #include <stdio.h> 11 #include <stdlib.h> 12 10 13 #include <File.h> 11 #include <Entry.h>12 14 #include <FindDirectory.h> 13 15 #include <Path.h> 14 #include <Volume.h>15 16 #include <VolumeRoster.h> 17 16 18 #include <driver_settings.h> 17 19 18 #include <stdio.h>19 #include <stdlib.h>20 #include <string.h>21 20 21 static const char* const kWindowSettingsFile = "VM_data"; 22 static const char* const kVirtualMemorySettings = "virtual_memory"; 23 static const off_t kMegaByte = 1024 * 1024; 22 24 23 static const char* kWindowSettingsFile = "VM_data";24 static const char* kVirtualMemorySettings = "virtual_memory";25 static const int64 kMegaByte = 1024 * 1024;26 25 27 28 26 Settings::Settings() 29 :30 fPositionUpdated(false)31 27 { 32 _ReadWindowSettings(); 33 _ReadSwapSettings(); 34 } 28 fDefaultSettings.enabled = true; 35 29 36 37 Settings::~Settings() 38 { 39 _WriteWindowSettings(); 40 _WriteSwapSettings(); 30 system_info sysInfo; 31 get_system_info(&sysInfo); 32 fDefaultSettings.size = (off_t)sysInfo.max_pages * B_PAGE_SIZE * 2; 33 fDefaultSettings.volume = dev_for_path("/boot"); 41 34 } 42 35 43 36 44 37 void 45 Settings::Set WindowPosition(BPoint position)38 Settings::SetSwapEnabled(bool enabled, bool revertable) 46 39 { 47 if (position == fWindowPosition) 48 return; 49 50 fWindowPosition = position; 51 fPositionUpdated = true; 40 fCurrentSettings.enabled = enabled; 41 if (!revertable) 42 fInitialSettings.enabled = enabled; 52 43 } 53 44 54 45 55 46 void 56 Settings::SetSwap Enabled(bool enabled)47 Settings::SetSwapSize(off_t size, bool revertable) 57 48 { 58 fSwapEnabled = enabled; 49 fCurrentSettings.size = size; 50 if (!revertable) 51 fInitialSettings.size = size; 59 52 } 60 53 61 54 62 55 void 63 Settings::SetSwap Size(off_t size)56 Settings::SetSwapVolume(dev_t volume, bool revertable) 64 57 { 65 fSwapSize = size; 66 } 58 fCurrentSettings.volume = volume; 59 if (!revertable) 60 fInitialSettings.volume = volume; 67 61 68 69 void70 Settings::SetSwapVolume(BVolume &volume)71 {72 if (volume.Device() == SwapVolume().Device()73 || volume.InitCheck() != B_OK)74 return;75 76 fSwapVolume.SetTo(volume.Device());77 62 } 78 63 79 64 80 65 void 81 Settings:: RevertSwapChanges()66 Settings::SetWindowPosition(BPoint position) 82 67 { 83 fSwapEnabled = fInitialSwapEnabled; 84 fSwapSize = fInitialSwapSize; 85 fSwapVolume.SetTo(fInitialSwapVolume); 68 fWindowPosition = position; 86 69 } 87 70 88 71 89 bool 90 Settings:: IsRevertible()72 status_t 73 Settings::ReadWindowSettings() 91 74 { 92 return fSwapEnabled != fInitialSwapEnabled 93 || fSwapSize != fInitialSwapSize 94 || fSwapVolume.Device() != fInitialSwapVolume; 95 } 75 BPath path; 76 if (find_directory(B_USER_SETTINGS_DIRECTORY, &path) != B_OK) 77 return B_ERROR; 96 78 79 path.Append(kWindowSettingsFile); 80 BFile file; 81 if (file.SetTo(path.Path(), B_READ_ONLY) != B_OK) 82 return B_ERROR; 97 83 98 void 99 Settings::_ReadWindowSettings() 100 { 101 bool success = false; 102 103 BPath path; 104 if (find_directory(B_USER_SETTINGS_DIRECTORY, &path) == B_OK) { 105 path.Append(kWindowSettingsFile); 106 BFile file; 107 if (file.SetTo(path.Path(), B_READ_ONLY) == B_OK) 108 if (file.Read(&fWindowPosition, sizeof(BPoint)) == sizeof(BPoint)) 109 success = true; 110 } 111 112 if (!success) 113 fWindowPosition.Set(-1, -1); 84 if (file.Read(&fWindowPosition, sizeof(BPoint)) == sizeof(BPoint)) 85 return B_OK; 86 else 87 return B_ERROR; 114 88 } 115 89 116 90 117 void 118 Settings:: _WriteWindowSettings()91 status_t 92 Settings::WriteWindowSettings() 119 93 { 120 if (!fPositionUpdated)121 return;122 123 94 BPath path; 124 95 if (find_directory(B_USER_SETTINGS_DIRECTORY, &path) < B_OK) 125 return ;96 return B_ERROR; 126 97 127 98 path.Append(kWindowSettingsFile); 128 99 129 100 BFile file; 130 if (file.SetTo(path.Path(), B_WRITE_ONLY | B_CREATE_FILE | B_ERASE_FILE) == B_OK) 131 file.Write(&fWindowPosition, sizeof(BPoint)); 101 if (file.SetTo(path.Path(), B_WRITE_ONLY | B_CREATE_FILE | B_ERASE_FILE) 102 != B_OK) 103 return B_ERROR; 104 105 file.Write(&fWindowPosition, sizeof(BPoint)); 106 return B_OK; 132 107 } 133 108 134 109 135 void 136 Settings:: _ReadSwapSettings()110 status_t 111 Settings::ReadSwapSettings() 137 112 { 138 113 void* settings = load_driver_settings(kVirtualMemorySettings); 139 if (settings != NULL) { 140 SetSwapEnabled(get_driver_boolean_parameter(settings, "vm", false, false)); 141 const char* swapSize = get_driver_parameter(settings, "swap_size", NULL, NULL); 142 SetSwapSize(swapSize ? atoll(swapSize) : 0); 143 144 #ifdef SWAP_VOLUME_IMPLEMENTED 145 // we need to hang onto this one 146 fBadVolName = strdup(get_driver_parameter(settings, "swap_volume", NULL, NULL)); 147 148 BVolumeRoster volumeRoster; 149 BVolume temporaryVolume; 150 151 if (fBadVolName != NULL) { 152 status_t result = volumeRoster.GetNextVolume(&temporaryVolume); 153 char volumeName[B_FILE_NAME_LENGTH]; 154 while (result != B_BAD_VALUE) { 155 temporaryVolume.GetName(volumeName); 156 if (strcmp(volumeName, fBadVolName) == 0 157 && temporaryVolume.IsPersistent() && volumeName[0]) { 158 SetSwapVolume(temporaryVolume); 159 break; 160 } 161 result = volumeRoster.GetNextVolume(&temporaryVolume); 114 if (settings == NULL) 115 return kErrorSettingsNotFound; 116 117 const char* enabled = get_driver_parameter(settings, 118 "vm", NULL, NULL); 119 const char* size = get_driver_parameter(settings, 120 "swap_size", NULL, NULL); 121 const char* volume = get_driver_parameter(settings, 122 "swap_volume_name", NULL, NULL); 123 const char* device = get_driver_parameter(settings, 124 "swap_volume_device", NULL, NULL); 125 const char* filesystem = get_driver_parameter(settings, 126 "swap_volume_filesystem", NULL, NULL); 127 const char* capacity = get_driver_parameter(settings, 128 "swap_volume_capacity", NULL, NULL); 129 130 if (enabled == NULL || size == NULL || device == NULL 131 || volume == NULL || capacity == NULL || filesystem == NULL) 132 return kErrorSettingsInvalid; 133 134 off_t volCapacity = atoll(capacity); 135 136 SetSwapEnabled(get_driver_boolean_parameter(settings, 137 "vm", false, false)); 138 SetSwapSize(atoll(size)); 139 unload_driver_settings(settings); 140 141 int32 bestScore = -1; 142 dev_t bestVol = -1; 143 144 BVolume vol; 145 fs_info volStat; 146 BVolumeRoster roster; 147 while (roster.GetNextVolume(&vol) == B_OK) { 148 if (!vol.IsPersistent() || vol.IsReadOnly() || vol.IsRemovable() 149 || vol.IsShared()) 150 continue; 151 if (fs_stat_dev(vol.Device(), &volStat) == 0) { 152 int32 score = 0; 153 if (strcmp(volume, volStat.volume_name) == 0) 154 score += 4; 155 if (strcmp(device, volStat.device_name) == 0) 156 score += 3; 157 if (volCapacity == volStat.total_blocks * volStat.block_size) 158 score += 2; 159 if (strcmp(filesystem, volStat.fsh_name) == 0) 160 score += 1; 161 if (score >= 4 && score > bestScore) { 162 bestVol = vol.Device(); 163 bestScore = score; 162 164 } 163 } else 164 volumeRoster.GetBootVolume(&fSwapVolume); 165 #endif 166 unload_driver_settings(settings); 167 } else 168 _SetSwapNull(); 165 } 166 } 169 167 170 #ifndef SWAP_VOLUME_IMPLEMENTED 171 BVolumeRoster volumeRoster; 172 volumeRoster.GetBootVolume(&fSwapVolume); 173 #endif 168 SetSwapVolume(bestVol); 169 fInitialSettings = fCurrentSettings; 174 170 175 fInitialSwapEnabled = fSwapEnabled; 176 fInitialSwapSize = fSwapSize; 177 fInitialSwapVolume = fSwapVolume.Device(); 171 if (bestVol < 0) 172 return kErrorVolumeNotFound; 173 else 174 return B_OK; 178 175 } 179 176 180 177 181 void 182 Settings::_WriteSwapSettings() 183 { 184 if (!IsRevertible()) 185 return; 186 178 status_t 179 Settings::WriteSwapSettings() 180 { 187 181 BPath path; 188 182 if (find_directory(B_USER_SETTINGS_DIRECTORY, &path) != B_OK) 189 return ;183 return B_ERROR; 190 184 191 185 path.Append("kernel/drivers"); 192 186 path.Append(kVirtualMemorySettings); … … 194 188 BFile file; 195 189 if (file.SetTo(path.Path(), B_WRITE_ONLY | B_CREATE_FILE | B_ERASE_FILE) 196 190 != B_OK) 197 return; 198 199 char buffer[256]; 200 #ifdef SWAP_VOLUME_IMPLEMENTED 201 char volumeName[B_FILE_NAME_LENGTH] = {0}; 202 if (SwapVolume().InitCheck() != B_NO_INIT) 203 SwapVolume().GetName(volumeName); 204 else if (fBadVolName) 205 strcpy(volumeName, fBadVolName); 206 snprintf(buffer, sizeof(buffer), "vm %s\nswap_size %Ld\nswap_volume %s\n", 207 SwapEnabled() ? "on" : "off", SwapSize(), 208 volumeName[0] ? volumeName : NULL); 209 #else 210 snprintf(buffer, sizeof(buffer), "vm %s\nswap_size %Ld\n", 211 fSwapEnabled ? "on" : "off", fSwapSize); 212 #endif 191 return B_ERROR; 213 192 193 fs_info info; 194 fs_stat_dev(SwapVolume(), &info); 195 196 char buffer[1024]; 197 snprintf(buffer, sizeof(buffer), "vm %s\nswap_size %lld\n" 198 "swap_volume_name %s\nswap_volume_device %s\n" 199 "swap_volume_filesystem %s\nswap_volume_capacity %lld\n", 200 SwapEnabled() ? "on" : "off", SwapSize(), 201 info.volume_name, info.device_name, info.fsh_name, 202 info.total_blocks * info.block_size); 203 214 204 file.Write(buffer, strlen(buffer)); 205 return B_OK; 215 206 } 216 207 217 208 209 bool 210 Settings::IsRevertable() 211 { 212 return SwapEnabled() != fInitialSettings.enabled 213 || SwapSize() != fInitialSettings.size 214 || SwapVolume() != fInitialSettings.volume; 215 } 216 217 218 218 void 219 Settings:: _SetSwapNull()219 Settings::RevertSwapSettings() 220 220 { 221 SetSwapEnabled(false); 222 BVolumeRoster volumeRoster; 223 BVolume temporaryVolume; 224 volumeRoster.GetBootVolume(&temporaryVolume); 225 SetSwapVolume(temporaryVolume); 226 SetSwapSize(0); 221 SetSwapEnabled(fInitialSettings.enabled); 222 SetSwapSize(fInitialSettings.size); 223 SetSwapVolume(fInitialSettings.volume); 227 224 } 228 225 229 226 227 bool 228 Settings::IsDefaultable() 229 { 230 return SwapEnabled() != fDefaultSettings.enabled 231 || SwapSize() != fDefaultSettings.size 232 || SwapVolume() != fDefaultSettings.volume; 233 } 234 235 236 void 237 Settings::DefaultSwapSettings(bool revertable) 238 { 239 SetSwapEnabled(fDefaultSettings.enabled); 240 SetSwapSize(fDefaultSettings.size); 241 SetSwapVolume(fDefaultSettings.volume); 242 if (!revertable) 243 fInitialSettings = fDefaultSettings; 244 } -
src/preferences/virtualmemory/VirtualMemory.h
7 7 8 8 9 9 #include <Application.h> 10 #include <Catalog.h>11 #include <Locale.h>12 10 13 class VMSettings;14 11 15 16 12 class VirtualMemory : public BApplication { 17 18 VirtualMemory();19 virtual~VirtualMemory();13 public: 14 VirtualMemory(); 15 virtual ~VirtualMemory(); 20 16 21 virtual void ReadyToRun(); 22 virtual void AboutRequested(); 23 24 private: 25 void GetCurrentSettings(bool& enabled, off_t& size); 26 27 VMSettings *fSettings; 17 virtual void ReadyToRun(); 18 virtual void AboutRequested(); 28 19 }; 29 20 30 21 #endif /* VIRTUAL_MEMORY_H */ -
src/preferences/virtualmemory/Settings.h
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 2011, Hamish Morrison, hamish@lavabit.com 3 * Copyright 2005, Axel Dörfler, axeld@pinc-software.de 4 * All rights reserved. Distributed under the terms of the MIT License. 4 5 */ 5 6 #ifndef SETTINGS_H 6 7 #define SETTINGS_H 7 8 8 9 9 10 #include <Point.h> 10 #include <Volume.h>11 11 12 12 13 class Settings { 14 public : 15 Settings(); 16 virtual ~Settings(); 13 static const int32 kErrorSettingsNotFound = B_ERRORS_END + 1; 14 static const int32 kErrorSettingsInvalid = B_ERRORS_END + 2; 15 static const int32 kErrorVolumeNotFound = B_ERRORS_END + 3; 17 16 18 BPoint WindowPosition() const { return fWindowPosition; }19 void SetWindowPosition(BPoint position);20 17 21 bool SwapEnabled() const { return fSwapEnabled; }22 off_t SwapSize() const { return fSwapSize; }23 BVolume& SwapVolume() { return fSwapVolume; }24 void SetSwapEnabled(bool enabled);25 void SetSwapSize(off_t size);26 void SetSwapVolume(BVolume& volume);27 18 28 void RevertSwapChanges(); 29 bool IsRevertible(); 19 class Settings { 20 public: 21 Settings(); 30 22 31 private: 32 void _ReadWindowSettings(); 33 void _WriteWindowSettings(); 23 bool SwapEnabled() const 24 { return fCurrentSettings.enabled; } 25 off_t SwapSize() const { return fCurrentSettings.size; } 26 dev_t SwapVolume() { return fCurrentSettings.volume; } 27 BPoint WindowPosition() const { return fWindowPosition; } 34 28 35 void _ReadSwapSettings(); 36 void _WriteSwapSettings(); 29 void SetSwapEnabled(bool enabled, 30 bool revertable = true); 31 void SetSwapSize(off_t size, bool revertable = true); 32 void SetSwapVolume(dev_t volume, 33 bool revertable = true); 34 void SetWindowPosition(BPoint position); 37 35 38 void _SetSwapNull(); 36 status_t ReadWindowSettings(); 37 status_t WriteWindowSettings(); 38 status_t ReadSwapSettings(); 39 status_t WriteSwapSettings(); 39 40 40 BPoint fWindowPosition; 41 bool IsRevertable(); 42 void RevertSwapSettings(); 41 43 42 bool fSwapEnabled; 43 off_t fSwapSize; 44 BVolume fSwapVolume; 44 bool IsDefaultable(); 45 void DefaultSwapSettings(bool revertable = true); 46 private: 47 struct SwapSettings { 48 bool enabled; 49 off_t size; 50 dev_t volume; 51 }; 45 52 46 bool fInitialSwapEnabled; 47 off_t fInitialSwapSize; 48 dev_t fInitialSwapVolume; 53 BPoint fWindowPosition; 49 54 50 bool fPositionUpdated; 51 const char* fBadVolName; 55 SwapSettings fCurrentSettings; 56 SwapSettings fInitialSettings; 57 SwapSettings fDefaultSettings; 52 58 }; 53 59 54 60 #endif /* SETTINGS_H */ -
src/preferences/virtualmemory/Jamfile
1 1 SubDir HAIKU_TOP src preferences virtualmemory ; 2 2 3 Preference VirtualMemory : 3 UsePrivateHeaders shared system ; 4 5 Preference VirtualMemory : 4 6 VirtualMemory.cpp 5 7 SettingsWindow.cpp 6 8 Settings.cpp 7 9 $(DRIVER_SETTINGS) 8 10 9 : be $(TARGET_LIBSTDC++) $(HAIKU_LOCALE_LIBS)11 : be libshared.a $(TARGET_LIBSTDC++) $(HAIKU_LOCALE_LIBS) 10 12 : VirtualMemory.rdef 11 13 ; 12 14 13 15 if ! $(TARGET_PLATFORM_HAIKU_COMPATIBLE) { 14 SEARCH on [ FGristFiles driver_settings.c ] += 16 SEARCH on [ FGristFiles driver_settings.c ] += 15 17 [ FDirName $(HAIKU_TOP) src system libroot os ] ; 16 18 } 17 19 18 DoCatalogs VirtualMemory : 19 x-vnd.Haiku-VirtualMemory 20 : 21 VirtualMemory.cpp 22 SettingsWindow.cpp 23 ; 20 DoCatalogs VirtualMemory : 21 x-vnd.Haiku-VirtualMemory 22 : 23 VirtualMemory.cpp 24 SettingsWindow.cpp 25 ; -
src/preferences/virtualmemory/SettingsWindow.cpp
1 1 /* 2 * Copyright 2010-2011, Hamish Morrison, hamish@lavabit.com 2 * Copyright 2010-2011, Hamish Morrison, hamish@lavabit.com 3 3 * Copyright 2005-2009, Axel Dörfler, axeld@pinc-software.de 4 4 * All rights reserved. Distributed under the terms of the MIT License. 5 5 */ 6 6 7 7 8 8 #include "SettingsWindow.h" 9 #include "Settings.h"10 9 11 #include <Application.h>12 10 #include <Alert.h> 13 11 #include <Box.h> 14 12 #include <Button.h> 15 13 #include <Catalog.h> 16 14 #include <CheckBox.h> 17 #include <GroupLayout.h> 18 #include <GroupLayoutBuilder.h> 19 #include <Locale.h> 15 #include <Directory.h> 16 #include <FindDirectory.h> 17 #include <LayoutBuilder.h> 18 #include <MenuField.h> 19 #include <NodeMonitor.h> 20 #include <PopUpMenu.h> 21 #include <Path.h> 20 22 #include <StringView.h> 21 23 #include <String.h> 22 24 #include <Slider.h> 23 #include <PopUpMenu.h>24 #include <MenuItem.h>25 #include <MenuField.h>26 #include <Screen.h>27 #include <FindDirectory.h>28 #include <Path.h>29 #include <Volume.h>30 25 #include <VolumeRoster.h> 31 26 32 #include <stdio.h> 27 #include <StringForSize.h> 28 #include <system_info.h> 33 29 30 #include "Settings.h" 31 32 34 33 #undef B_TRANSLATE_CONTEXT 35 34 #define B_TRANSLATE_CONTEXT "SettingsWindow" 36 35 … … 40 39 static const uint32 kMsgSliderUpdate = 'slup'; 41 40 static const uint32 kMsgSwapEnabledUpdate = 'swen'; 42 41 static const uint32 kMsgVolumeSelected = 'vlsl'; 43 static const int64 kMegaByte = 1024 * 1024; 42 static const off_t kMegaByte = 1024 * 1024; 43 static dev_t bootDev = -1; 44 44 45 45 46 class SizeSlider : public BSlider {47 public:48 SizeSlider(const char* name, const char* label,49 BMessage* message, int32 min, int32 max, uint32 flags);50 virtual ~SizeSlider();51 52 virtual const char* UpdateText() const;53 54 private:55 mutable BString fText;56 };57 58 59 46 SizeSlider::SizeSlider(const char* name, const char* label, 60 47 BMessage* message, int32 min, int32 max, uint32 flags) 61 : BSlider(name, label, message, min, max, B_HORIZONTAL, B_BLOCK_THUMB, flags) 48 : 49 BSlider(name, label, message, min, max, B_HORIZONTAL, 50 B_BLOCK_THUMB, flags) 62 51 { 63 52 rgb_color color = ui_color(B_CONTROL_HIGHLIGHT_COLOR); 64 53 UseFillColor(true, &color); 65 54 } 66 55 67 56 68 SizeSlider::~SizeSlider() 57 const char* 58 SizeSlider::UpdateText() const 69 59 { 60 return string_for_size(Value() * kMegaByte, fText, sizeof(fText)); 70 61 } 71 62 72 63 73 const char* 74 byte_string(int64 size) 64 VolumeMenuItem::VolumeMenuItem(BVolume volume, BMessage* message) 65 : 66 BMenuItem("", message), 67 fVolume(volume) 75 68 { 76 double value = 1. * size;77 static char string[256]; 69 GenerateLabel(); 70 } 78 71 79 if (value < 1024)80 snprintf(string, sizeof(string), B_TRANSLATE("%Ld B"), size);81 else {82 static const char *units[] = {83 B_TRANSLATE_MARK("KB"),84 B_TRANSLATE_MARK("MB"),85 B_TRANSLATE_MARK("GB"),86 NULL87 };88 int32 i = -1;89 72 90 do { 91 value /= 1024.0; 92 i++; 93 } while (value >= 1024 && units[i + 1]);94 95 off_t rounded = off_t(value * 100LL);96 snprintf(string, sizeof(string), "%g %s", rounded / 100.0,97 B_TRANSLATE_NOCOLLECT(units[i]));73 void 74 VolumeMenuItem::MessageReceived(BMessage* message) 75 { 76 if (message->what == B_NODE_MONITOR) { 77 int32 code; 78 if (message->FindInt32("opcode", &code) == B_OK) 79 if (code == B_ENTRY_MOVED) 80 GenerateLabel(); 98 81 } 99 100 return string;101 82 } 102 83 103 84 104 const char* 105 SizeSlider::UpdateText() const 85 void 86 VolumeMenuItem::GenerateLabel() 106 87 { 107 fText = byte_string(Value() * kMegaByte); 108 return fText.String(); 109 } 88 char name[B_FILE_NAME_LENGTH + 1]; 89 fVolume.GetName(name); 110 90 91 BDirectory dir; 92 if (fVolume.GetRootDirectory(&dir) == B_OK) { 93 BEntry entry; 94 if (dir.GetEntry(&entry) == B_OK) { 95 BPath path; 96 if (entry.GetPath(&path) == B_OK) { 97 BString label; 98 label << name << " (" << path.Path() << ")"; 99 SetLabel(label); 100 return; 101 } 102 } 103 } 111 104 112 class VolumeMenuItem : public BMenuItem { 113 public: 114 VolumeMenuItem(const char* label, BMessage* message, BVolume* volume); 115 BVolume* Volume() { return fVolume; } 116 117 private: 118 BVolume* fVolume; 119 }; 120 121 122 VolumeMenuItem::VolumeMenuItem(const char* label, BMessage* message, 123 BVolume* volume) 124 : BMenuItem(label, message) 125 { 126 fVolume = volume; 105 SetLabel(name); 127 106 } 128 107 129 130 108 SettingsWindow::SettingsWindow() 131 109 : 132 110 BWindow(BRect(0, 0, 269, 172), B_TRANSLATE_SYSTEM_NAME("VirtualMemory"), 133 111 B_TITLED_WINDOW, B_NOT_RESIZABLE | B_ASYNCHRONOUS_CONTROLS 134 | B_NOT_ZOOMABLE | B_AUTO_UPDATE_SIZE_LIMITS), 135 fLocked(false) 136 112 | B_NOT_ZOOMABLE | B_AUTO_UPDATE_SIZE_LIMITS) 113 137 114 { 138 BView* view = new BGroupView(); 115 bootDev = dev_for_path("/boot"); 116 BAlignment align(B_ALIGN_LEFT, B_ALIGN_MIDDLE); 139 117 118 if (fSettings.ReadWindowSettings() == B_OK) 119 MoveTo(fSettings.WindowPosition()); 120 else 121 CenterOnScreen(); 122 123 status_t result = fSettings.ReadSwapSettings(); 124 if (result == kErrorSettingsNotFound) 125 fSettings.DefaultSwapSettings(false); 126 else if (result == kErrorSettingsInvalid) { 127 int32 choice = (new BAlert("VirtualMemory", 128 B_TRANSLATE("The settings specified in the settings file " 129 "are invalid. You can load the defaults or quit."), 130 B_TRANSLATE("Load defaults"), B_TRANSLATE("Quit")))->Go(); 131 if (choice == 1) { 132 be_app->PostMessage(B_QUIT_REQUESTED); 133 return; 134 } 135 fSettings.DefaultSwapSettings(false); 136 } else if (result == kErrorVolumeNotFound) { 137 int32 choice = (new BAlert("VirtualMemory", 138 B_TRANSLATE("The volume specified in the settings file " 139 "could not be found. You can use the boot volume or quit."), 140 B_TRANSLATE("Use boot volume"), B_TRANSLATE("Quit")))->Go(); 141 if (choice == 1) { 142 be_app->PostMessage(B_QUIT_REQUESTED); 143 return; 144 } 145 fSettings.SetSwapVolume(bootDev, false); 146 } 147 140 148 fSwapEnabledCheckBox = new BCheckBox("enable swap", 141 149 B_TRANSLATE("Enable virtual memory"), 142 150 new BMessage(kMsgSwapEnabledUpdate)); 151 fSwapEnabledCheckBox->SetExplicitAlignment(align); 143 152 144 BBox* box = new BBox("box", B_FOLLOW_LEFT_RIGHT); 145 box->SetLabel(fSwapEnabledCheckBox); 146 153 char sizeStr[16]; 147 154 system_info info; 148 155 get_system_info(&info); 149 150 156 BString string = B_TRANSLATE("Physical memory: "); 151 string << byte_string((off_t)info.max_pages * B_PAGE_SIZE); 152 BStringView* memoryView = new BStringView("physical memory", string.String()); 157 string << string_for_size(info.max_pages * B_PAGE_SIZE, sizeStr, 158 sizeof(sizeStr)); 159 BStringView* memoryView = new BStringView("physical memory", 160 string.String()); 161 memoryView->SetExplicitAlignment(align); 153 162 163 system_memory_info memInfo = {}; 164 __get_system_info_etc(B_MEMORY_INFO, &memInfo, sizeof(memInfo)); 154 165 string = B_TRANSLATE("Current swap file size: "); 155 string << byte_string(fSettings.SwapSize()); 156 BStringView* swapfileView = new BStringView("current swap size", string.String()); 166 string << string_for_size(memInfo.max_swap_space, sizeStr, 167 sizeof(sizeStr)); 168 BStringView* swapFileView = new BStringView("current swap size", 169 string.String()); 170 swapFileView->SetExplicitAlignment(align); 157 171 158 BPopUpMenu* menu = new BPopUpMenu("invalid"); 172 BPopUpMenu* menu = new BPopUpMenu("volume menu"); 173 fVolumeMenuField = new BMenuField("volume menu field", 174 B_TRANSLATE("Use volume:"), menu); 175 fVolumeMenuField->SetExplicitAlignment(align); 159 176 160 // collect volumes 161 // TODO: listen to volume changes! 162 // TODO: accept dropped volumes 163 164 BVolumeRoster volumeRoster; 165 BVolume* volume = new BVolume(); 166 char name[B_FILE_NAME_LENGTH]; 167 while (volumeRoster.GetNextVolume(volume) == B_OK) { 168 if (!volume->IsPersistent() || volume->GetName(name) != B_OK || !name[0]) 177 BVolumeRoster roster; 178 BVolume vol; 179 while (roster.GetNextVolume(&vol) == B_OK) { 180 if (!vol.IsPersistent() || vol.IsReadOnly() || vol.IsRemovable() 181 || vol.IsShared()) 169 182 continue; 170 VolumeMenuItem* item = new VolumeMenuItem(name, 171 new BMessage(kMsgVolumeSelected), volume); 172 menu->AddItem(item); 173 volume = new BVolume(); 183 _AddVolumeMenuItem(vol.Device()); 174 184 } 175 185 176 fVolumeMenuField = new BMenuField("volumes", B_TRANSLATE("Use volume:"), menu);177 178 fSizeSlider = new SizeSlider("size slider", 179 B_TRANSLATE("Requested swap file size:"), new BMessage(kMsgSliderUpdate),180 1, 1, B_WILL_DRAW | B_FRAME_EVENTS);186 watch_node(NULL, B_WATCH_MOUNT, this, this); 187 188 fSizeSlider = new SizeSlider("size slider", 189 B_TRANSLATE("Requested swap file size:"), 190 new BMessage(kMsgSliderUpdate), 0, 0, B_WILL_DRAW | B_FRAME_EVENTS); 181 191 fSizeSlider->SetViewColor(255, 0, 255); 192 fSizeSlider->SetExplicitAlignment(align); 182 193 183 fWarningStringView = new BStringView(" ", "");184 fWarningStringView->SetAlignment(B_ALIGN_CENTER);194 fWarningStringView = new BStringView("warning", 195 B_TRANSLATE("Changes will take effect upon reboot.")); 185 196 186 view->SetLayout(new BGroupLayout(B_HORIZONTAL)); 187 view->AddChild(BGroupLayoutBuilder(B_VERTICAL, 10) 188 .AddGroup(B_HORIZONTAL) 189 .Add(memoryView) 190 .AddGlue() 191 .End() 192 .AddGroup(B_HORIZONTAL) 193 .Add(swapfileView) 194 .AddGlue() 195 .End() 196 #ifdef SWAP_VOLUME_IMPLEMENTED 197 .AddGroup(B_HORIZONTAL) 198 .Add(fVolumeMenuField) 199 .AddGlue() 200 .End() 201 #else 202 .AddGlue() 203 #endif 197 BBox* box = new BBox("box"); 198 box->SetLabel(fSwapEnabledCheckBox); 199 200 box->AddChild(BLayoutBuilder::Group<>(B_VERTICAL, B_USE_DEFAULT_SPACING) 201 .Add(memoryView) 202 .Add(swapFileView) 203 .Add(fVolumeMenuField) 204 204 .Add(fSizeSlider) 205 205 .Add(fWarningStringView) 206 .SetInsets(10, 10, 10, 10) 207 ); 208 box->AddChild(view); 206 .SetInsets(10) 207 .View()); 209 208 210 209 fDefaultsButton = new BButton("defaults", B_TRANSLATE("Defaults"), 211 210 new BMessage(kMsgDefaults)); … … 214 213 new BMessage(kMsgRevert)); 215 214 fRevertButton->SetEnabled(false); 216 215 217 SetLayout(new BGroupLayout(B_HORIZONTAL)); 218 AddChild(BGroupLayoutBuilder(B_VERTICAL, 10) 216 BLayoutBuilder::Group<>(this, B_VERTICAL, B_USE_DEFAULT_SPACING) 219 217 .Add(box) 220 218 .AddGroup(B_HORIZONTAL, 10) 221 219 .Add(fDefaultsButton) 222 220 .Add(fRevertButton) 223 221 .AddGlue() 224 222 .End() 225 .SetInsets(10, 10, 10, 10) 226 ); 227 228 BScreen screen; 229 BRect screenFrame = screen.Frame(); 230 if (!screenFrame.Contains(fSettings.WindowPosition())) 231 CenterOnScreen(); 232 else 233 MoveTo(fSettings.WindowPosition()); 234 235 #ifdef SWAP_VOLUME_IMPLEMENTED 236 // Validate the volume specified in settings file 237 status_t result = fSettings.SwapVolume().InitCheck(); 238 239 if (result != B_OK) { 240 int32 choice = (new BAlert("VirtualMemory", B_TRANSLATE( 241 "The swap volume specified in the settings file is invalid.\n" 242 "You can keep the current setting or switch to the " 243 "default swap volume."), 244 B_TRANSLATE("Keep"), B_TRANSLATE("Switch"), NULL, 245 B_WIDTH_AS_USUAL, B_WARNING_ALERT))->Go(); 246 if (choice == 1) { 247 BVolumeRoster volumeRoster; 248 BVolume bootVolume; 249 volumeRoster.GetBootVolume(&bootVolume); 250 fSettings.SetSwapVolume(bootVolume); 251 } 252 } 253 #endif 254 223 .SetInsets(10); 255 224 _Update(); 256 225 } 257 226 258 227 259 SettingsWindow::~SettingsWindow()260 {261 }262 263 264 228 void 265 229 SettingsWindow::MessageReceived(BMessage* message) 266 230 { 267 231 switch (message->what) { 232 case B_NODE_MONITOR: 233 { 234 int32 opcode; 235 if (message->FindInt32("opcode", &opcode) != B_OK) 236 break; 237 dev_t device; 238 if (opcode == B_DEVICE_MOUNTED 239 && message->FindInt32("new device", &device) == B_OK) { 240 BVolume vol(device); 241 if (!vol.IsPersistent() || vol.IsReadOnly() 242 || vol.IsRemovable() || vol.IsShared()) 243 break; 244 _AddVolumeMenuItem(device); 245 } 246 else if (opcode == B_DEVICE_UNMOUNTED 247 && message->FindInt32("device", &device) == B_OK) 248 _RemoveVolumeMenuItem(device); 249 _Update(); 250 break; 251 } 268 252 case kMsgRevert: 269 fSettings.RevertSwap Changes();253 fSettings.RevertSwapSettings(); 270 254 _Update(); 271 255 break; 272 256 case kMsgDefaults: 273 _SetSwapDefaults();257 fSettings.DefaultSwapSettings(); 274 258 _Update(); 275 259 break; 276 260 case kMsgSliderUpdate: … … 278 262 _Update(); 279 263 break; 280 264 case kMsgVolumeSelected: 281 fSettings.SetSwapVolume( *((VolumeMenuItem*)fVolumeMenuField->Menu()282 -> FindMarked())->Volume());265 fSettings.SetSwapVolume(((VolumeMenuItem*)fVolumeMenuField 266 ->Menu()->FindMarked())->Volume().Device()); 283 267 _Update(); 284 268 break; 285 269 case kMsgSwapEnabledUpdate: 286 270 { 287 int32 value; 288 if (message->FindInt32("be:value", &value) != B_OK) 289 break; 290 291 if (value == 0) { 292 // print out warning, give the user the time to think about it :) 271 if (fSwapEnabledCheckBox->Value() == 0) { 272 // print out warning, give the user the 273 // time to think about it :) 293 274 // ToDo: maybe we want to remove this possibility in the GUI 294 275 // as Be did, but I thought a proper warning could be helpful 295 276 // (for those that want to change that anyway) … … 300 281 "Virtual memory does not affect system performance " 301 282 "until this point is reached.\n\n" 302 283 "Are you really sure you want to turn it off?"), 303 B_TRANSLATE("Turn off"), B_TRANSLATE("Keep enabled"), NULL,304 B_WIDTH_AS_USUAL, B_WARNING_ALERT))->Go();284 B_TRANSLATE("Turn off"), B_TRANSLATE("Keep enabled"), 285 NULL, B_WIDTH_AS_USUAL, B_WARNING_ALERT))->Go(); 305 286 if (choice == 1) { 306 287 fSwapEnabledCheckBox->SetValue(1); 307 288 break; 308 289 } 309 290 } 310 311 fSettings.SetSwapEnabled(value != 0); 291 fSettings.SetSwapEnabled(fSwapEnabledCheckBox->Value()); 312 292 _Update(); 313 293 break; 314 294 } … … 323 303 SettingsWindow::QuitRequested() 324 304 { 325 305 fSettings.SetWindowPosition(Frame().LeftTop()); 306 fSettings.WriteWindowSettings(); 307 fSettings.WriteSwapSettings(); 326 308 be_app->PostMessage(B_QUIT_REQUESTED); 327 309 return true; 328 310 } 329 311 330 312 331 void 332 SettingsWindow::_ Update()313 status_t 314 SettingsWindow::_AddVolumeMenuItem(dev_t device) 333 315 { 334 if ( (fSwapEnabledCheckBox->Value() != 0) != fSettings.SwapEnabled())335 fSwapEnabledCheckBox->SetValue(fSettings.SwapEnabled());316 if (_FindVolumeMenuItem(device) != NULL) 317 return B_ERROR; 336 318 337 #ifdef SWAP_VOLUME_IMPLEMENTED 338 if (fVolumeMenuField->IsEnabled() != fSettings.SwapEnabled()) 339 fVolumeMenuField->SetEnabled(fSettings.SwapEnabled()); 340 VolumeMenuItem* selectedVolumeItem = 341 (VolumeMenuItem*)fVolumeMenuField->Menu()->FindMarked(); 342 if (selectedVolumeItem == NULL) { 343 VolumeMenuItem* currentVolumeItem; 344 int32 items = fVolumeMenuField->Menu()->CountItems(); 345 for (int32 index = 0; index < items; ++index) { 346 currentVolumeItem = ((VolumeMenuItem*)fVolumeMenuField->Menu()->ItemAt(index)); 347 if (*(currentVolumeItem->fVolume) == fSettings.SwapVolume()) { 348 currentVolumeItem->SetMarked(true); 349 break; 350 } 351 } 352 } else if (*selectedVolumeItem->fVolume != fSettings.SwapVolume()) { 353 VolumeMenuItem* currentVolumeItem; 354 int32 items = fVolumeMenuField->Menu()->CountItems(); 355 for (int32 index = 0; index < items; ++index) { 356 currentVolumeItem = ((VolumeMenuItem*)fVolumeMenuField->Menu()->ItemAt(index)); 357 if (*(currentVolumeItem->fVolume) == fSettings.SwapVolume()) { 358 currentVolumeItem->SetMarked(true); 359 break; 360 } 361 } 362 } 363 #endif 319 VolumeMenuItem* item = new VolumeMenuItem(device, 320 new BMessage(kMsgVolumeSelected)); 364 321 365 fWarningStringView->SetText(""); 366 fLocked = false; 367 368 if (fSettings.IsRevertible()) 369 fWarningStringView->SetText( 370 B_TRANSLATE("Changes will take effect on restart!")); 371 if (fRevertButton->IsEnabled() != fSettings.IsRevertible()) 372 fRevertButton->SetEnabled(fSettings.IsRevertible()); 373 374 off_t minSize, maxSize; 375 if (_GetSwapFileLimits(minSize, maxSize) == B_OK) { 376 // round to nearest MB -- slider steps in whole MBs 377 (minSize >>= 20) <<= 20; 378 (maxSize >>= 20) <<= 20; 379 BString minLabel, maxLabel; 380 minLabel << byte_string(minSize); 381 maxLabel << byte_string(maxSize); 382 if (minLabel != fSizeSlider->MinLimitLabel() 383 || maxLabel != fSizeSlider->MaxLimitLabel()) { 384 fSizeSlider->SetLimitLabels(minLabel.String(), maxLabel.String()); 385 fSizeSlider->SetLimits(minSize / kMegaByte, maxSize / kMegaByte); 386 } 387 } else if (fSettings.SwapEnabled()) { 388 fWarningStringView->SetText( 389 B_TRANSLATE("Insufficient space for a swap file.")); 390 fLocked = true; 322 fs_info info; 323 if (fs_stat_dev(device, &info) == 0) { 324 node_ref node; 325 node.device = info.dev; 326 node.node = info.root; 327 AddHandler(item); 328 watch_node(&node, B_WATCH_NAME, item); 391 329 } 392 if (fSizeSlider->Value() != fSettings.SwapSize() / kMegaByte) 393 fSizeSlider->SetValue(fSettings.SwapSize() / kMegaByte); 394 if (fSizeSlider->IsEnabled() != fSettings.SwapEnabled() || fLocked) 395 { 396 fSizeSlider->SetEnabled(fSettings.SwapEnabled() && !fLocked); 397 fSettings.SetSwapSize((off_t)fSizeSlider->Value() * kMegaByte); 398 } 330 331 fVolumeMenuField->Menu()->AddItem(item); 332 return B_OK; 399 333 } 400 334 401 335 402 336 status_t 403 SettingsWindow::_ GetSwapFileLimits(off_t& minSize, off_t& maxSize)337 SettingsWindow::_RemoveVolumeMenuItem(dev_t device) 404 338 { 405 minSize = kMegaByte; 339 VolumeMenuItem* item = _FindVolumeMenuItem(device); 340 if (item != NULL) { 341 fVolumeMenuField->Menu()->RemoveItem(item); 342 delete item; 343 return B_OK; 344 } else 345 return B_ERROR; 346 } 406 347 407 // maximum size is the free space on the current volume408 // (minus some safety offset, depending on the disk size)409 off_t freeSpace = fSettings.SwapVolume().FreeBytes();410 off_t safetyFreeSpace = fSettings.SwapVolume().Capacity() / 100;411 if (safetyFreeSpace > 1024 * kMegaByte)412 safetyFreeSpace = 1024 * kMegaByte;413 348 414 // check if there already is a page file on this disk and 415 // adjust the free space accordingly 416 BPath path; 417 if (find_directory(B_COMMON_VAR_DIRECTORY, &path, false, 418 &fSettings.SwapVolume()) == B_OK) { 419 path.Append("swap"); 420 BEntry swap(path.Path()); 421 422 off_t size; 423 if (swap.GetSize(&size) == B_OK) { 424 // If swap file exists, forget about safety space; 425 // disk may have filled after creation of swap file. 426 safetyFreeSpace = 0; 427 freeSpace += size; 428 } 349 VolumeMenuItem* 350 SettingsWindow::_FindVolumeMenuItem(dev_t device) 351 { 352 VolumeMenuItem* item = NULL; 353 int32 count = fVolumeMenuField->Menu()->CountItems(); 354 for (int i = 0; i < count; i++) { 355 item = (VolumeMenuItem*)fVolumeMenuField->Menu()->ItemAt(i); 356 if (item->Volume().Device() == device) 357 return item; 429 358 } 430 359 431 maxSize = freeSpace - safetyFreeSpace; 432 if (maxSize < minSize) { 433 maxSize = 0; 434 minSize = 0; 435 return B_ERROR; 436 } 437 438 return B_OK; 360 return NULL; 439 361 } 440 362 441 363 442 364 void 443 SettingsWindow::_ SetSwapDefaults()365 SettingsWindow::_Update() 444 366 { 445 fS ettings.SetSwapEnabled(true);367 fSwapEnabledCheckBox->SetValue(fSettings.SwapEnabled()); 446 368 447 BVolumeRoster volumeRoster; 448 BVolume temporaryVolume; 449 volumeRoster.GetBootVolume(&temporaryVolume); 450 fSettings.SetSwapVolume(temporaryVolume); 369 VolumeMenuItem* item = _FindVolumeMenuItem(fSettings.SwapVolume()); 370 if (item != NULL) { 371 fSizeSlider->SetEnabled(true); 372 item->SetMarked(true); 373 BEntry swapFile; 374 if (bootDev == item->Volume().Device()) 375 swapFile.SetTo("/var/swap"); 376 else { 377 BDirectory root; 378 item->Volume().GetRootDirectory(&root); 379 swapFile.SetTo(&root, "swap"); 380 } 451 381 452 system_info info; 453 get_system_info(&info); 454 455 off_t defaultSize = (off_t)info.max_pages * B_PAGE_SIZE; 456 off_t minSize, maxSize; 457 _GetSwapFileLimits(minSize, maxSize); 458 459 if (defaultSize > maxSize / 2) 460 defaultSize = maxSize / 2; 461 462 fSettings.SetSwapSize(defaultSize); 463 } 382 off_t swapFileSize = 0; 383 swapFile.GetSize(&swapFileSize); 464 384 385 char sizeStr[16]; 386 387 off_t freeSpace = item->Volume().FreeBytes() + swapFileSize; 388 off_t safeSpace = freeSpace - (off_t)(0.15 * freeSpace); 389 (safeSpace >>= 20) <<= 20; 390 off_t minSize = B_PAGE_SIZE + kMegaByte; 391 (minSize >>= 20) <<= 20; 392 BString minLabel, maxLabel; 393 minLabel << string_for_size(minSize, sizeStr, sizeof(sizeStr)); 394 maxLabel << string_for_size(safeSpace, sizeStr, sizeof(sizeStr)); 395 396 fSizeSlider->SetLimitLabels(minLabel.String(), maxLabel.String()); 397 fSizeSlider->SetLimits(minSize / kMegaByte, safeSpace / kMegaByte); 398 fSizeSlider->SetValue(fSettings.SwapSize() / kMegaByte); 399 } else 400 fSizeSlider->SetEnabled(false); 401 402 bool revertable = fSettings.IsRevertable(); 403 if (revertable) 404 fWarningStringView->Show(); 405 else 406 fWarningStringView->Hide(); 407 fRevertButton->SetEnabled(revertable); 408 fDefaultsButton->SetEnabled(fSettings.IsDefaultable()); 409 } -
src/preferences/virtualmemory/SettingsWindow.h
1 1 /* 2 * Copyright 2005-2006, Axel Dörfler, axeld@pinc-software.de. All rights reserved. 3 * Distributed under the terms of the MIT License. 2 * Copyright 2011, Hamish Morrison, hamish@lavabit.com 3 * Copyright 2005-2006, Axel Dörfler, axeld@pinc-software.de 4 * All rights reserved. Distributed under the terms of the MIT License. 4 5 */ 5 6 #ifndef SETTINGS_WINDOW_H 6 7 #define SETTINGS_WINDOW_H 7 8 8 9 10 #include <MenuItem.h> 11 #include <Slider.h> 12 #include <Volume.h> 9 13 #include <Window.h> 10 14 11 15 #include "Settings.h" 12 16 17 13 18 class BStringView; 14 19 class BCheckBox; 15 20 class BSlider; 16 21 class BButton; 17 22 class BMenuField; 18 23 24 25 class SizeSlider : public BSlider { 26 public: 27 SizeSlider(const char* name, const char* label, 28 BMessage* message, int32 min, int32 max, 29 uint32 flags); 30 virtual ~SizeSlider() {}; 31 32 virtual const char* UpdateText() const; 33 34 private: 35 mutable char fText[128]; 36 }; 37 38 39 class VolumeMenuItem : public BMenuItem, public BHandler { 40 public: 41 VolumeMenuItem(BVolume volume, BMessage* message); 42 virtual ~VolumeMenuItem() {} 43 44 virtual BVolume Volume() { return fVolume; } 45 virtual void MessageReceived(BMessage* message); 46 virtual void GenerateLabel(); 47 48 private: 49 BVolume fVolume; 50 }; 51 52 19 53 class SettingsWindow : public BWindow { 20 21 SettingsWindow();22 virtual ~SettingsWindow();54 public: 55 SettingsWindow(); 56 virtual ~SettingsWindow() {}; 23 57 24 virtual bool QuitRequested();25 virtual void MessageReceived(BMessage* message);58 virtual void MessageReceived(BMessage* message); 59 virtual bool QuitRequested(); 26 60 27 28 void _Update();29 status_t _GetSwapFileLimits(off_t& minSize, off_t& maxSize);30 void _SetSwapDefaults();61 private: 62 status_t _AddVolumeMenuItem(dev_t device); 63 status_t _RemoveVolumeMenuItem(dev_t device); 64 VolumeMenuItem* _FindVolumeMenuItem(dev_t device); 31 65 32 BCheckBox* fSwapEnabledCheckBox;33 BSlider* fSizeSlider; 34 BButton* fDefaultsButton;35 BButton* fRevertButton;36 BStringView* fWarningStringView;37 BMenuField* fVolumeMenuField;38 Settings fSettings;39 40 bool fLocked;66 void _Update(); 67 68 BCheckBox* fSwapEnabledCheckBox; 69 BSlider* fSizeSlider; 70 BButton* fDefaultsButton; 71 BButton* fRevertButton; 72 BStringView* fWarningStringView; 73 BMenuField* fVolumeMenuField; 74 Settings fSettings; 41 75 }; 42 76 43 77 #endif /* SETTINGS_WINDOW_H */