xref: /haiku/src/preferences/virtualmemory/Settings.cpp (revision 0d452c8f34013b611a54c746a71c05e28796eae2)
1 /*
2  * Copyright 2010-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.
5  */
6 
7 
8 #include "Settings.h"
9 
10 #include <File.h>
11 #include <Entry.h>
12 #include <FindDirectory.h>
13 #include <Path.h>
14 #include <Volume.h>
15 #include <VolumeRoster.h>
16 #include <driver_settings.h>
17 
18 #include <stdio.h>
19 #include <stdlib.h>
20 #include <string.h>
21 
22 
23 static const char* kWindowSettingsFile = "VM_data";
24 static const char* kVirtualMemorySettings = "virtual_memory";
25 static const int64 kMegaByte = 1024 * 1024;
26 
27 
28 Settings::Settings()
29 	:
30 	fPositionUpdated(false)
31 {
32 	_ReadWindowSettings();
33 	_ReadSwapSettings();
34 }
35 
36 
37 Settings::~Settings()
38 {
39 	_WriteWindowSettings();
40 	_WriteSwapSettings();
41 }
42 
43 
44 void
45 Settings::SetWindowPosition(BPoint position)
46 {
47 	if (position == fWindowPosition)
48 		return;
49 
50 	fWindowPosition = position;
51 	fPositionUpdated = true;
52 }
53 
54 
55 void
56 Settings::SetSwapEnabled(bool enabled)
57 {
58 	fSwapEnabled = enabled;
59 }
60 
61 
62 void
63 Settings::SetSwapSize(off_t size)
64 {
65 	fSwapSize = size;
66 }
67 
68 
69 void
70 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 }
78 
79 
80 void
81 Settings::RevertSwapChanges()
82 {
83 	fSwapEnabled = fInitialSwapEnabled;
84 	fSwapSize = fInitialSwapSize;
85 	fSwapVolume.SetTo(fInitialSwapVolume);
86 }
87 
88 
89 bool
90 Settings::IsRevertible()
91 {
92 	return fSwapEnabled != fInitialSwapEnabled
93 		|| fSwapSize != fInitialSwapSize
94 		|| fSwapVolume.Device() != fInitialSwapVolume;
95 }
96 
97 
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);
114 }
115 
116 
117 void
118 Settings::_WriteWindowSettings()
119 {
120 	if (!fPositionUpdated)
121 		return;
122 
123 	BPath path;
124 	if (find_directory(B_USER_SETTINGS_DIRECTORY, &path) < B_OK)
125 		return;
126 
127 	path.Append(kWindowSettingsFile);
128 
129 	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));
132 }
133 
134 
135 void
136 Settings::_ReadSwapSettings()
137 {
138 	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);
162 			}
163 		} else
164 			volumeRoster.GetBootVolume(&fSwapVolume);
165 #endif
166 		unload_driver_settings(settings);
167 	} else
168 		_SetSwapNull();
169 
170 #ifndef SWAP_VOLUME_IMPLEMENTED
171 	BVolumeRoster volumeRoster;
172 	volumeRoster.GetBootVolume(&fSwapVolume);
173 #endif
174 
175 	fInitialSwapEnabled = fSwapEnabled;
176 	fInitialSwapSize = fSwapSize;
177 	fInitialSwapVolume = fSwapVolume.Device();
178 }
179 
180 
181 void
182 Settings::_WriteSwapSettings()
183 {
184 	if (!IsRevertible())
185 		return;
186 
187 	BPath path;
188 	if (find_directory(B_USER_SETTINGS_DIRECTORY, &path) != B_OK)
189 		return;
190 
191 	path.Append("kernel/drivers");
192 	path.Append(kVirtualMemorySettings);
193 
194 	BFile file;
195 	if (file.SetTo(path.Path(), B_WRITE_ONLY | B_CREATE_FILE | B_ERASE_FILE)
196 		!= 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
213 
214 	file.Write(buffer, strlen(buffer));
215 }
216 
217 
218 void
219 Settings::_SetSwapNull()
220 {
221 	SetSwapEnabled(false);
222 	BVolumeRoster volumeRoster;
223 	BVolume temporaryVolume;
224 	volumeRoster.GetBootVolume(&temporaryVolume);
225 	SetSwapVolume(temporaryVolume);
226 	SetSwapSize(0);
227 }
228 
229 
230