xref: /haiku/src/servers/input/MouseSettings.cpp (revision 68d37cfb3a755a7270d772b505ee15c8b18aa5e0)
1 /*
2  * Copyright 2004-2009, Haiku, Inc. All rights reserved.
3  * Distributed under the terms of the MIT License.
4  *
5  * Authors:
6  *		Jérôme Duval
7  *		Andrew McCall (mccall@digitalparadise.co.uk)
8  *		Axel Dörfler, axeld@pinc-software.de
9  */
10 
11 
12 #include "MouseSettings.h"
13 
14 #include <stdio.h>
15 
16 #include <FindDirectory.h>
17 #include <File.h>
18 #include <Path.h>
19 #include <View.h>
20 
21 
22 static const bigtime_t kDefaultClickSpeed = 500000;
23 static const int32 kDefaultMouseSpeed = 65536;
24 static const int32 kDefaultMouseType = 3;	// 3 button mouse
25 static const int32 kDefaultAccelerationFactor = 65536;
26 static const bool kDefaultAcceptFirstClick = true;
27 
28 
29 
30 MouseSettings::MouseSettings()
31 {
32 	Defaults();
33 
34 #ifdef DEBUG
35 	Dump();
36 #endif
37 
38 	fOriginalSettings = fSettings;
39 	fOriginalMode = fMode;
40 	fOriginalFocusFollowsMouseMode = fFocusFollowsMouseMode;
41 	fOriginalAcceptFirstClick = fAcceptFirstClick;
42 }
43 
44 
45 MouseSettings::MouseSettings(mouse_settings* originalSettings)
46 {
47 	Defaults();
48 	fMode = mouse_mode();
49 	fAcceptFirstClick = accept_first_click();
50 
51 	fOriginalSettings = *originalSettings;
52 	fSettings = *originalSettings;
53 
54 #ifdef DEBUG
55 	Dump();
56 #endif
57 
58 	fOriginalMode = fMode;
59 	fOriginalFocusFollowsMouseMode = fFocusFollowsMouseMode;
60 	fOriginalAcceptFirstClick = fAcceptFirstClick;
61 }
62 
63 
64 MouseSettings::~MouseSettings()
65 {
66 }
67 
68 
69 status_t
70 MouseSettings::GetSettingsPath(BPath &path)
71 {
72 	status_t status = find_directory(B_USER_SETTINGS_DIRECTORY, &path);
73 	if (status < B_OK)
74 		return status;
75 
76 	path.Append(mouse_settings_file);
77 	return B_OK;
78 }
79 
80 
81 void
82 MouseSettings::RetrieveSettings()
83 {
84 	// retrieve current values
85 
86 	fMode = mouse_mode();
87 	fAcceptFirstClick = accept_first_click();
88 	Defaults();
89 
90 	// also try to load the window position from disk
91 
92 	BPath path;
93 	if (GetSettingsPath(path) < B_OK)
94 		return;
95 
96 	BFile file(path.Path(), B_READ_ONLY);
97 	if (file.InitCheck() < B_OK)
98 		return;
99 
100 	if (file.ReadAt(0, &fSettings, sizeof(mouse_settings))
101 			!= sizeof(mouse_settings)) {
102 		Defaults();
103 	}
104 
105 	if ((fSettings.click_speed == 0)
106 		|| (fSettings.type == 0)) {
107 		Defaults();
108 	}
109 }
110 
111 
112 #ifdef DEBUG
113 void
114 MouseSettings::Dump()
115 {
116 	printf("type:\t\t%" B_PRId32 " button mouse\n", fSettings.type);
117 	printf("map:\t\tleft = %" B_PRIu32 " : middle = %" B_PRIu32 " : "
118 		"right = %" B_PRIu32 "\n",
119 		fSettings.map.button[0], fSettings.map.button[2],
120 		fSettings.map.button[1]);
121 	printf("click speed:\t%" B_PRId64 "\n", fSettings.click_speed);
122 	printf("accel:\t\t%s\n", fSettings.accel.enabled
123 		? "enabled" : "disabled");
124 	printf("accel factor:\t%" B_PRId32 "\n", fSettings.accel.accel_factor);
125 	printf("speed:\t\t%" B_PRId32 "\n", fSettings.accel.speed);
126 
127 	const char *mode = "unknown";
128 	switch (fMode) {
129 		case B_NORMAL_MOUSE:
130 			mode = "activate";
131 			break;
132 		case B_CLICK_TO_FOCUS_MOUSE:
133 			mode = "focus";
134 			break;
135 		case B_FOCUS_FOLLOWS_MOUSE:
136 			mode = "auto-focus";
137 			break;
138 	}
139 	printf("mouse mode:\t%s\n", mode);
140 
141 	const char *focus_follows_mouse_mode = "unknown";
142 	switch (fFocusFollowsMouseMode) {
143 		case B_NORMAL_FOCUS_FOLLOWS_MOUSE:
144 			focus_follows_mouse_mode = "normal";
145 			break;
146 		case B_WARP_FOCUS_FOLLOWS_MOUSE:
147 			focus_follows_mouse_mode = "warp";
148 			break;
149 		case B_INSTANT_WARP_FOCUS_FOLLOWS_MOUSE:
150 			focus_follows_mouse_mode = "instant warp";
151 			break;
152 	}
153 	printf("focus follows mouse mode:\t%s\n", focus_follows_mouse_mode);
154 	printf("accept first click:\t%s\n", fAcceptFirstClick
155 		? "enabled" : "disabled");
156 }
157 #endif
158 
159 
160 /**	Resets the settings to the system defaults
161  */
162 
163 void
164 MouseSettings::Defaults()
165 {
166 	SetClickSpeed(kDefaultClickSpeed);
167 	SetMouseSpeed(kDefaultMouseSpeed);
168 	SetMouseType(kDefaultMouseType);
169 	SetAccelerationFactor(kDefaultAccelerationFactor);
170 	SetMouseMode(B_NORMAL_MOUSE);
171 	SetFocusFollowsMouseMode(B_NORMAL_FOCUS_FOLLOWS_MOUSE);
172 	SetAcceptFirstClick(kDefaultAcceptFirstClick);
173 
174 	for (int i = 0; i < B_MAX_MOUSE_BUTTONS; i++)
175 		fSettings.map.button[i] = B_MOUSE_BUTTON(i + 1);
176 }
177 
178 
179 void
180 MouseSettings::SetMouseType(int32 type)
181 {
182 	fSettings.type = type;
183 }
184 
185 
186 bigtime_t
187 MouseSettings::ClickSpeed() const
188 {
189 	return fSettings.click_speed;
190 }
191 
192 
193 void
194 MouseSettings::SetClickSpeed(bigtime_t clickSpeed)
195 {
196 	fSettings.click_speed = clickSpeed;
197 }
198 
199 
200 void
201 MouseSettings::SetMouseSpeed(int32 speed)
202 {
203 	fSettings.accel.speed = speed;
204 }
205 
206 
207 void
208 MouseSettings::SetAccelerationFactor(int32 factor)
209 {
210 	fSettings.accel.accel_factor = factor;
211 }
212 
213 
214 uint32
215 MouseSettings::Mapping(int32 index) const
216 {
217 	return fSettings.map.button[index];
218 }
219 
220 
221 void
222 MouseSettings::Mapping(mouse_map &map) const
223 {
224 	map = fSettings.map;
225 }
226 
227 
228 void
229 MouseSettings::SetMapping(int32 index, uint32 button)
230 {
231 	fSettings.map.button[index] = button;
232 }
233 
234 
235 void
236 MouseSettings::SetMapping(mouse_map &map)
237 {
238 	fSettings.map = map;
239 }
240 
241 
242 void
243 MouseSettings::SetMouseMode(mode_mouse mode)
244 {
245 	fMode = mode;
246 }
247 
248 
249 void
250 MouseSettings::SetFocusFollowsMouseMode(mode_focus_follows_mouse mode)
251 {
252 	fFocusFollowsMouseMode = mode;
253 }
254 
255 
256 void
257 MouseSettings::SetAcceptFirstClick(bool acceptFirstClick)
258 {
259 	fAcceptFirstClick = acceptFirstClick;
260 }
261 
262 
263 /* MultiMouseSettings functions */
264 
265 MultipleMouseSettings::MultipleMouseSettings()
266 {
267 	fDeprecatedMouseSettings = NULL;
268 	RetrieveSettings();
269 
270 #ifdef DEBUG
271 	Dump();
272 #endif
273 }
274 
275 
276 MultipleMouseSettings::~MultipleMouseSettings()
277 {
278 	SaveSettings();
279 
280 #ifdef DEBUG
281 	Dump();
282 #endif
283 
284 	std::map<BString, MouseSettings*>::iterator itr;
285 	for (itr = fMouseSettingsObject.begin(); itr != fMouseSettingsObject.end();
286 		++itr)
287 		delete itr->second;
288 
289 	delete fDeprecatedMouseSettings;
290 }
291 
292 
293 status_t
294 MultipleMouseSettings::GetSettingsPath(BPath &path)
295 {
296 	status_t status = find_directory(B_USER_SETTINGS_DIRECTORY, &path);
297 	if (status < B_OK)
298 		return status;
299 
300 	path.Append(mouse_settings_file);
301 	return B_OK;
302 }
303 
304 
305 void
306 MultipleMouseSettings::RetrieveSettings()
307 {
308 	BPath path;
309 	if (GetSettingsPath(path) < B_OK)
310 		return;
311 
312 	BFile file(path.Path(), B_READ_ONLY);
313 	if (file.InitCheck() < B_OK)
314 		return;
315 
316 	BMessage message;
317 
318 	if (message.Unflatten(&file) == B_OK) {
319 		int i = 0;
320 		BString deviceName;
321 		mouse_settings* settings;
322 		ssize_t size = 0;
323 
324 		while (message.FindString("mouseDevice", i, &deviceName) == B_OK) {
325 			message.FindData("mouseSettings", B_ANY_TYPE, i,
326 				(const void**)&settings, &size);
327 			MouseSettings* mouseSettings = new MouseSettings(settings);
328 			fMouseSettingsObject.insert(std::pair<BString, MouseSettings*>
329 				(deviceName, mouseSettings));
330 			i++;
331 		}
332 	} else {
333 		fDeprecatedMouseSettings = new MouseSettings();
334 		fDeprecatedMouseSettings->RetrieveSettings();
335 	}
336 }
337 
338 
339 status_t
340 MultipleMouseSettings::Archive(BMessage* into, bool deep) const
341 {
342 	std::map<BString, MouseSettings*>::const_iterator itr;
343 	for (itr = fMouseSettingsObject.begin(); itr != fMouseSettingsObject.end();
344 		++itr) {
345 		into->AddString("mouseDevice", itr->first);
346 		into->AddData("mouseSettings", B_ANY_TYPE, itr->second->GetSettings(),
347 			sizeof(*(itr->second->GetSettings())));
348 	}
349 
350 	return B_OK;
351 }
352 
353 
354 status_t
355 MultipleMouseSettings::SaveSettings()
356 {
357 	BPath path;
358 	status_t status = GetSettingsPath(path);
359 	if (status < B_OK)
360 		return status;
361 
362 	BFile file(path.Path(), B_WRITE_ONLY | B_CREATE_FILE | B_ERASE_FILE);
363 	status = file.InitCheck();
364 	if (status != B_OK)
365 		return status;
366 
367 	BMessage message;
368 	Archive(&message, true);
369 	message.Flatten(&file);
370 
371 	return B_OK;
372 }
373 
374 
375 void
376 MultipleMouseSettings::Defaults()
377 {
378 	std::map<BString, MouseSettings*>::iterator itr;
379 	for (itr = fMouseSettingsObject.begin(); itr != fMouseSettingsObject.end();
380 		++itr) {
381 		itr->second->Defaults();
382 	}
383 }
384 
385 
386 #ifdef DEBUG
387 void
388 MultipleMouseSettings::Dump()
389 {
390 	std::map<BString, MouseSettings*>::iterator itr;
391 	for (itr = fMouseSettingsObject.begin();
392 		itr != fMouseSettingsObject.end(); ++itr) {
393 		printf("mouse_name:\t%s\n", itr->first.String());
394 		itr->second->Dump();
395 		printf("\n");
396 	}
397 
398 }
399 #endif
400 
401 
402 MouseSettings*
403 MultipleMouseSettings::AddMouseSettings(BString mouse_name)
404 {
405 	if(fDeprecatedMouseSettings != NULL) {
406 		MouseSettings* RetrievedSettings = new (std::nothrow) MouseSettings
407 			(*fDeprecatedMouseSettings);
408 
409 		if (RetrievedSettings != NULL) {
410 			fMouseSettingsObject.insert(std::pair<BString, MouseSettings*>
411 				(mouse_name, RetrievedSettings));
412 
413 			return RetrievedSettings;
414 		}
415 	}
416 
417 	std::map<BString, MouseSettings*>::iterator itr;
418 	itr = fMouseSettingsObject.find(mouse_name);
419 
420 	if (itr != fMouseSettingsObject.end())
421 		return GetMouseSettings(mouse_name);
422 
423 	MouseSettings* settings = new (std::nothrow) MouseSettings();
424 
425 	if(settings != NULL) {
426 		fMouseSettingsObject.insert(std::pair<BString, MouseSettings*>
427 			(mouse_name, settings));
428 		return settings;
429 	}
430 	return NULL;
431 }
432 
433 
434 MouseSettings*
435 MultipleMouseSettings::GetMouseSettings(BString mouse_name)
436 {
437 	std::map<BString, MouseSettings*>::iterator itr;
438 	itr = fMouseSettingsObject.find(mouse_name);
439 
440 	if (itr != fMouseSettingsObject.end())
441 		return itr->second;
442 	return NULL;
443  }
444 
445