1 /* 2 * Copyright 2005-2007, 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 } 221 222 return B_OK; 223 } 224 225 226 status_t 227 DesktopSettingsPrivate::Save(uint32 mask) 228 { 229 BPath basePath; 230 status_t status = _GetPath(basePath); 231 if (status < B_OK) 232 return status; 233 234 if (mask & kWorkspacesSettings) { 235 BPath path(basePath); 236 if (path.Append("workspaces") == B_OK) { 237 BMessage settings('asws'); 238 settings.AddInt32("count", fWorkspacesCount); 239 240 for (int32 i = 0; i < kMaxWorkspaces; i++) { 241 settings.AddMessage("workspace", &fWorkspaceMessages[i]); 242 } 243 244 BFile file; 245 status = file.SetTo(path.Path(), B_CREATE_FILE | B_ERASE_FILE | B_READ_WRITE); 246 if (status == B_OK) { 247 status = settings.Flatten(&file, NULL); 248 } 249 } 250 } 251 252 if (mask & kFontSettings) { 253 BPath path(basePath); 254 if (path.Append("fonts") == B_OK) { 255 BMessage settings('asfn'); 256 257 settings.AddString("plain family", fPlainFont.Family()); 258 settings.AddString("plain style", fPlainFont.Style()); 259 settings.AddFloat("plain size", fPlainFont.Size()); 260 261 settings.AddString("bold family", fBoldFont.Family()); 262 settings.AddString("bold style", fBoldFont.Style()); 263 settings.AddFloat("bold size", fBoldFont.Size()); 264 265 settings.AddString("fixed family", fFixedFont.Family()); 266 settings.AddString("fixed style", fFixedFont.Style()); 267 settings.AddFloat("fixed size", fFixedFont.Size()); 268 269 BFile file; 270 status = file.SetTo(path.Path(), B_CREATE_FILE | B_ERASE_FILE | B_READ_WRITE); 271 if (status == B_OK) { 272 status = settings.Flatten(&file, NULL); 273 } 274 } 275 } 276 277 if (mask & kMouseSettings) { 278 BPath path(basePath); 279 if (path.Append("mouse") == B_OK) { 280 BMessage settings('asms'); 281 settings.AddInt32("mode", (int32)fMouseMode); 282 283 BFile file; 284 status = file.SetTo(path.Path(), B_CREATE_FILE | B_ERASE_FILE | B_READ_WRITE); 285 if (status == B_OK) { 286 status = settings.Flatten(&file, NULL); 287 } 288 } 289 } 290 291 if (mask & kDraggerSettings) { 292 BPath path(basePath); 293 if (path.Append("dragger") == B_OK) { 294 BMessage settings('asdg'); 295 settings.AddBool("show", fShowAllDraggers); 296 297 BFile file; 298 status = file.SetTo(path.Path(), B_CREATE_FILE | B_ERASE_FILE | B_READ_WRITE); 299 if (status == B_OK) { 300 status = settings.Flatten(&file, NULL); 301 } 302 } 303 } 304 305 if (mask & kAppearanceSettings) { 306 BPath path(basePath); 307 if (path.Append("appearance") == B_OK) { 308 BMessage settings('aslk'); 309 settings.AddFloat("font size", fMenuInfo.font_size); 310 settings.AddString("font family", fMenuInfo.f_family); 311 settings.AddString("font style", fMenuInfo.f_style); 312 settings.AddInt32("bg color", (const int32&)fMenuInfo.background_color); 313 settings.AddInt32("separator", fMenuInfo.separator); 314 settings.AddBool("click to open", fMenuInfo.click_to_open); 315 settings.AddBool("triggers always shown", fMenuInfo.triggers_always_shown); 316 // TODO: more appearance settings 317 318 BFile file; 319 status = file.SetTo(path.Path(), B_CREATE_FILE | B_ERASE_FILE | B_READ_WRITE); 320 if (status == B_OK) { 321 status = settings.Flatten(&file, NULL); 322 } 323 } 324 } 325 326 return status; 327 } 328 329 330 void 331 DesktopSettingsPrivate::SetDefaultPlainFont(const ServerFont &font) 332 { 333 fPlainFont = font; 334 Save(kFontSettings); 335 } 336 337 338 const ServerFont & 339 DesktopSettingsPrivate::DefaultPlainFont() const 340 { 341 return fPlainFont; 342 } 343 344 345 void 346 DesktopSettingsPrivate::SetDefaultBoldFont(const ServerFont &font) 347 { 348 fBoldFont = font; 349 Save(kFontSettings); 350 } 351 352 353 const ServerFont & 354 DesktopSettingsPrivate::DefaultBoldFont() const 355 { 356 return fBoldFont; 357 } 358 359 360 void 361 DesktopSettingsPrivate::SetDefaultFixedFont(const ServerFont &font) 362 { 363 fFixedFont = font; 364 Save(kFontSettings); 365 } 366 367 368 const ServerFont & 369 DesktopSettingsPrivate::DefaultFixedFont() const 370 { 371 return fFixedFont; 372 } 373 374 375 void 376 DesktopSettingsPrivate::SetScrollBarInfo(const scroll_bar_info& info) 377 { 378 fScrollBarInfo = info; 379 Save(kAppearanceSettings); 380 } 381 382 383 const scroll_bar_info& 384 DesktopSettingsPrivate::ScrollBarInfo() const 385 { 386 return fScrollBarInfo; 387 } 388 389 390 void 391 DesktopSettingsPrivate::SetMenuInfo(const menu_info& info) 392 { 393 fMenuInfo = info; 394 Save(kAppearanceSettings); 395 } 396 397 398 const menu_info& 399 DesktopSettingsPrivate::MenuInfo() const 400 { 401 return fMenuInfo; 402 } 403 404 405 void 406 DesktopSettingsPrivate::SetMouseMode(const mode_mouse mode) 407 { 408 fMouseMode = mode; 409 Save(kMouseSettings); 410 } 411 412 413 mode_mouse 414 DesktopSettingsPrivate::MouseMode() const 415 { 416 return fMouseMode; 417 } 418 419 420 bool 421 DesktopSettingsPrivate::FocusFollowsMouse() const 422 { 423 return MouseMode() != B_NORMAL_MOUSE; 424 } 425 426 427 void 428 DesktopSettingsPrivate::SetShowAllDraggers(bool show) 429 { 430 fShowAllDraggers = show; 431 Save(kDraggerSettings); 432 } 433 434 435 bool 436 DesktopSettingsPrivate::ShowAllDraggers() const 437 { 438 return fShowAllDraggers; 439 } 440 441 442 void 443 DesktopSettingsPrivate::SetWorkspacesCount(int32 number) 444 { 445 if (number < 1) 446 number = 1; 447 else if (number > kMaxWorkspaces) 448 number = kMaxWorkspaces; 449 450 fWorkspacesCount = number; 451 } 452 453 454 int32 455 DesktopSettingsPrivate::WorkspacesCount() const 456 { 457 return fWorkspacesCount; 458 } 459 460 461 void 462 DesktopSettingsPrivate::SetWorkspacesMessage(int32 index, BMessage& message) 463 { 464 if (index < 0 || index > kMaxWorkspaces) 465 return; 466 467 fWorkspaceMessages[index] = message; 468 } 469 470 471 const BMessage* 472 DesktopSettingsPrivate::WorkspacesMessage(int32 index) const 473 { 474 if (index < 0 || index > kMaxWorkspaces) 475 return NULL; 476 477 return &fWorkspaceMessages[index]; 478 } 479 480 481 // #pragma mark - read access 482 483 484 DesktopSettings::DesktopSettings(Desktop* desktop) 485 : 486 fSettings(desktop->fSettings) 487 { 488 #if DEBUG 489 if (!desktop->fWindowLock.IsWriteLocked() 490 && !desktop->fWindowLock.IsReadLocked()) 491 debugger("desktop not locked when trying to access settings"); 492 #endif 493 } 494 495 496 void 497 DesktopSettings::GetDefaultPlainFont(ServerFont &font) const 498 { 499 font = fSettings->DefaultPlainFont(); 500 } 501 502 503 void 504 DesktopSettings::GetDefaultBoldFont(ServerFont &font) const 505 { 506 font = fSettings->DefaultBoldFont(); 507 } 508 509 510 void 511 DesktopSettings::GetDefaultFixedFont(ServerFont &font) const 512 { 513 font = fSettings->DefaultFixedFont(); 514 } 515 516 517 void 518 DesktopSettings::GetScrollBarInfo(scroll_bar_info& info) const 519 { 520 info = fSettings->ScrollBarInfo(); 521 } 522 523 524 void 525 DesktopSettings::GetMenuInfo(menu_info& info) const 526 { 527 info = fSettings->MenuInfo(); 528 } 529 530 531 mode_mouse 532 DesktopSettings::MouseMode() const 533 { 534 return fSettings->MouseMode(); 535 } 536 537 538 bool 539 DesktopSettings::FocusFollowsMouse() const 540 { 541 return fSettings->FocusFollowsMouse(); 542 } 543 544 545 bool 546 DesktopSettings::ShowAllDraggers() const 547 { 548 return fSettings->ShowAllDraggers(); 549 } 550 551 552 int32 553 DesktopSettings::WorkspacesCount() const 554 { 555 return fSettings->WorkspacesCount(); 556 } 557 558 559 const BMessage* 560 DesktopSettings::WorkspacesMessage(int32 index) const 561 { 562 return fSettings->WorkspacesMessage(index); 563 } 564 565 566 // #pragma mark - write access 567 568 569 LockedDesktopSettings::LockedDesktopSettings(Desktop* desktop) 570 : DesktopSettings(desktop), 571 fDesktop(desktop) 572 { 573 #if DEBUG 574 if (desktop->fWindowLock.IsReadLocked()) 575 debugger("desktop read locked when trying to change settings"); 576 #endif 577 578 fDesktop->LockAllWindows(); 579 } 580 581 582 LockedDesktopSettings::~LockedDesktopSettings() 583 { 584 fDesktop->UnlockAllWindows(); 585 } 586 587 588 void 589 LockedDesktopSettings::SetDefaultPlainFont(const ServerFont &font) 590 { 591 fSettings->SetDefaultPlainFont(font); 592 } 593 594 595 void 596 LockedDesktopSettings::SetDefaultBoldFont(const ServerFont &font) 597 { 598 fSettings->SetDefaultBoldFont(font); 599 } 600 601 602 void 603 LockedDesktopSettings::SetDefaultFixedFont(const ServerFont &font) 604 { 605 fSettings->SetDefaultFixedFont(font); 606 } 607 608 609 void 610 LockedDesktopSettings::SetScrollBarInfo(const scroll_bar_info& info) 611 { 612 fSettings->SetScrollBarInfo(info); 613 } 614 615 616 void 617 LockedDesktopSettings::SetMenuInfo(const menu_info& info) 618 { 619 fSettings->SetMenuInfo(info); 620 } 621 622 623 void 624 LockedDesktopSettings::SetMouseMode(const mode_mouse mode) 625 { 626 fSettings->SetMouseMode(mode); 627 } 628 629 630 void 631 LockedDesktopSettings::SetShowAllDraggers(bool show) 632 { 633 fSettings->SetShowAllDraggers(show); 634 } 635 636