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
MouseSettings()22 MouseSettings::MouseSettings()
23 {
24 Defaults();
25
26 #ifdef DEBUG
27 Dump();
28 #endif
29 }
30
31
MouseSettings(const mouse_settings * originalSettings)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
~MouseSettings()54 MouseSettings::~MouseSettings()
55 {
56 }
57
58
59 #ifdef DEBUG
60 void
Dump()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
Defaults()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
SetMouseType(int32 type)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
ClickSpeed() const137 MouseSettings::ClickSpeed() const
138 {
139 return fSettings.click_speed;
140 }
141
142
143 void
SetClickSpeed(bigtime_t clickSpeed)144 MouseSettings::SetClickSpeed(bigtime_t clickSpeed)
145 {
146 fSettings.click_speed = clickSpeed;
147 }
148
149
150 void
SetMouseSpeed(int32 speed)151 MouseSettings::SetMouseSpeed(int32 speed)
152 {
153 fSettings.accel.speed = speed;
154 }
155
156
157 void
SetAccelerationFactor(int32 factor)158 MouseSettings::SetAccelerationFactor(int32 factor)
159 {
160 fSettings.accel.accel_factor = factor;
161 }
162
163
164 uint32
Mapping(int32 index) const165 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
Mapping(mouse_map & map) const175 MouseSettings::Mapping(mouse_map &map) const
176 {
177 map = fSettings.map;
178 }
179
180
181 void
SetMapping(int32 index,uint32 button)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
SetMapping(mouse_map & map)193 MouseSettings::SetMapping(mouse_map &map)
194 {
195 fSettings.map = map;
196 _AssureValidMapping();
197 }
198
199
200 void
_AssureValidMapping()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
SetMouseMode(mode_mouse mode)217 MouseSettings::SetMouseMode(mode_mouse mode)
218 {
219 fMode = mode;
220 }
221
222
223 void
SetFocusFollowsMouseMode(mode_focus_follows_mouse mode)224 MouseSettings::SetFocusFollowsMouseMode(mode_focus_follows_mouse mode)
225 {
226 fFocusFollowsMouseMode = mode;
227 }
228
229
230 void
SetAcceptFirstClick(bool acceptFirstClick)231 MouseSettings::SetAcceptFirstClick(bool acceptFirstClick)
232 {
233 fAcceptFirstClick = acceptFirstClick;
234 }
235
236
237 /* MultiMouseSettings functions */
238
MultipleMouseSettings()239 MultipleMouseSettings::MultipleMouseSettings()
240 {
241 RetrieveSettings();
242
243 #ifdef DEBUG
244 Dump();
245 #endif
246 }
247
248
~MultipleMouseSettings()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
GetSettingsPath(BPath & path)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
RetrieveSettings()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
Archive(BMessage * into,bool deep) const307 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
SaveSettings()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
Defaults()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
Dump()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*
AddMouseSettings(BString mouse_name)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*
GetMouseSettings(BString mouse_name)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