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