VM Preflet: Add support for device selection
* Enables swap file to be placed on non-boot partition * Changes tied closely to recent kernel virtual memory change
This commit is contained in:
committed by
Alexander von Gluck IV
parent
5c69b8405b
commit
b8838e91d9
@@ -1,23 +1,25 @@
|
||||
SubDir HAIKU_TOP src preferences virtualmemory ;
|
||||
|
||||
Preference VirtualMemory :
|
||||
UsePrivateHeaders shared system ;
|
||||
|
||||
Preference VirtualMemory :
|
||||
VirtualMemory.cpp
|
||||
SettingsWindow.cpp
|
||||
Settings.cpp
|
||||
$(DRIVER_SETTINGS)
|
||||
|
||||
: be $(TARGET_LIBSTDC++) $(HAIKU_LOCALE_LIBS)
|
||||
: be libshared.a $(TARGET_LIBSTDC++) $(HAIKU_LOCALE_LIBS)
|
||||
: VirtualMemory.rdef
|
||||
;
|
||||
;
|
||||
|
||||
if ! $(TARGET_PLATFORM_HAIKU_COMPATIBLE) {
|
||||
SEARCH on [ FGristFiles driver_settings.c ] +=
|
||||
SEARCH on [ FGristFiles driver_settings.c ] +=
|
||||
[ FDirName $(HAIKU_TOP) src system libroot os ] ;
|
||||
}
|
||||
|
||||
DoCatalogs VirtualMemory :
|
||||
x-vnd.Haiku-VirtualMemory
|
||||
:
|
||||
VirtualMemory.cpp
|
||||
SettingsWindow.cpp
|
||||
;
|
||||
DoCatalogs VirtualMemory :
|
||||
x-vnd.Haiku-VirtualMemory
|
||||
:
|
||||
VirtualMemory.cpp
|
||||
SettingsWindow.cpp
|
||||
;
|
||||
|
||||
@@ -7,186 +7,179 @@
|
||||
|
||||
#include "Settings.h"
|
||||
|
||||
#include <File.h>
|
||||
#include <Entry.h>
|
||||
#include <FindDirectory.h>
|
||||
#include <Path.h>
|
||||
#include <Volume.h>
|
||||
#include <VolumeRoster.h>
|
||||
#include <driver_settings.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <File.h>
|
||||
#include <FindDirectory.h>
|
||||
#include <Path.h>
|
||||
#include <VolumeRoster.h>
|
||||
|
||||
static const char* kWindowSettingsFile = "VM_data";
|
||||
static const char* kVirtualMemorySettings = "virtual_memory";
|
||||
static const int64 kMegaByte = 1024 * 1024;
|
||||
#include <driver_settings.h>
|
||||
|
||||
|
||||
static const char* const kWindowSettingsFile = "VM_data";
|
||||
static const char* const kVirtualMemorySettings = "virtual_memory";
|
||||
static const off_t kMegaByte = 1024 * 1024;
|
||||
|
||||
|
||||
Settings::Settings()
|
||||
:
|
||||
fPositionUpdated(false)
|
||||
{
|
||||
_ReadWindowSettings();
|
||||
_ReadSwapSettings();
|
||||
fDefaultSettings.enabled = true;
|
||||
|
||||
system_info sysInfo;
|
||||
get_system_info(&sysInfo);
|
||||
fDefaultSettings.size = (off_t)sysInfo.max_pages * B_PAGE_SIZE * 2;
|
||||
fDefaultSettings.volume = dev_for_path("/boot");
|
||||
}
|
||||
|
||||
|
||||
Settings::~Settings()
|
||||
void
|
||||
Settings::SetSwapEnabled(bool enabled, bool revertable)
|
||||
{
|
||||
_WriteWindowSettings();
|
||||
_WriteSwapSettings();
|
||||
fCurrentSettings.enabled = enabled;
|
||||
if (!revertable)
|
||||
fInitialSettings.enabled = enabled;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Settings::SetSwapSize(off_t size, bool revertable)
|
||||
{
|
||||
fCurrentSettings.size = size;
|
||||
if (!revertable)
|
||||
fInitialSettings.size = size;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Settings::SetSwapVolume(dev_t volume, bool revertable)
|
||||
{
|
||||
fCurrentSettings.volume = volume;
|
||||
if (!revertable)
|
||||
fInitialSettings.volume = volume;
|
||||
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Settings::SetWindowPosition(BPoint position)
|
||||
{
|
||||
if (position == fWindowPosition)
|
||||
return;
|
||||
|
||||
fWindowPosition = position;
|
||||
fPositionUpdated = true;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Settings::SetSwapEnabled(bool enabled)
|
||||
status_t
|
||||
Settings::ReadWindowSettings()
|
||||
{
|
||||
fSwapEnabled = enabled;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Settings::SetSwapSize(off_t size)
|
||||
{
|
||||
fSwapSize = size;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Settings::SetSwapVolume(BVolume &volume)
|
||||
{
|
||||
if (volume.Device() == SwapVolume().Device()
|
||||
|| volume.InitCheck() != B_OK)
|
||||
return;
|
||||
|
||||
fSwapVolume.SetTo(volume.Device());
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Settings::RevertSwapChanges()
|
||||
{
|
||||
fSwapEnabled = fInitialSwapEnabled;
|
||||
fSwapSize = fInitialSwapSize;
|
||||
fSwapVolume.SetTo(fInitialSwapVolume);
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
Settings::IsRevertible()
|
||||
{
|
||||
return fSwapEnabled != fInitialSwapEnabled
|
||||
|| fSwapSize != fInitialSwapSize
|
||||
|| fSwapVolume.Device() != fInitialSwapVolume;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Settings::_ReadWindowSettings()
|
||||
{
|
||||
bool success = false;
|
||||
|
||||
BPath path;
|
||||
if (find_directory(B_USER_SETTINGS_DIRECTORY, &path) == B_OK) {
|
||||
path.Append(kWindowSettingsFile);
|
||||
BFile file;
|
||||
if (file.SetTo(path.Path(), B_READ_ONLY) == B_OK)
|
||||
if (file.Read(&fWindowPosition, sizeof(BPoint)) == sizeof(BPoint))
|
||||
success = true;
|
||||
}
|
||||
if (find_directory(B_USER_SETTINGS_DIRECTORY, &path) != B_OK)
|
||||
return B_ERROR;
|
||||
|
||||
if (!success)
|
||||
fWindowPosition.Set(-1, -1);
|
||||
path.Append(kWindowSettingsFile);
|
||||
BFile file;
|
||||
if (file.SetTo(path.Path(), B_READ_ONLY) != B_OK)
|
||||
return B_ERROR;
|
||||
|
||||
if (file.Read(&fWindowPosition, sizeof(BPoint)) == sizeof(BPoint))
|
||||
return B_OK;
|
||||
else
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Settings::_WriteWindowSettings()
|
||||
status_t
|
||||
Settings::WriteWindowSettings()
|
||||
{
|
||||
if (!fPositionUpdated)
|
||||
return;
|
||||
|
||||
BPath path;
|
||||
if (find_directory(B_USER_SETTINGS_DIRECTORY, &path) < B_OK)
|
||||
return;
|
||||
return B_ERROR;
|
||||
|
||||
path.Append(kWindowSettingsFile);
|
||||
|
||||
BFile file;
|
||||
if (file.SetTo(path.Path(), B_WRITE_ONLY | B_CREATE_FILE | B_ERASE_FILE) == B_OK)
|
||||
file.Write(&fWindowPosition, sizeof(BPoint));
|
||||
if (file.SetTo(path.Path(), B_WRITE_ONLY | B_CREATE_FILE | B_ERASE_FILE)
|
||||
!= B_OK)
|
||||
return B_ERROR;
|
||||
|
||||
file.Write(&fWindowPosition, sizeof(BPoint));
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Settings::_ReadSwapSettings()
|
||||
status_t
|
||||
Settings::ReadSwapSettings()
|
||||
{
|
||||
void* settings = load_driver_settings(kVirtualMemorySettings);
|
||||
if (settings != NULL) {
|
||||
SetSwapEnabled(get_driver_boolean_parameter(settings, "vm", false, false));
|
||||
const char* swapSize = get_driver_parameter(settings, "swap_size", NULL, NULL);
|
||||
SetSwapSize(swapSize ? atoll(swapSize) : 0);
|
||||
|
||||
#ifdef SWAP_VOLUME_IMPLEMENTED
|
||||
// we need to hang onto this one
|
||||
fBadVolName = strdup(get_driver_parameter(settings, "swap_volume", NULL, NULL));
|
||||
|
||||
BVolumeRoster volumeRoster;
|
||||
BVolume temporaryVolume;
|
||||
|
||||
if (fBadVolName != NULL) {
|
||||
status_t result = volumeRoster.GetNextVolume(&temporaryVolume);
|
||||
char volumeName[B_FILE_NAME_LENGTH];
|
||||
while (result != B_BAD_VALUE) {
|
||||
temporaryVolume.GetName(volumeName);
|
||||
if (strcmp(volumeName, fBadVolName) == 0
|
||||
&& temporaryVolume.IsPersistent() && volumeName[0]) {
|
||||
SetSwapVolume(temporaryVolume);
|
||||
break;
|
||||
}
|
||||
result = volumeRoster.GetNextVolume(&temporaryVolume);
|
||||
if (settings == NULL)
|
||||
return kErrorSettingsNotFound;
|
||||
|
||||
const char* enabled = get_driver_parameter(settings, "vm", NULL, NULL);
|
||||
const char* size = get_driver_parameter(settings, "swap_size", NULL, NULL);
|
||||
const char* volume = get_driver_parameter(settings, "swap_volume_name",
|
||||
NULL, NULL);
|
||||
const char* device = get_driver_parameter(settings,
|
||||
"swap_volume_device", NULL, NULL);
|
||||
const char* filesystem = get_driver_parameter(settings,
|
||||
"swap_volume_filesystem", NULL, NULL);
|
||||
const char* capacity = get_driver_parameter(settings,
|
||||
"swap_volume_capacity", NULL, NULL);
|
||||
|
||||
if (enabled == NULL || size == NULL || device == NULL || volume == NULL
|
||||
|| capacity == NULL || filesystem == NULL)
|
||||
return kErrorSettingsInvalid;
|
||||
|
||||
off_t volCapacity = atoll(capacity);
|
||||
|
||||
SetSwapEnabled(get_driver_boolean_parameter(settings,
|
||||
"vm", false, false));
|
||||
SetSwapSize(atoll(size));
|
||||
unload_driver_settings(settings);
|
||||
|
||||
int32 bestScore = -1;
|
||||
dev_t bestVol = -1;
|
||||
|
||||
BVolume vol;
|
||||
fs_info volStat;
|
||||
BVolumeRoster roster;
|
||||
while (roster.GetNextVolume(&vol) == B_OK) {
|
||||
if (!vol.IsPersistent() || vol.IsReadOnly() || vol.IsRemovable()
|
||||
|| vol.IsShared())
|
||||
continue;
|
||||
if (fs_stat_dev(vol.Device(), &volStat) == 0) {
|
||||
int32 score = 0;
|
||||
if (strcmp(volume, volStat.volume_name) == 0)
|
||||
score += 4;
|
||||
if (strcmp(device, volStat.device_name) == 0)
|
||||
score += 3;
|
||||
if (volCapacity == volStat.total_blocks * volStat.block_size)
|
||||
score += 2;
|
||||
if (strcmp(filesystem, volStat.fsh_name) == 0)
|
||||
score += 1;
|
||||
if (score >= 4 && score > bestScore) {
|
||||
bestVol = vol.Device();
|
||||
bestScore = score;
|
||||
}
|
||||
} else
|
||||
volumeRoster.GetBootVolume(&fSwapVolume);
|
||||
#endif
|
||||
unload_driver_settings(settings);
|
||||
} else
|
||||
_SetSwapNull();
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef SWAP_VOLUME_IMPLEMENTED
|
||||
BVolumeRoster volumeRoster;
|
||||
volumeRoster.GetBootVolume(&fSwapVolume);
|
||||
#endif
|
||||
SetSwapVolume(bestVol);
|
||||
fInitialSettings = fCurrentSettings;
|
||||
|
||||
fInitialSwapEnabled = fSwapEnabled;
|
||||
fInitialSwapSize = fSwapSize;
|
||||
fInitialSwapVolume = fSwapVolume.Device();
|
||||
if (bestVol < 0)
|
||||
return kErrorVolumeNotFound;
|
||||
else
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Settings::_WriteSwapSettings()
|
||||
{
|
||||
if (!IsRevertible())
|
||||
return;
|
||||
|
||||
status_t
|
||||
Settings::WriteSwapSettings()
|
||||
{
|
||||
BPath path;
|
||||
if (find_directory(B_USER_SETTINGS_DIRECTORY, &path) != B_OK)
|
||||
return;
|
||||
return B_ERROR;
|
||||
|
||||
path.Append("kernel/drivers");
|
||||
path.Append(kVirtualMemorySettings);
|
||||
@@ -194,36 +187,56 @@ Settings::_WriteSwapSettings()
|
||||
BFile file;
|
||||
if (file.SetTo(path.Path(), B_WRITE_ONLY | B_CREATE_FILE | B_ERASE_FILE)
|
||||
!= B_OK)
|
||||
return;
|
||||
|
||||
char buffer[256];
|
||||
#ifdef SWAP_VOLUME_IMPLEMENTED
|
||||
char volumeName[B_FILE_NAME_LENGTH] = {0};
|
||||
if (SwapVolume().InitCheck() != B_NO_INIT)
|
||||
SwapVolume().GetName(volumeName);
|
||||
else if (fBadVolName)
|
||||
strcpy(volumeName, fBadVolName);
|
||||
snprintf(buffer, sizeof(buffer), "vm %s\nswap_size %Ld\nswap_volume %s\n",
|
||||
SwapEnabled() ? "on" : "off", SwapSize(),
|
||||
volumeName[0] ? volumeName : NULL);
|
||||
#else
|
||||
snprintf(buffer, sizeof(buffer), "vm %s\nswap_size %Ld\n",
|
||||
fSwapEnabled ? "on" : "off", fSwapSize);
|
||||
#endif
|
||||
return B_ERROR;
|
||||
|
||||
fs_info info;
|
||||
fs_stat_dev(SwapVolume(), &info);
|
||||
|
||||
char buffer[1024];
|
||||
snprintf(buffer, sizeof(buffer), "vm %s\nswap_size %lld\n"
|
||||
"swap_volume_name %s\nswap_volume_device %s\n"
|
||||
"swap_volume_filesystem %s\nswap_volume_capacity %lld\n",
|
||||
SwapEnabled() ? "on" : "off", SwapSize(), info.volume_name,
|
||||
info.device_name, info.fsh_name, info.total_blocks * info.block_size);
|
||||
|
||||
file.Write(buffer, strlen(buffer));
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
Settings::IsRevertable()
|
||||
{
|
||||
return SwapEnabled() != fInitialSettings.enabled
|
||||
|| SwapSize() != fInitialSettings.size
|
||||
|| SwapVolume() != fInitialSettings.volume;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Settings::_SetSwapNull()
|
||||
Settings::RevertSwapSettings()
|
||||
{
|
||||
SetSwapEnabled(false);
|
||||
BVolumeRoster volumeRoster;
|
||||
BVolume temporaryVolume;
|
||||
volumeRoster.GetBootVolume(&temporaryVolume);
|
||||
SetSwapVolume(temporaryVolume);
|
||||
SetSwapSize(0);
|
||||
SetSwapEnabled(fInitialSettings.enabled);
|
||||
SetSwapSize(fInitialSettings.size);
|
||||
SetSwapVolume(fInitialSettings.volume);
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
Settings::IsDefaultable()
|
||||
{
|
||||
return SwapEnabled() != fDefaultSettings.enabled
|
||||
|| SwapSize() != fDefaultSettings.size
|
||||
|| SwapVolume() != fDefaultSettings.volume;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Settings::DefaultSwapSettings(bool revertable)
|
||||
{
|
||||
SetSwapEnabled(fDefaultSettings.enabled);
|
||||
SetSwapSize(fDefaultSettings.size);
|
||||
SetSwapVolume(fDefaultSettings.volume);
|
||||
if (!revertable)
|
||||
fInitialSettings = fDefaultSettings;
|
||||
}
|
||||
|
||||
@@ -1,54 +1,63 @@
|
||||
/*
|
||||
* Copyright 2005, Axel Dörfler, [email protected]. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
* Copyright 2011, Hamish Morrison, [email protected]
|
||||
* Copyright 2005, Axel Dörfler, [email protected]
|
||||
* All rights reserved. Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef SETTINGS_H
|
||||
#define SETTINGS_H
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <Point.h>
|
||||
#include <Volume.h>
|
||||
|
||||
|
||||
static const int32 kErrorSettingsNotFound = B_ERRORS_END + 1;
|
||||
static const int32 kErrorSettingsInvalid = B_ERRORS_END + 2;
|
||||
static const int32 kErrorVolumeNotFound = B_ERRORS_END + 3;
|
||||
|
||||
|
||||
|
||||
class Settings {
|
||||
public :
|
||||
Settings();
|
||||
virtual ~Settings();
|
||||
public:
|
||||
Settings();
|
||||
|
||||
BPoint WindowPosition() const { return fWindowPosition; }
|
||||
void SetWindowPosition(BPoint position);
|
||||
bool SwapEnabled() const
|
||||
{ return fCurrentSettings.enabled; }
|
||||
off_t SwapSize() const { return fCurrentSettings.size; }
|
||||
dev_t SwapVolume() { return fCurrentSettings.volume; }
|
||||
BPoint WindowPosition() const { return fWindowPosition; }
|
||||
|
||||
bool SwapEnabled() const { return fSwapEnabled; }
|
||||
off_t SwapSize() const { return fSwapSize; }
|
||||
BVolume& SwapVolume() { return fSwapVolume; }
|
||||
void SetSwapEnabled(bool enabled);
|
||||
void SetSwapSize(off_t size);
|
||||
void SetSwapVolume(BVolume& volume);
|
||||
void SetSwapEnabled(bool enabled,
|
||||
bool revertable = true);
|
||||
void SetSwapSize(off_t size, bool revertable = true);
|
||||
void SetSwapVolume(dev_t volume,
|
||||
bool revertable = true);
|
||||
void SetWindowPosition(BPoint position);
|
||||
|
||||
void RevertSwapChanges();
|
||||
bool IsRevertible();
|
||||
status_t ReadWindowSettings();
|
||||
status_t WriteWindowSettings();
|
||||
status_t ReadSwapSettings();
|
||||
status_t WriteSwapSettings();
|
||||
|
||||
private:
|
||||
void _ReadWindowSettings();
|
||||
void _WriteWindowSettings();
|
||||
bool IsRevertable();
|
||||
void RevertSwapSettings();
|
||||
|
||||
void _ReadSwapSettings();
|
||||
void _WriteSwapSettings();
|
||||
bool IsDefaultable();
|
||||
void DefaultSwapSettings(bool revertable = true);
|
||||
private:
|
||||
struct SwapSettings {
|
||||
bool enabled;
|
||||
off_t size;
|
||||
dev_t volume;
|
||||
};
|
||||
|
||||
void _SetSwapNull();
|
||||
BPoint fWindowPosition;
|
||||
|
||||
BPoint fWindowPosition;
|
||||
|
||||
bool fSwapEnabled;
|
||||
off_t fSwapSize;
|
||||
BVolume fSwapVolume;
|
||||
|
||||
bool fInitialSwapEnabled;
|
||||
off_t fInitialSwapSize;
|
||||
dev_t fInitialSwapVolume;
|
||||
|
||||
bool fPositionUpdated;
|
||||
const char* fBadVolName;
|
||||
SwapSettings fCurrentSettings;
|
||||
SwapSettings fInitialSettings;
|
||||
SwapSettings fDefaultSettings;
|
||||
};
|
||||
|
||||
#endif /* SETTINGS_H */
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
|
||||
|
||||
#include "SettingsWindow.h"
|
||||
#include "Settings.h"
|
||||
|
||||
#include <Application.h>
|
||||
#include <Alert.h>
|
||||
@@ -14,22 +13,25 @@
|
||||
#include <Button.h>
|
||||
#include <Catalog.h>
|
||||
#include <CheckBox.h>
|
||||
#include <GroupLayout.h>
|
||||
#include <GroupLayoutBuilder.h>
|
||||
#include <Locale.h>
|
||||
#include <Directory.h>
|
||||
#include <FindDirectory.h>
|
||||
#include <LayoutBuilder.h>
|
||||
#include <MenuItem.h>
|
||||
#include <MenuField.h>
|
||||
#include <NodeMonitor.h>
|
||||
#include <Path.h>
|
||||
#include <PopUpMenu.h>
|
||||
#include <Screen.h>
|
||||
#include <StringForSize.h>
|
||||
#include <StringView.h>
|
||||
#include <String.h>
|
||||
#include <Slider.h>
|
||||
#include <PopUpMenu.h>
|
||||
#include <MenuItem.h>
|
||||
#include <MenuField.h>
|
||||
#include <Screen.h>
|
||||
#include <FindDirectory.h>
|
||||
#include <Path.h>
|
||||
#include <system_info.h>
|
||||
#include <Volume.h>
|
||||
#include <VolumeRoster.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include "Settings.h"
|
||||
|
||||
|
||||
#undef B_TRANSLATION_CONTEXT
|
||||
#define B_TRANSLATION_CONTEXT "SettingsWindow"
|
||||
@@ -40,90 +42,70 @@ static const uint32 kMsgRevert = 'rvrt';
|
||||
static const uint32 kMsgSliderUpdate = 'slup';
|
||||
static const uint32 kMsgSwapEnabledUpdate = 'swen';
|
||||
static const uint32 kMsgVolumeSelected = 'vlsl';
|
||||
static const int64 kMegaByte = 1024 * 1024;
|
||||
|
||||
|
||||
class SizeSlider : public BSlider {
|
||||
public:
|
||||
SizeSlider(const char* name, const char* label,
|
||||
BMessage* message, int32 min, int32 max, uint32 flags);
|
||||
virtual ~SizeSlider();
|
||||
|
||||
virtual const char* UpdateText() const;
|
||||
|
||||
private:
|
||||
mutable BString fText;
|
||||
};
|
||||
static const off_t kMegaByte = 1024 * 1024;
|
||||
static dev_t bootDev = -1;
|
||||
|
||||
|
||||
SizeSlider::SizeSlider(const char* name, const char* label,
|
||||
BMessage* message, int32 min, int32 max, uint32 flags)
|
||||
: BSlider(name, label, message, min, max, B_HORIZONTAL, B_BLOCK_THUMB, flags)
|
||||
:
|
||||
BSlider(name, label, message, min, max, B_HORIZONTAL,
|
||||
B_BLOCK_THUMB, flags)
|
||||
{
|
||||
rgb_color color = ui_color(B_CONTROL_HIGHLIGHT_COLOR);
|
||||
UseFillColor(true, &color);
|
||||
}
|
||||
|
||||
|
||||
SizeSlider::~SizeSlider()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
const char*
|
||||
byte_string(int64 size)
|
||||
{
|
||||
double value = 1. * size;
|
||||
static char string[256];
|
||||
|
||||
if (value < 1024)
|
||||
snprintf(string, sizeof(string), B_TRANSLATE("%Ld B"), size);
|
||||
else {
|
||||
static const char *units[] = {
|
||||
B_TRANSLATE_MARK("KB"),
|
||||
B_TRANSLATE_MARK("MB"),
|
||||
B_TRANSLATE_MARK("GB"),
|
||||
NULL
|
||||
};
|
||||
int32 i = -1;
|
||||
|
||||
do {
|
||||
value /= 1024.0;
|
||||
i++;
|
||||
} while (value >= 1024 && units[i + 1]);
|
||||
|
||||
off_t rounded = off_t(value * 100LL);
|
||||
snprintf(string, sizeof(string), "%g %s", rounded / 100.0,
|
||||
B_TRANSLATE_NOCOLLECT(units[i]));
|
||||
}
|
||||
|
||||
return string;
|
||||
}
|
||||
|
||||
|
||||
const char*
|
||||
SizeSlider::UpdateText() const
|
||||
{
|
||||
fText = byte_string(Value() * kMegaByte);
|
||||
return fText.String();
|
||||
return string_for_size(Value() * kMegaByte, fText, sizeof(fText));
|
||||
}
|
||||
|
||||
|
||||
class VolumeMenuItem : public BMenuItem {
|
||||
public:
|
||||
VolumeMenuItem(const char* label, BMessage* message, BVolume* volume);
|
||||
BVolume* Volume() { return fVolume; }
|
||||
|
||||
private:
|
||||
BVolume* fVolume;
|
||||
};
|
||||
|
||||
|
||||
VolumeMenuItem::VolumeMenuItem(const char* label, BMessage* message,
|
||||
BVolume* volume)
|
||||
: BMenuItem(label, message)
|
||||
VolumeMenuItem::VolumeMenuItem(BVolume volume, BMessage* message)
|
||||
:
|
||||
BMenuItem("", message),
|
||||
fVolume(volume)
|
||||
{
|
||||
fVolume = volume;
|
||||
GenerateLabel();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
VolumeMenuItem::MessageReceived(BMessage* message)
|
||||
{
|
||||
if (message->what == B_NODE_MONITOR) {
|
||||
int32 code;
|
||||
if (message->FindInt32("opcode", &code) == B_OK)
|
||||
if (code == B_ENTRY_MOVED)
|
||||
GenerateLabel();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
VolumeMenuItem::GenerateLabel()
|
||||
{
|
||||
char name[B_FILE_NAME_LENGTH + 1];
|
||||
fVolume.GetName(name);
|
||||
|
||||
BDirectory dir;
|
||||
if (fVolume.GetRootDirectory(&dir) == B_OK) {
|
||||
BEntry entry;
|
||||
if (dir.GetEntry(&entry) == B_OK) {
|
||||
BPath path;
|
||||
if (entry.GetPath(&path) == B_OK) {
|
||||
BString label;
|
||||
label << name << " (" << path.Path() << ")";
|
||||
SetLabel(label);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SetLabel(name);
|
||||
}
|
||||
|
||||
|
||||
@@ -131,81 +113,102 @@ SettingsWindow::SettingsWindow()
|
||||
:
|
||||
BWindow(BRect(0, 0, 269, 172), B_TRANSLATE_SYSTEM_NAME("VirtualMemory"),
|
||||
B_TITLED_WINDOW, B_NOT_RESIZABLE | B_ASYNCHRONOUS_CONTROLS
|
||||
| B_NOT_ZOOMABLE | B_AUTO_UPDATE_SIZE_LIMITS),
|
||||
fLocked(false)
|
||||
|
||||
| B_NOT_ZOOMABLE | B_AUTO_UPDATE_SIZE_LIMITS)
|
||||
|
||||
{
|
||||
BView* view = new BGroupView();
|
||||
bootDev = dev_for_path("/boot");
|
||||
BAlignment align(B_ALIGN_LEFT, B_ALIGN_MIDDLE);
|
||||
|
||||
if (fSettings.ReadWindowSettings() == B_OK)
|
||||
MoveTo(fSettings.WindowPosition());
|
||||
else
|
||||
CenterOnScreen();
|
||||
|
||||
status_t result = fSettings.ReadSwapSettings();
|
||||
if (result == kErrorSettingsNotFound)
|
||||
fSettings.DefaultSwapSettings(false);
|
||||
else if (result == kErrorSettingsInvalid) {
|
||||
int32 choice = (new BAlert("VirtualMemory",
|
||||
B_TRANSLATE("The settings specified in the settings file "
|
||||
"are invalid. You can load the defaults or quit."),
|
||||
B_TRANSLATE("Load defaults"), B_TRANSLATE("Quit")))->Go();
|
||||
if (choice == 1) {
|
||||
be_app->PostMessage(B_QUIT_REQUESTED);
|
||||
return;
|
||||
}
|
||||
fSettings.DefaultSwapSettings(false);
|
||||
} else if (result == kErrorVolumeNotFound) {
|
||||
int32 choice = (new BAlert("VirtualMemory",
|
||||
B_TRANSLATE("The volume specified in the settings file "
|
||||
"could not be found. You can use the boot volume or quit."),
|
||||
B_TRANSLATE("Use boot volume"), B_TRANSLATE("Quit")))->Go();
|
||||
if (choice == 1) {
|
||||
be_app->PostMessage(B_QUIT_REQUESTED);
|
||||
return;
|
||||
}
|
||||
fSettings.SetSwapVolume(bootDev, false);
|
||||
}
|
||||
|
||||
fSwapEnabledCheckBox = new BCheckBox("enable swap",
|
||||
B_TRANSLATE("Enable virtual memory"),
|
||||
new BMessage(kMsgSwapEnabledUpdate));
|
||||
fSwapEnabledCheckBox->SetExplicitAlignment(align);
|
||||
|
||||
BBox* box = new BBox("box", B_FOLLOW_LEFT_RIGHT);
|
||||
box->SetLabel(fSwapEnabledCheckBox);
|
||||
|
||||
char sizeStr[16];
|
||||
system_info info;
|
||||
get_system_info(&info);
|
||||
|
||||
BString string = B_TRANSLATE("Physical memory: ");
|
||||
string << byte_string((off_t)info.max_pages * B_PAGE_SIZE);
|
||||
BStringView* memoryView = new BStringView("physical memory", string.String());
|
||||
string << string_for_size(info.max_pages * B_PAGE_SIZE, sizeStr,
|
||||
sizeof(sizeStr));
|
||||
BStringView* memoryView = new BStringView("physical memory",
|
||||
string.String());
|
||||
memoryView->SetExplicitAlignment(align);
|
||||
|
||||
system_memory_info memInfo = {};
|
||||
__get_system_info_etc(B_MEMORY_INFO, &memInfo, sizeof(memInfo));
|
||||
string = B_TRANSLATE("Current swap file size: ");
|
||||
string << byte_string(fSettings.SwapSize());
|
||||
BStringView* swapfileView = new BStringView("current swap size", string.String());
|
||||
string << string_for_size(memInfo.max_swap_space, sizeStr,
|
||||
sizeof(sizeStr));
|
||||
BStringView* swapFileView = new BStringView("current swap size",
|
||||
string.String());
|
||||
swapFileView->SetExplicitAlignment(align);
|
||||
|
||||
BPopUpMenu* menu = new BPopUpMenu("invalid");
|
||||
BPopUpMenu* menu = new BPopUpMenu("volume menu");
|
||||
fVolumeMenuField = new BMenuField("volume menu field",
|
||||
B_TRANSLATE("Use volume:"), menu);
|
||||
fVolumeMenuField->SetExplicitAlignment(align);
|
||||
|
||||
// collect volumes
|
||||
// TODO: listen to volume changes!
|
||||
// TODO: accept dropped volumes
|
||||
|
||||
BVolumeRoster volumeRoster;
|
||||
BVolume* volume = new BVolume();
|
||||
char name[B_FILE_NAME_LENGTH];
|
||||
while (volumeRoster.GetNextVolume(volume) == B_OK) {
|
||||
if (!volume->IsPersistent() || volume->GetName(name) != B_OK || !name[0])
|
||||
BVolumeRoster roster;
|
||||
BVolume vol;
|
||||
while (roster.GetNextVolume(&vol) == B_OK) {
|
||||
if (!vol.IsPersistent() || vol.IsReadOnly() || vol.IsRemovable()
|
||||
|| vol.IsShared())
|
||||
continue;
|
||||
VolumeMenuItem* item = new VolumeMenuItem(name,
|
||||
new BMessage(kMsgVolumeSelected), volume);
|
||||
menu->AddItem(item);
|
||||
volume = new BVolume();
|
||||
_AddVolumeMenuItem(vol.Device());
|
||||
}
|
||||
|
||||
fVolumeMenuField = new BMenuField("volumes", B_TRANSLATE("Use volume:"), menu);
|
||||
|
||||
fSizeSlider = new SizeSlider("size slider",
|
||||
B_TRANSLATE("Requested swap file size:"), new BMessage(kMsgSliderUpdate),
|
||||
1, 1, B_WILL_DRAW | B_FRAME_EVENTS);
|
||||
watch_node(NULL, B_WATCH_MOUNT, this, this);
|
||||
|
||||
fSizeSlider = new SizeSlider("size slider",
|
||||
B_TRANSLATE("Requested swap file size:"),
|
||||
new BMessage(kMsgSliderUpdate), 0, 0, B_WILL_DRAW | B_FRAME_EVENTS);
|
||||
fSizeSlider->SetViewColor(255, 0, 255);
|
||||
fSizeSlider->SetExplicitAlignment(align);
|
||||
|
||||
fWarningStringView = new BStringView("", "");
|
||||
fWarningStringView->SetAlignment(B_ALIGN_CENTER);
|
||||
fWarningStringView = new BStringView("warning",
|
||||
B_TRANSLATE("Changes will take effect upon reboot."));
|
||||
|
||||
view->SetLayout(new BGroupLayout(B_HORIZONTAL));
|
||||
view->AddChild(BGroupLayoutBuilder(B_VERTICAL, 10)
|
||||
.AddGroup(B_HORIZONTAL)
|
||||
.Add(memoryView)
|
||||
.AddGlue()
|
||||
.End()
|
||||
.AddGroup(B_HORIZONTAL)
|
||||
.Add(swapfileView)
|
||||
.AddGlue()
|
||||
.End()
|
||||
#ifdef SWAP_VOLUME_IMPLEMENTED
|
||||
.AddGroup(B_HORIZONTAL)
|
||||
.Add(fVolumeMenuField)
|
||||
.AddGlue()
|
||||
.End()
|
||||
#else
|
||||
.AddGlue()
|
||||
#endif
|
||||
BBox* box = new BBox("box");
|
||||
box->SetLabel(fSwapEnabledCheckBox);
|
||||
|
||||
box->AddChild(BLayoutBuilder::Group<>(B_VERTICAL, B_USE_DEFAULT_SPACING)
|
||||
.Add(memoryView)
|
||||
.Add(swapFileView)
|
||||
.Add(fVolumeMenuField)
|
||||
.Add(fSizeSlider)
|
||||
.Add(fWarningStringView)
|
||||
.SetInsets(10, 10, 10, 10)
|
||||
);
|
||||
box->AddChild(view);
|
||||
.SetInsets(10)
|
||||
.View());
|
||||
|
||||
fDefaultsButton = new BButton("defaults", B_TRANSLATE("Defaults"),
|
||||
new BMessage(kMsgDefaults));
|
||||
@@ -214,16 +217,14 @@ SettingsWindow::SettingsWindow()
|
||||
new BMessage(kMsgRevert));
|
||||
fRevertButton->SetEnabled(false);
|
||||
|
||||
SetLayout(new BGroupLayout(B_HORIZONTAL));
|
||||
AddChild(BGroupLayoutBuilder(B_VERTICAL, 10)
|
||||
BLayoutBuilder::Group<>(this, B_VERTICAL, B_USE_DEFAULT_SPACING)
|
||||
.Add(box)
|
||||
.AddGroup(B_HORIZONTAL, 10)
|
||||
.Add(fDefaultsButton)
|
||||
.Add(fRevertButton)
|
||||
.AddGlue()
|
||||
.End()
|
||||
.SetInsets(10, 10, 10, 10)
|
||||
);
|
||||
.SetInsets(10);
|
||||
|
||||
BScreen screen;
|
||||
BRect screenFrame = screen.Frame();
|
||||
@@ -258,21 +259,37 @@ SettingsWindow::SettingsWindow()
|
||||
}
|
||||
|
||||
|
||||
SettingsWindow::~SettingsWindow()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
SettingsWindow::MessageReceived(BMessage* message)
|
||||
{
|
||||
switch (message->what) {
|
||||
case B_NODE_MONITOR:
|
||||
{
|
||||
int32 opcode;
|
||||
if (message->FindInt32("opcode", &opcode) != B_OK)
|
||||
break;
|
||||
dev_t device;
|
||||
if (opcode == B_DEVICE_MOUNTED
|
||||
&& message->FindInt32("new device", &device) == B_OK) {
|
||||
BVolume vol(device);
|
||||
if (!vol.IsPersistent() || vol.IsReadOnly()
|
||||
|| vol.IsRemovable() || vol.IsShared()) {
|
||||
break;
|
||||
}
|
||||
_AddVolumeMenuItem(device);
|
||||
} else if (opcode == B_DEVICE_UNMOUNTED
|
||||
&& message->FindInt32("device", &device) == B_OK) {
|
||||
_RemoveVolumeMenuItem(device);
|
||||
}
|
||||
_Update();
|
||||
break;
|
||||
}
|
||||
case kMsgRevert:
|
||||
fSettings.RevertSwapChanges();
|
||||
fSettings.RevertSwapSettings();
|
||||
_Update();
|
||||
break;
|
||||
case kMsgDefaults:
|
||||
_SetSwapDefaults();
|
||||
fSettings.DefaultSwapSettings();
|
||||
_Update();
|
||||
break;
|
||||
case kMsgSliderUpdate:
|
||||
@@ -280,18 +297,15 @@ SettingsWindow::MessageReceived(BMessage* message)
|
||||
_Update();
|
||||
break;
|
||||
case kMsgVolumeSelected:
|
||||
fSettings.SetSwapVolume(*((VolumeMenuItem*)fVolumeMenuField->Menu()
|
||||
->FindMarked())->Volume());
|
||||
fSettings.SetSwapVolume(((VolumeMenuItem*)fVolumeMenuField
|
||||
->Menu()->FindMarked())->Volume().Device());
|
||||
_Update();
|
||||
break;
|
||||
case kMsgSwapEnabledUpdate:
|
||||
{
|
||||
int32 value;
|
||||
if (message->FindInt32("be:value", &value) != B_OK)
|
||||
break;
|
||||
|
||||
if (value == 0) {
|
||||
// print out warning, give the user the time to think about it :)
|
||||
if (fSwapEnabledCheckBox->Value() == 0) {
|
||||
// print out warning, give the user the
|
||||
// time to think about it :)
|
||||
// ToDo: maybe we want to remove this possibility in the GUI
|
||||
// as Be did, but I thought a proper warning could be helpful
|
||||
// (for those that want to change that anyway)
|
||||
@@ -312,7 +326,7 @@ SettingsWindow::MessageReceived(BMessage* message)
|
||||
}
|
||||
}
|
||||
|
||||
fSettings.SetSwapEnabled(value != 0);
|
||||
fSettings.SetSwapEnabled(fSwapEnabledCheckBox->Value());
|
||||
_Update();
|
||||
break;
|
||||
}
|
||||
@@ -327,142 +341,107 @@ bool
|
||||
SettingsWindow::QuitRequested()
|
||||
{
|
||||
fSettings.SetWindowPosition(Frame().LeftTop());
|
||||
fSettings.WriteWindowSettings();
|
||||
fSettings.WriteSwapSettings();
|
||||
be_app->PostMessage(B_QUIT_REQUESTED);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
SettingsWindow::_AddVolumeMenuItem(dev_t device)
|
||||
{
|
||||
if (_FindVolumeMenuItem(device) != NULL)
|
||||
return B_ERROR;
|
||||
|
||||
VolumeMenuItem* item = new VolumeMenuItem(device,
|
||||
new BMessage(kMsgVolumeSelected));
|
||||
|
||||
fs_info info;
|
||||
if (fs_stat_dev(device, &info) == 0) {
|
||||
node_ref node;
|
||||
node.device = info.dev;
|
||||
node.node = info.root;
|
||||
AddHandler(item);
|
||||
watch_node(&node, B_WATCH_NAME, item);
|
||||
}
|
||||
|
||||
fVolumeMenuField->Menu()->AddItem(item);
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
SettingsWindow::_RemoveVolumeMenuItem(dev_t device)
|
||||
{
|
||||
VolumeMenuItem* item = _FindVolumeMenuItem(device);
|
||||
if (item != NULL) {
|
||||
fVolumeMenuField->Menu()->RemoveItem(item);
|
||||
delete item;
|
||||
return B_OK;
|
||||
} else
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
|
||||
VolumeMenuItem*
|
||||
SettingsWindow::_FindVolumeMenuItem(dev_t device)
|
||||
{
|
||||
VolumeMenuItem* item = NULL;
|
||||
int32 count = fVolumeMenuField->Menu()->CountItems();
|
||||
for (int i = 0; i < count; i++) {
|
||||
item = (VolumeMenuItem*)fVolumeMenuField->Menu()->ItemAt(i);
|
||||
if (item->Volume().Device() == device)
|
||||
return item;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
SettingsWindow::_Update()
|
||||
{
|
||||
if ((fSwapEnabledCheckBox->Value() != 0) != fSettings.SwapEnabled())
|
||||
fSwapEnabledCheckBox->SetValue(fSettings.SwapEnabled());
|
||||
fSwapEnabledCheckBox->SetValue(fSettings.SwapEnabled());
|
||||
|
||||
#ifdef SWAP_VOLUME_IMPLEMENTED
|
||||
if (fVolumeMenuField->IsEnabled() != fSettings.SwapEnabled())
|
||||
fVolumeMenuField->SetEnabled(fSettings.SwapEnabled());
|
||||
VolumeMenuItem* selectedVolumeItem =
|
||||
(VolumeMenuItem*)fVolumeMenuField->Menu()->FindMarked();
|
||||
if (selectedVolumeItem == NULL) {
|
||||
VolumeMenuItem* currentVolumeItem;
|
||||
int32 items = fVolumeMenuField->Menu()->CountItems();
|
||||
for (int32 index = 0; index < items; ++index) {
|
||||
currentVolumeItem = ((VolumeMenuItem*)fVolumeMenuField->Menu()->ItemAt(index));
|
||||
if (*(currentVolumeItem->fVolume) == fSettings.SwapVolume()) {
|
||||
currentVolumeItem->SetMarked(true);
|
||||
break;
|
||||
}
|
||||
VolumeMenuItem* item = _FindVolumeMenuItem(fSettings.SwapVolume());
|
||||
if (item != NULL) {
|
||||
fSizeSlider->SetEnabled(true);
|
||||
item->SetMarked(true);
|
||||
BEntry swapFile;
|
||||
if (bootDev == item->Volume().Device())
|
||||
swapFile.SetTo("/var/swap");
|
||||
else {
|
||||
BDirectory root;
|
||||
item->Volume().GetRootDirectory(&root);
|
||||
swapFile.SetTo(&root, "swap");
|
||||
}
|
||||
} else if (*selectedVolumeItem->fVolume != fSettings.SwapVolume()) {
|
||||
VolumeMenuItem* currentVolumeItem;
|
||||
int32 items = fVolumeMenuField->Menu()->CountItems();
|
||||
for (int32 index = 0; index < items; ++index) {
|
||||
currentVolumeItem = ((VolumeMenuItem*)fVolumeMenuField->Menu()->ItemAt(index));
|
||||
if (*(currentVolumeItem->fVolume) == fSettings.SwapVolume()) {
|
||||
currentVolumeItem->SetMarked(true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
fWarningStringView->SetText("");
|
||||
fLocked = false;
|
||||
|
||||
if (fSettings.IsRevertible())
|
||||
fWarningStringView->SetText(
|
||||
B_TRANSLATE("Changes will take effect on restart!"));
|
||||
if (fRevertButton->IsEnabled() != fSettings.IsRevertible())
|
||||
fRevertButton->SetEnabled(fSettings.IsRevertible());
|
||||
|
||||
off_t minSize, maxSize;
|
||||
if (_GetSwapFileLimits(minSize, maxSize) == B_OK) {
|
||||
// round to nearest MB -- slider steps in whole MBs
|
||||
off_t swapFileSize = 0;
|
||||
swapFile.GetSize(&swapFileSize);
|
||||
|
||||
char sizeStr[16];
|
||||
|
||||
off_t freeSpace = item->Volume().FreeBytes() + swapFileSize;
|
||||
off_t safeSpace = freeSpace - (off_t)(0.15 * freeSpace);
|
||||
(safeSpace >>= 20) <<= 20;
|
||||
off_t minSize = B_PAGE_SIZE + kMegaByte;
|
||||
(minSize >>= 20) <<= 20;
|
||||
(maxSize >>= 20) <<= 20;
|
||||
BString minLabel, maxLabel;
|
||||
minLabel << byte_string(minSize);
|
||||
maxLabel << byte_string(maxSize);
|
||||
if (minLabel != fSizeSlider->MinLimitLabel()
|
||||
|| maxLabel != fSizeSlider->MaxLimitLabel()) {
|
||||
fSizeSlider->SetLimitLabels(minLabel.String(), maxLabel.String());
|
||||
fSizeSlider->SetLimits(minSize / kMegaByte, maxSize / kMegaByte);
|
||||
}
|
||||
} else if (fSettings.SwapEnabled()) {
|
||||
fWarningStringView->SetText(
|
||||
B_TRANSLATE("Insufficient space for a swap file."));
|
||||
fLocked = true;
|
||||
}
|
||||
if (fSizeSlider->Value() != fSettings.SwapSize() / kMegaByte)
|
||||
minLabel << string_for_size(minSize, sizeStr, sizeof(sizeStr));
|
||||
maxLabel << string_for_size(safeSpace, sizeStr, sizeof(sizeStr));
|
||||
|
||||
fSizeSlider->SetLimitLabels(minLabel.String(), maxLabel.String());
|
||||
fSizeSlider->SetLimits(minSize / kMegaByte, safeSpace / kMegaByte);
|
||||
fSizeSlider->SetValue(fSettings.SwapSize() / kMegaByte);
|
||||
if (fSizeSlider->IsEnabled() != fSettings.SwapEnabled() || fLocked)
|
||||
{
|
||||
fSizeSlider->SetEnabled(fSettings.SwapEnabled() && !fLocked);
|
||||
fSettings.SetSwapSize((off_t)fSizeSlider->Value() * kMegaByte);
|
||||
}
|
||||
} else
|
||||
fSizeSlider->SetEnabled(false);
|
||||
|
||||
bool revertable = fSettings.IsRevertable();
|
||||
if (revertable)
|
||||
fWarningStringView->Show();
|
||||
else
|
||||
fWarningStringView->Hide();
|
||||
fRevertButton->SetEnabled(revertable);
|
||||
fDefaultsButton->SetEnabled(fSettings.IsDefaultable());
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
SettingsWindow::_GetSwapFileLimits(off_t& minSize, off_t& maxSize)
|
||||
{
|
||||
minSize = kMegaByte;
|
||||
|
||||
// maximum size is the free space on the current volume
|
||||
// (minus some safety offset, depending on the disk size)
|
||||
off_t freeSpace = fSettings.SwapVolume().FreeBytes();
|
||||
off_t safetyFreeSpace = fSettings.SwapVolume().Capacity() / 100;
|
||||
if (safetyFreeSpace > 1024 * kMegaByte)
|
||||
safetyFreeSpace = 1024 * kMegaByte;
|
||||
|
||||
// check if there already is a page file on this disk and
|
||||
// adjust the free space accordingly
|
||||
BPath path;
|
||||
if (find_directory(B_COMMON_VAR_DIRECTORY, &path, false,
|
||||
&fSettings.SwapVolume()) == B_OK) {
|
||||
path.Append("swap");
|
||||
BEntry swap(path.Path());
|
||||
|
||||
off_t size;
|
||||
if (swap.GetSize(&size) == B_OK) {
|
||||
// If swap file exists, forget about safety space;
|
||||
// disk may have filled after creation of swap file.
|
||||
safetyFreeSpace = 0;
|
||||
freeSpace += size;
|
||||
}
|
||||
}
|
||||
|
||||
maxSize = freeSpace - safetyFreeSpace;
|
||||
if (maxSize < minSize) {
|
||||
maxSize = 0;
|
||||
minSize = 0;
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
SettingsWindow::_SetSwapDefaults()
|
||||
{
|
||||
fSettings.SetSwapEnabled(true);
|
||||
|
||||
BVolumeRoster volumeRoster;
|
||||
BVolume temporaryVolume;
|
||||
volumeRoster.GetBootVolume(&temporaryVolume);
|
||||
fSettings.SetSwapVolume(temporaryVolume);
|
||||
|
||||
system_info info;
|
||||
get_system_info(&info);
|
||||
|
||||
off_t defaultSize = (off_t)info.max_pages * B_PAGE_SIZE;
|
||||
off_t minSize, maxSize;
|
||||
_GetSwapFileLimits(minSize, maxSize);
|
||||
|
||||
if (defaultSize > maxSize / 2)
|
||||
defaultSize = maxSize / 2;
|
||||
|
||||
fSettings.SetSwapSize(defaultSize);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,43 +1,77 @@
|
||||
/*
|
||||
* Copyright 2005-2006, Axel Dörfler, [email protected]. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
* Copyright 2011, Hamish Morrison, [email protected]
|
||||
* Copyright 2005-2006, Axel Dörfler, [email protected]
|
||||
* All rights reserved. Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef SETTINGS_WINDOW_H
|
||||
#define SETTINGS_WINDOW_H
|
||||
|
||||
|
||||
#include <MenuItem.h>
|
||||
#include <Slider.h>
|
||||
#include <Volume.h>
|
||||
#include <Window.h>
|
||||
|
||||
#include "Settings.h"
|
||||
|
||||
|
||||
class BStringView;
|
||||
class BCheckBox;
|
||||
class BSlider;
|
||||
class BButton;
|
||||
class BMenuField;
|
||||
|
||||
|
||||
class SizeSlider : public BSlider {
|
||||
public:
|
||||
SizeSlider(const char* name, const char* label,
|
||||
BMessage* message, int32 min, int32 max,
|
||||
uint32 flags);
|
||||
virtual ~SizeSlider() {};
|
||||
|
||||
virtual const char* UpdateText() const;
|
||||
|
||||
private:
|
||||
mutable char fText[128];
|
||||
};
|
||||
|
||||
|
||||
class VolumeMenuItem : public BMenuItem, public BHandler {
|
||||
public:
|
||||
VolumeMenuItem(BVolume volume, BMessage* message);
|
||||
virtual ~VolumeMenuItem() {}
|
||||
|
||||
virtual BVolume Volume() { return fVolume; }
|
||||
virtual void MessageReceived(BMessage* message);
|
||||
virtual void GenerateLabel();
|
||||
|
||||
private:
|
||||
BVolume fVolume;
|
||||
};
|
||||
|
||||
|
||||
class SettingsWindow : public BWindow {
|
||||
public:
|
||||
SettingsWindow();
|
||||
virtual ~SettingsWindow();
|
||||
public:
|
||||
SettingsWindow();
|
||||
virtual ~SettingsWindow() {};
|
||||
|
||||
virtual bool QuitRequested();
|
||||
virtual void MessageReceived(BMessage* message);
|
||||
virtual void MessageReceived(BMessage* message);
|
||||
virtual bool QuitRequested();
|
||||
|
||||
private:
|
||||
void _Update();
|
||||
status_t _GetSwapFileLimits(off_t& minSize, off_t& maxSize);
|
||||
void _SetSwapDefaults();
|
||||
private:
|
||||
status_t _AddVolumeMenuItem(dev_t device);
|
||||
status_t _RemoveVolumeMenuItem(dev_t device);
|
||||
VolumeMenuItem* _FindVolumeMenuItem(dev_t device);
|
||||
|
||||
BCheckBox* fSwapEnabledCheckBox;
|
||||
BSlider* fSizeSlider;
|
||||
BButton* fDefaultsButton;
|
||||
BButton* fRevertButton;
|
||||
BStringView* fWarningStringView;
|
||||
BMenuField* fVolumeMenuField;
|
||||
Settings fSettings;
|
||||
|
||||
bool fLocked;
|
||||
void _Update();
|
||||
|
||||
BCheckBox* fSwapEnabledCheckBox;
|
||||
BSlider* fSizeSlider;
|
||||
BButton* fDefaultsButton;
|
||||
BButton* fRevertButton;
|
||||
BStringView* fWarningStringView;
|
||||
BMenuField* fVolumeMenuField;
|
||||
Settings fSettings;
|
||||
};
|
||||
|
||||
#endif /* SETTINGS_WINDOW_H */
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include "SettingsWindow.h"
|
||||
|
||||
#include <Alert.h>
|
||||
#include <Catalog.h>
|
||||
#include <TextView.h>
|
||||
|
||||
|
||||
|
||||
@@ -7,24 +7,15 @@
|
||||
|
||||
|
||||
#include <Application.h>
|
||||
#include <Catalog.h>
|
||||
#include <Locale.h>
|
||||
|
||||
class VMSettings;
|
||||
|
||||
|
||||
class VirtualMemory : public BApplication {
|
||||
public:
|
||||
VirtualMemory();
|
||||
virtual ~VirtualMemory();
|
||||
public:
|
||||
VirtualMemory();
|
||||
virtual ~VirtualMemory();
|
||||
|
||||
virtual void ReadyToRun();
|
||||
virtual void AboutRequested();
|
||||
|
||||
private:
|
||||
void GetCurrentSettings(bool& enabled, off_t& size);
|
||||
|
||||
VMSettings *fSettings;
|
||||
virtual void ReadyToRun();
|
||||
virtual void AboutRequested();
|
||||
};
|
||||
|
||||
|
||||
#endif /* VIRTUAL_MEMORY_H */
|
||||
|
||||
Reference in New Issue
Block a user