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