1 /* 2 * Copyright 2005-2008, Haiku. 3 * Distributed under the terms of the MIT License. 4 * 5 * Authors: 6 * Stephan Aßmus <superstippi@gmx.de> 7 * Axel Dörfler, axeld@pinc-software.de 8 */ 9 10 11 #include "DesktopSettings.h" 12 #include "DesktopSettingsPrivate.h" 13 #include "Desktop.h" 14 #include "FontManager.h" 15 #include "ServerConfig.h" 16 17 #include <DefaultColors.h> 18 #include <ServerReadOnlyMemory.h> 19 20 #include <Directory.h> 21 #include <File.h> 22 #include <FindDirectory.h> 23 #include <Path.h> 24 25 26 DesktopSettingsPrivate::DesktopSettingsPrivate(server_read_only_memory* shared) 27 : 28 fShared(*shared) 29 { 30 // if the on-disk settings are not complete, the defaults will be kept 31 _SetDefaults(); 32 _Load(); 33 } 34 35 36 DesktopSettingsPrivate::~DesktopSettingsPrivate() 37 { 38 } 39 40 41 void 42 DesktopSettingsPrivate::_SetDefaults() 43 { 44 fPlainFont = *gFontManager->DefaultPlainFont(); 45 fBoldFont = *gFontManager->DefaultBoldFont(); 46 fFixedFont = *gFontManager->DefaultFixedFont(); 47 48 fMouseMode = B_NORMAL_MOUSE; 49 fShowAllDraggers = true; 50 51 // init scrollbar info 52 fScrollBarInfo.proportional = true; 53 fScrollBarInfo.double_arrows = false; 54 fScrollBarInfo.knob = 1; 55 // look of the knob (R5: (0, 1, 2), 1 = default) 56 fScrollBarInfo.min_knob_size = 15; 57 58 // init menu info 59 strlcpy(fMenuInfo.f_family, fPlainFont.Family(), B_FONT_FAMILY_LENGTH); 60 strlcpy(fMenuInfo.f_style, fPlainFont.Style(), B_FONT_STYLE_LENGTH); 61 fMenuInfo.font_size = fPlainFont.Size(); 62 fMenuInfo.background_color.set_to(216, 216, 216); 63 64 fMenuInfo.separator = 0; 65 // look of the separator (R5: (0, 1, 2), default 0) 66 fMenuInfo.click_to_open = true; // always true 67 fMenuInfo.triggers_always_shown = false; 68 69 fWorkspacesCount = 4; 70 71 memcpy(fShared.colors, BPrivate::kDefaultColors, sizeof(rgb_color) * kNumColors); 72 } 73 74 75 status_t 76 DesktopSettingsPrivate::_GetPath(BPath& path) 77 { 78 status_t status = find_directory(B_USER_SETTINGS_DIRECTORY, &path); 79 if (status < B_OK) 80 return status; 81 82 status = path.Append("system/app_server"); 83 if (status < B_OK) 84 return status; 85 86 return create_directory(path.Path(), 0755); 87 } 88 89 90 status_t 91 DesktopSettingsPrivate::_Load() 92 { 93 // TODO: add support for old app_server_settings file as well 94 95 BPath basePath; 96 status_t status = _GetPath(basePath); 97 if (status < B_OK) 98 return status; 99 100 // read workspaces settings 101 102 BPath path(basePath); 103 path.Append("workspaces"); 104 105 BFile file; 106 status = file.SetTo(path.Path(), B_READ_ONLY); 107 if (status == B_OK) { 108 BMessage settings; 109 status = settings.Unflatten(&file); 110 if (status == B_OK) { 111 int32 count; 112 if (settings.FindInt32("count", &count) == B_OK) { 113 fWorkspacesCount = count; 114 if (fWorkspacesCount < 1 || fWorkspacesCount > 32) 115 fWorkspacesCount = 4; 116 } 117 118 int32 i = 0; 119 while (i < kMaxWorkspaces 120 && settings.FindMessage("workspace", i, &fWorkspaceMessages[i]) == B_OK) { 121 i++; 122 } 123 } 124 } 125 126 // read font settings 127 128 path = basePath; 129 path.Append("fonts"); 130 131 status = file.SetTo(path.Path(), B_READ_ONLY); 132 if (status == B_OK) { 133 BMessage settings; 134 status = settings.Unflatten(&file); 135 if (status == B_OK && gFontManager->Lock()) { 136 const char* family; 137 const char* style; 138 float size; 139 if (settings.FindString("plain family", &family) == B_OK 140 && settings.FindString("plain style", &style) == B_OK 141 && settings.FindFloat("plain size", &size) == B_OK) { 142 FontStyle* fontStyle = gFontManager->GetStyle(family, style); 143 fPlainFont.SetStyle(fontStyle); 144 fPlainFont.SetSize(size); 145 } 146 if (settings.FindString("bold family", &family) == B_OK 147 && settings.FindString("bold style", &style) == B_OK 148 && settings.FindFloat("bold size", &size) == B_OK) { 149 FontStyle* fontStyle = gFontManager->GetStyle(family, style); 150 fBoldFont.SetStyle(fontStyle); 151 fBoldFont.SetSize(size); 152 } 153 if (settings.FindString("fixed family", &family) == B_OK 154 && settings.FindString("fixed style", &style) == B_OK 155 && settings.FindFloat("fixed size", &size) == B_OK) { 156 FontStyle* fontStyle = gFontManager->GetStyle(family, style); 157 if (fontStyle->IsFixedWidth()) 158 fFixedFont.SetStyle(fontStyle); 159 fFixedFont.SetSize(size); 160 } 161 gFontManager->Unlock(); 162 } 163 } 164 165 // read mouse settings 166 167 path = basePath; 168 path.Append("mouse"); 169 170 status = file.SetTo(path.Path(), B_READ_ONLY); 171 if (status == B_OK) { 172 BMessage settings; 173 status = settings.Unflatten(&file); 174 if (status == B_OK) { 175 int32 mode; 176 if (settings.FindInt32("mode", &mode) == B_OK) { 177 fMouseMode = (mode_mouse)mode; 178 } 179 } 180 } 181 182 // read appearance settings 183 184 path = basePath; 185 path.Append("appearance"); 186 187 status = file.SetTo(path.Path(), B_READ_ONLY); 188 if (status == B_OK) { 189 BMessage settings; 190 status = settings.Unflatten(&file); 191 if (status == B_OK) { 192 float fontSize; 193 if (settings.FindFloat("font size", &fontSize) == B_OK) 194 fMenuInfo.font_size = fontSize; 195 196 const char* fontFamily; 197 if (settings.FindString("font family", &fontFamily) == B_OK) 198 strlcpy(fMenuInfo.f_family, fontFamily, B_FONT_FAMILY_LENGTH); 199 200 const char* fontStyle; 201 if (settings.FindString("font style", &fontStyle) == B_OK) 202 strlcpy(fMenuInfo.f_style, fontStyle, B_FONT_STYLE_LENGTH); 203 204 rgb_color bgColor; 205 if (settings.FindInt32("bg color", (int32*)&bgColor) == B_OK) 206 fMenuInfo.background_color = bgColor; 207 208 int32 separator; 209 if (settings.FindInt32("separator", &separator) == B_OK) 210 fMenuInfo.separator = separator; 211 212 bool clickToOpen; 213 if (settings.FindBool("click to open", &clickToOpen) == B_OK) 214 fMenuInfo.click_to_open = clickToOpen; 215 216 bool triggersAlwaysShown; 217 if (settings.FindBool("triggers always shown", &triggersAlwaysShown) == B_OK) 218 fMenuInfo.triggers_always_shown = triggersAlwaysShown; 219 220 for (int32 i = 0; i < kNumColors; i++) { 221 char colorName[12]; 222 snprintf(colorName, sizeof(colorName), "color%ld", 223 (int32)index_to_color_which(i)); 224 225 settings.FindInt32(colorName, (int32*)&fShared.colors[i]); 226 } 227 } 228 } 229 230 return B_OK; 231 } 232 233 234 status_t 235 DesktopSettingsPrivate::Save(uint32 mask) 236 { 237 BPath basePath; 238 status_t status = _GetPath(basePath); 239 if (status < B_OK) 240 return status; 241 242 if (mask & kWorkspacesSettings) { 243 BPath path(basePath); 244 if (path.Append("workspaces") == B_OK) { 245 BMessage settings('asws'); 246 settings.AddInt32("count", fWorkspacesCount); 247 248 for (int32 i = 0; i < kMaxWorkspaces; i++) { 249 settings.AddMessage("workspace", &fWorkspaceMessages[i]); 250 } 251 252 BFile file; 253 status = file.SetTo(path.Path(), B_CREATE_FILE | B_ERASE_FILE | B_READ_WRITE); 254 if (status == B_OK) { 255 status = settings.Flatten(&file, NULL); 256 } 257 } 258 } 259 260 if (mask & kFontSettings) { 261 BPath path(basePath); 262 if (path.Append("fonts") == B_OK) { 263 BMessage settings('asfn'); 264 265 settings.AddString("plain family", fPlainFont.Family()); 266 settings.AddString("plain style", fPlainFont.Style()); 267 settings.AddFloat("plain size", fPlainFont.Size()); 268 269 settings.AddString("bold family", fBoldFont.Family()); 270 settings.AddString("bold style", fBoldFont.Style()); 271 settings.AddFloat("bold size", fBoldFont.Size()); 272 273 settings.AddString("fixed family", fFixedFont.Family()); 274 settings.AddString("fixed style", fFixedFont.Style()); 275 settings.AddFloat("fixed size", fFixedFont.Size()); 276 277 BFile file; 278 status = file.SetTo(path.Path(), B_CREATE_FILE | B_ERASE_FILE | B_READ_WRITE); 279 if (status == B_OK) { 280 status = settings.Flatten(&file, NULL); 281 } 282 } 283 } 284 285 if (mask & kMouseSettings) { 286 BPath path(basePath); 287 if (path.Append("mouse") == B_OK) { 288 BMessage settings('asms'); 289 settings.AddInt32("mode", (int32)fMouseMode); 290 291 BFile file; 292 status = file.SetTo(path.Path(), B_CREATE_FILE | B_ERASE_FILE | B_READ_WRITE); 293 if (status == B_OK) { 294 status = settings.Flatten(&file, NULL); 295 } 296 } 297 } 298 299 if (mask & kDraggerSettings) { 300 BPath path(basePath); 301 if (path.Append("dragger") == B_OK) { 302 BMessage settings('asdg'); 303 settings.AddBool("show", fShowAllDraggers); 304 305 BFile file; 306 status = file.SetTo(path.Path(), B_CREATE_FILE | B_ERASE_FILE | B_READ_WRITE); 307 if (status == B_OK) { 308 status = settings.Flatten(&file, NULL); 309 } 310 } 311 } 312 313 if (mask & kAppearanceSettings) { 314 BPath path(basePath); 315 if (path.Append("appearance") == B_OK) { 316 BMessage settings('aslk'); 317 settings.AddFloat("font size", fMenuInfo.font_size); 318 settings.AddString("font family", fMenuInfo.f_family); 319 settings.AddString("font style", fMenuInfo.f_style); 320 settings.AddInt32("bg color", (const int32&)fMenuInfo.background_color); 321 settings.AddInt32("separator", fMenuInfo.separator); 322 settings.AddBool("click to open", fMenuInfo.click_to_open); 323 settings.AddBool("triggers always shown", fMenuInfo.triggers_always_shown); 324 325 for (int32 i = 0; i < kNumColors; i++) { 326 char colorName[12]; 327 snprintf(colorName, sizeof(colorName), "color%ld", 328 (int32)index_to_color_which(i)); 329 settings.AddInt32(colorName, (const int32&)fShared.colors[i]); 330 } 331 332 BFile file; 333 status = file.SetTo(path.Path(), B_CREATE_FILE | B_ERASE_FILE | B_READ_WRITE); 334 if (status == B_OK) { 335 status = settings.Flatten(&file, NULL); 336 } 337 } 338 } 339 340 return status; 341 } 342 343 344 void 345 DesktopSettingsPrivate::SetDefaultPlainFont(const ServerFont &font) 346 { 347 fPlainFont = font; 348 Save(kFontSettings); 349 } 350 351 352 const ServerFont & 353 DesktopSettingsPrivate::DefaultPlainFont() const 354 { 355 return fPlainFont; 356 } 357 358 359 void 360 DesktopSettingsPrivate::SetDefaultBoldFont(const ServerFont &font) 361 { 362 fBoldFont = font; 363 Save(kFontSettings); 364 } 365 366 367 const ServerFont & 368 DesktopSettingsPrivate::DefaultBoldFont() const 369 { 370 return fBoldFont; 371 } 372 373 374 void 375 DesktopSettingsPrivate::SetDefaultFixedFont(const ServerFont &font) 376 { 377 fFixedFont = font; 378 Save(kFontSettings); 379 } 380 381 382 const ServerFont & 383 DesktopSettingsPrivate::DefaultFixedFont() const 384 { 385 return fFixedFont; 386 } 387 388 389 void 390 DesktopSettingsPrivate::SetScrollBarInfo(const scroll_bar_info& info) 391 { 392 fScrollBarInfo = info; 393 Save(kAppearanceSettings); 394 } 395 396 397 const scroll_bar_info& 398 DesktopSettingsPrivate::ScrollBarInfo() const 399 { 400 return fScrollBarInfo; 401 } 402 403 404 void 405 DesktopSettingsPrivate::SetMenuInfo(const menu_info& info) 406 { 407 fMenuInfo = info; 408 // Also update the ui_color 409 SetUIColor(B_MENU_BACKGROUND_COLOR, info.background_color); 410 // SetUIColor already saves the settings 411 } 412 413 414 const menu_info& 415 DesktopSettingsPrivate::MenuInfo() const 416 { 417 return fMenuInfo; 418 } 419 420 421 void 422 DesktopSettingsPrivate::SetMouseMode(const mode_mouse mode) 423 { 424 fMouseMode = mode; 425 Save(kMouseSettings); 426 } 427 428 429 mode_mouse 430 DesktopSettingsPrivate::MouseMode() const 431 { 432 return fMouseMode; 433 } 434 435 436 bool 437 DesktopSettingsPrivate::FocusFollowsMouse() const 438 { 439 return MouseMode() != B_NORMAL_MOUSE; 440 } 441 442 443 void 444 DesktopSettingsPrivate::SetShowAllDraggers(bool show) 445 { 446 fShowAllDraggers = show; 447 Save(kDraggerSettings); 448 } 449 450 451 bool 452 DesktopSettingsPrivate::ShowAllDraggers() const 453 { 454 return fShowAllDraggers; 455 } 456 457 458 void 459 DesktopSettingsPrivate::SetWorkspacesCount(int32 number) 460 { 461 if (number < 1) 462 number = 1; 463 else if (number > kMaxWorkspaces) 464 number = kMaxWorkspaces; 465 466 fWorkspacesCount = number; 467 } 468 469 470 int32 471 DesktopSettingsPrivate::WorkspacesCount() const 472 { 473 return fWorkspacesCount; 474 } 475 476 477 void 478 DesktopSettingsPrivate::SetWorkspacesMessage(int32 index, BMessage& message) 479 { 480 if (index < 0 || index > kMaxWorkspaces) 481 return; 482 483 fWorkspaceMessages[index] = message; 484 } 485 486 487 const BMessage* 488 DesktopSettingsPrivate::WorkspacesMessage(int32 index) const 489 { 490 if (index < 0 || index > kMaxWorkspaces) 491 return NULL; 492 493 return &fWorkspaceMessages[index]; 494 } 495 496 497 void 498 DesktopSettingsPrivate::SetUIColor(color_which which, const rgb_color color) 499 { 500 // 501 int32 index = color_which_to_index(which); 502 if (index < 0 || index >= kNumColors) 503 return; 504 fShared.colors[index] = color; 505 // TODO: deprecate the background_color member of the menu_info struct, 506 // otherwise we have to keep this duplication... 507 if (which == B_MENU_BACKGROUND_COLOR) 508 fMenuInfo.background_color = color; 509 Save(kAppearanceSettings); 510 } 511 512 513 rgb_color 514 DesktopSettingsPrivate::UIColor(color_which which) const 515 { 516 static const rgb_color invalidColor = {0, 0, 0, 0}; 517 int32 index = color_which_to_index(which); 518 if (index < 0 || index >= kNumColors) 519 return invalidColor; 520 return fShared.colors[index]; 521 } 522 523 524 // #pragma mark - read access 525 526 527 DesktopSettings::DesktopSettings(Desktop* desktop) 528 : 529 fSettings(desktop->fSettings) 530 { 531 #if DEBUG 532 if (!desktop->fWindowLock.IsWriteLocked() 533 && !desktop->fWindowLock.IsReadLocked()) 534 debugger("desktop not locked when trying to access settings"); 535 #endif 536 } 537 538 539 void 540 DesktopSettings::GetDefaultPlainFont(ServerFont &font) const 541 { 542 font = fSettings->DefaultPlainFont(); 543 } 544 545 546 void 547 DesktopSettings::GetDefaultBoldFont(ServerFont &font) const 548 { 549 font = fSettings->DefaultBoldFont(); 550 } 551 552 553 void 554 DesktopSettings::GetDefaultFixedFont(ServerFont &font) const 555 { 556 font = fSettings->DefaultFixedFont(); 557 } 558 559 560 void 561 DesktopSettings::GetScrollBarInfo(scroll_bar_info& info) const 562 { 563 info = fSettings->ScrollBarInfo(); 564 } 565 566 567 void 568 DesktopSettings::GetMenuInfo(menu_info& info) const 569 { 570 info = fSettings->MenuInfo(); 571 } 572 573 574 mode_mouse 575 DesktopSettings::MouseMode() const 576 { 577 return fSettings->MouseMode(); 578 } 579 580 581 bool 582 DesktopSettings::FocusFollowsMouse() const 583 { 584 return fSettings->FocusFollowsMouse(); 585 } 586 587 588 bool 589 DesktopSettings::ShowAllDraggers() const 590 { 591 return fSettings->ShowAllDraggers(); 592 } 593 594 595 int32 596 DesktopSettings::WorkspacesCount() const 597 { 598 return fSettings->WorkspacesCount(); 599 } 600 601 602 const BMessage* 603 DesktopSettings::WorkspacesMessage(int32 index) const 604 { 605 return fSettings->WorkspacesMessage(index); 606 } 607 608 609 rgb_color 610 DesktopSettings::UIColor(color_which which) const 611 { 612 return fSettings->UIColor(which); 613 } 614 615 616 // #pragma mark - write access 617 618 619 LockedDesktopSettings::LockedDesktopSettings(Desktop* desktop) 620 : DesktopSettings(desktop), 621 fDesktop(desktop) 622 { 623 #if DEBUG 624 if (desktop->fWindowLock.IsReadLocked()) 625 debugger("desktop read locked when trying to change settings"); 626 #endif 627 628 fDesktop->LockAllWindows(); 629 } 630 631 632 LockedDesktopSettings::~LockedDesktopSettings() 633 { 634 fDesktop->UnlockAllWindows(); 635 } 636 637 638 void 639 LockedDesktopSettings::SetDefaultPlainFont(const ServerFont &font) 640 { 641 fSettings->SetDefaultPlainFont(font); 642 } 643 644 645 void 646 LockedDesktopSettings::SetDefaultBoldFont(const ServerFont &font) 647 { 648 fSettings->SetDefaultBoldFont(font); 649 } 650 651 652 void 653 LockedDesktopSettings::SetDefaultFixedFont(const ServerFont &font) 654 { 655 fSettings->SetDefaultFixedFont(font); 656 } 657 658 659 void 660 LockedDesktopSettings::SetScrollBarInfo(const scroll_bar_info& info) 661 { 662 fSettings->SetScrollBarInfo(info); 663 } 664 665 666 void 667 LockedDesktopSettings::SetMenuInfo(const menu_info& info) 668 { 669 fSettings->SetMenuInfo(info); 670 } 671 672 673 void 674 LockedDesktopSettings::SetMouseMode(const mode_mouse mode) 675 { 676 fSettings->SetMouseMode(mode); 677 } 678 679 680 void 681 LockedDesktopSettings::SetShowAllDraggers(bool show) 682 { 683 fSettings->SetShowAllDraggers(show); 684 } 685 686 687 void 688 LockedDesktopSettings::SetUIColor(color_which which, const rgb_color color) 689 { 690 fSettings->SetUIColor(which, color); 691 } 692 693 694