1 /* 2 * Copyright 2005-2006, 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 DesktopSettings::Private::Private(server_read_only_memory* shared) 27 : BLocker("DesktopSettings_Private"), 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 DesktopSettings::Private::~Private() 37 { 38 } 39 40 41 void 42 DesktopSettings::Private::_SetDefaults() 43 { 44 fPlainFont = *gFontManager->DefaultPlainFont(); 45 fBoldFont = *gFontManager->DefaultBoldFont(); 46 fFixedFont = *gFontManager->DefaultFixedFont(); 47 48 fMouseMode = B_NORMAL_MOUSE; 49 50 // init scrollbar info 51 fScrollBarInfo.proportional = true; 52 fScrollBarInfo.double_arrows = false; 53 // look of the knob (R5: (0, 1, 2), 1 = default) 54 fScrollBarInfo.knob = 1; 55 fScrollBarInfo.min_knob_size = 15; 56 57 // init menu info 58 strlcpy(fMenuInfo.f_family, fPlainFont.Family(), B_FONT_FAMILY_LENGTH); 59 strlcpy(fMenuInfo.f_style, fPlainFont.Style(), B_FONT_STYLE_LENGTH); 60 fMenuInfo.font_size = fPlainFont.Size(); 61 fMenuInfo.background_color.set_to(216, 216, 216); 62 63 // look of the separator (R5: (0, 1, 2), default 0) 64 // TODO: we could just choose a nice one and remove the others 65 fMenuInfo.separator = 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 DesktopSettings::Private::_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 DesktopSettings::Private::_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 DesktopSettings::Private::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 & kAppearanceSettings) { 292 BPath path(basePath); 293 if (path.Append("appearance") == B_OK) { 294 BMessage settings('aslk'); 295 settings.AddFloat("font size", fMenuInfo.font_size); 296 settings.AddString("font family", fMenuInfo.f_family); 297 settings.AddString("font style", fMenuInfo.f_style); 298 settings.AddInt32("bg color", (const int32&)fMenuInfo.background_color); 299 settings.AddInt32("separator", fMenuInfo.separator); 300 settings.AddBool("click to open", fMenuInfo.click_to_open); 301 settings.AddBool("triggers always shown", fMenuInfo.triggers_always_shown); 302 // TODO: more appearance settings 303 304 BFile file; 305 status = file.SetTo(path.Path(), B_CREATE_FILE | B_ERASE_FILE | B_READ_WRITE); 306 if (status == B_OK) { 307 status = settings.Flatten(&file, NULL); 308 } 309 } 310 } 311 312 return status; 313 } 314 315 316 void 317 DesktopSettings::Private::SetDefaultPlainFont(const ServerFont &font) 318 { 319 fPlainFont = font; 320 Save(kFontSettings); 321 } 322 323 324 const ServerFont & 325 DesktopSettings::Private::DefaultPlainFont() const 326 { 327 return fPlainFont; 328 } 329 330 331 void 332 DesktopSettings::Private::SetDefaultBoldFont(const ServerFont &font) 333 { 334 fBoldFont = font; 335 Save(kFontSettings); 336 } 337 338 339 const ServerFont & 340 DesktopSettings::Private::DefaultBoldFont() const 341 { 342 return fBoldFont; 343 } 344 345 346 void 347 DesktopSettings::Private::SetDefaultFixedFont(const ServerFont &font) 348 { 349 fFixedFont = font; 350 Save(kFontSettings); 351 } 352 353 354 const ServerFont & 355 DesktopSettings::Private::DefaultFixedFont() const 356 { 357 return fFixedFont; 358 } 359 360 361 void 362 DesktopSettings::Private::SetScrollBarInfo(const scroll_bar_info& info) 363 { 364 fScrollBarInfo = info; 365 Save(kAppearanceSettings); 366 } 367 368 369 const scroll_bar_info& 370 DesktopSettings::Private::ScrollBarInfo() const 371 { 372 return fScrollBarInfo; 373 } 374 375 376 void 377 DesktopSettings::Private::SetMenuInfo(const menu_info& info) 378 { 379 fMenuInfo = info; 380 Save(kAppearanceSettings); 381 } 382 383 384 const menu_info& 385 DesktopSettings::Private::MenuInfo() const 386 { 387 return fMenuInfo; 388 } 389 390 391 void 392 DesktopSettings::Private::SetMouseMode(const mode_mouse mode) 393 { 394 fMouseMode = mode; 395 Save(kMouseSettings); 396 } 397 398 399 mode_mouse 400 DesktopSettings::Private::MouseMode() const 401 { 402 return fMouseMode; 403 } 404 405 406 bool 407 DesktopSettings::Private::FocusFollowsMouse() const 408 { 409 return MouseMode() != B_NORMAL_MOUSE; 410 } 411 412 413 void 414 DesktopSettings::Private::SetWorkspacesCount(int32 number) 415 { 416 if (number < 1) 417 number = 1; 418 else if (number > kMaxWorkspaces) 419 number = kMaxWorkspaces; 420 421 fWorkspacesCount = number; 422 } 423 424 425 int32 426 DesktopSettings::Private::WorkspacesCount() const 427 { 428 return fWorkspacesCount; 429 } 430 431 432 void 433 DesktopSettings::Private::SetWorkspacesMessage(int32 index, BMessage& message) 434 { 435 if (index < 0 || index > kMaxWorkspaces) 436 return; 437 438 fWorkspaceMessages[index] = message; 439 } 440 441 442 const BMessage* 443 DesktopSettings::Private::WorkspacesMessage(int32 index) const 444 { 445 if (index < 0 || index > kMaxWorkspaces) 446 return NULL; 447 448 return &fWorkspaceMessages[index]; 449 } 450 451 452 453 // #pragma mark - 454 455 456 DesktopSettings::DesktopSettings(Desktop* desktop) 457 { 458 fSettings = desktop->fSettings; 459 fSettings->Lock(); 460 } 461 462 463 DesktopSettings::~DesktopSettings() 464 { 465 fSettings->Unlock(); 466 } 467 468 469 void 470 DesktopSettings::SetDefaultPlainFont(const ServerFont &font) 471 { 472 fSettings->SetDefaultPlainFont(font); 473 } 474 475 476 void 477 DesktopSettings::GetDefaultPlainFont(ServerFont &font) const 478 { 479 font = fSettings->DefaultPlainFont(); 480 } 481 482 483 void 484 DesktopSettings::SetDefaultBoldFont(const ServerFont &font) 485 { 486 fSettings->SetDefaultBoldFont(font); 487 } 488 489 490 void 491 DesktopSettings::GetDefaultBoldFont(ServerFont &font) const 492 { 493 font = fSettings->DefaultBoldFont(); 494 } 495 496 497 void 498 DesktopSettings::SetDefaultFixedFont(const ServerFont &font) 499 { 500 fSettings->SetDefaultFixedFont(font); 501 } 502 503 504 void 505 DesktopSettings::GetDefaultFixedFont(ServerFont &font) const 506 { 507 font = fSettings->DefaultFixedFont(); 508 } 509 510 511 void 512 DesktopSettings::SetScrollBarInfo(const scroll_bar_info& info) 513 { 514 fSettings->SetScrollBarInfo(info); 515 } 516 517 518 void 519 DesktopSettings::GetScrollBarInfo(scroll_bar_info& info) const 520 { 521 info = fSettings->ScrollBarInfo(); 522 } 523 524 525 void 526 DesktopSettings::SetMenuInfo(const menu_info& info) 527 { 528 fSettings->SetMenuInfo(info); 529 } 530 531 532 void 533 DesktopSettings::GetMenuInfo(menu_info& info) const 534 { 535 info = fSettings->MenuInfo(); 536 } 537 538 539 void 540 DesktopSettings::SetMouseMode(const mode_mouse mode) 541 { 542 fSettings->SetMouseMode(mode); 543 } 544 545 546 mode_mouse 547 DesktopSettings::MouseMode() const 548 { 549 return fSettings->MouseMode(); 550 } 551 552 553 bool 554 DesktopSettings::FocusFollowsMouse() const 555 { 556 return fSettings->FocusFollowsMouse(); 557 } 558 559 560 void 561 DesktopSettings::SetWorkspacesCount(int32 number) 562 { 563 fSettings->SetWorkspacesCount(number); 564 } 565 566 567 int32 568 DesktopSettings::WorkspacesCount() const 569 { 570 return fSettings->WorkspacesCount(); 571 } 572 573 574 void 575 DesktopSettings::SetWorkspacesMessage(int32 index, BMessage& message) 576 { 577 fSettings->SetWorkspacesMessage(index, message); 578 } 579 580 581 const BMessage* 582 DesktopSettings::WorkspacesMessage(int32 index) const 583 { 584 return fSettings->WorkspacesMessage(index); 585 } 586 587