xref: /haiku/src/servers/app/DesktopSettings.cpp (revision db6fcb750a1afb5fdc752322972adf6044d3b4c4)
1 /*
2  * Copyright 2005-2015, 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  *		Andrej Spielmann, <andrej.spielmann@seh.ox.ac.uk>
9  *		Joseph Groover <looncraz@looncraz.net>
10  */
11 
12 
13 #include "DesktopSettings.h"
14 #include "DesktopSettingsPrivate.h"
15 
16 #include <Directory.h>
17 #include <File.h>
18 #include <FindDirectory.h>
19 #include <Path.h>
20 
21 #include <DefaultColors.h>
22 #include <InterfaceDefs.h>
23 #include <ServerReadOnlyMemory.h>
24 
25 #include "Desktop.h"
26 #include "FontCache.h"
27 #include "FontCacheEntry.h"
28 #include "FontManager.h"
29 #include "GlobalSubpixelSettings.h"
30 #include "ServerConfig.h"
31 
32 
33 DesktopSettingsPrivate::DesktopSettingsPrivate(server_read_only_memory* shared)
34 	:
35 	fShared(*shared)
36 {
37 	// if the on-disk settings are not complete, the defaults will be kept
38 	_SetDefaults();
39 	_Load();
40 }
41 
42 
43 DesktopSettingsPrivate::~DesktopSettingsPrivate()
44 {
45 }
46 
47 
48 void
49 DesktopSettingsPrivate::_SetDefaults()
50 {
51 	fPlainFont = *gFontManager->DefaultPlainFont();
52 	fBoldFont = *gFontManager->DefaultBoldFont();
53 	fFixedFont = *gFontManager->DefaultFixedFont();
54 
55 	fMouseMode = B_NORMAL_MOUSE;
56 	fFocusFollowsMouseMode = B_NORMAL_FOCUS_FOLLOWS_MOUSE;
57 	fAcceptFirstClick = false;
58 	fShowAllDraggers = true;
59 
60 	// init scrollbar info
61 	fScrollBarInfo.proportional = true;
62 	fScrollBarInfo.double_arrows = false;
63 	fScrollBarInfo.knob = 0;
64 		// look of the knob (R5: (0, 1, 2), 1 = default)
65 		// change default = 0 (no knob) in Haiku
66 	fScrollBarInfo.min_knob_size = 15;
67 
68 	// init menu info
69 	strlcpy(fMenuInfo.f_family, fPlainFont.Family(), B_FONT_FAMILY_LENGTH);
70 	strlcpy(fMenuInfo.f_style, fPlainFont.Style(), B_FONT_STYLE_LENGTH);
71 	fMenuInfo.font_size = fPlainFont.Size();
72 	fMenuInfo.background_color.set_to(216, 216, 216);
73 
74 	fMenuInfo.separator = 0;
75 		// look of the separator (R5: (0, 1, 2), default 0)
76 	fMenuInfo.click_to_open = true; // always true
77 	fMenuInfo.triggers_always_shown = false;
78 
79 	fWorkspacesColumns = 2;
80 	fWorkspacesRows = 2;
81 
82 	memcpy(fShared.colors, BPrivate::kDefaultColors,
83 		sizeof(rgb_color) * kColorWhichCount);
84 
85 	gSubpixelAntialiasing = true;
86 	gDefaultHintingMode = HINTING_MODE_ON;
87 	gSubpixelAverageWeight = 120;
88 	gSubpixelOrderingRGB = true;
89 }
90 
91 
92 status_t
93 DesktopSettingsPrivate::_GetPath(BPath& path)
94 {
95 	status_t status = find_directory(B_USER_SETTINGS_DIRECTORY, &path);
96 	if (status < B_OK)
97 		return status;
98 
99 	status = path.Append("system/app_server");
100 	if (status < B_OK)
101 		return status;
102 
103 	return create_directory(path.Path(), 0755);
104 }
105 
106 
107 status_t
108 DesktopSettingsPrivate::_Load()
109 {
110 	// TODO: add support for old app_server_settings file as well
111 
112 	BPath basePath;
113 	status_t status = _GetPath(basePath);
114 	if (status < B_OK)
115 		return status;
116 
117 	// read workspaces settings
118 
119 	BPath path(basePath);
120 	path.Append("workspaces");
121 
122 	BFile file;
123 	status = file.SetTo(path.Path(), B_READ_ONLY);
124 	if (status == B_OK) {
125 		BMessage settings;
126 		status = settings.Unflatten(&file);
127 		if (status == B_OK) {
128 			int32 columns;
129 			int32 rows;
130 			if (settings.FindInt32("columns", &columns) == B_OK
131 				&& settings.FindInt32("rows", &rows) == B_OK) {
132 				_ValidateWorkspacesLayout(columns, rows);
133 				fWorkspacesColumns = columns;
134 				fWorkspacesRows = rows;
135 			}
136 
137 			int32 i = 0;
138 			while (i < kMaxWorkspaces && settings.FindMessage("workspace",
139 					i, &fWorkspaceMessages[i]) == B_OK) {
140 				i++;
141 			}
142 		}
143 	}
144 
145 	// read font settings
146 
147 	path = basePath;
148 	path.Append("fonts");
149 
150 	status = file.SetTo(path.Path(), B_READ_ONLY);
151 	if (status == B_OK) {
152 		BMessage settings;
153 		status = settings.Unflatten(&file);
154 		if (status == B_OK && gFontManager->Lock()) {
155 			const char* family;
156 			const char* style;
157 			float size;
158 
159 			if (settings.FindString("plain family", &family) == B_OK
160 				&& settings.FindString("plain style", &style) == B_OK
161 				&& settings.FindFloat("plain size", &size) == B_OK) {
162 				FontStyle* fontStyle = gFontManager->GetStyle(family, style);
163 				fPlainFont.SetStyle(fontStyle);
164 				fPlainFont.SetSize(size);
165 			}
166 
167 			if (settings.FindString("bold family", &family) == B_OK
168 				&& settings.FindString("bold style", &style) == B_OK
169 				&& settings.FindFloat("bold size", &size) == B_OK) {
170 				FontStyle* fontStyle = gFontManager->GetStyle(family, style);
171 				fBoldFont.SetStyle(fontStyle);
172 				fBoldFont.SetSize(size);
173 			}
174 
175 			if (settings.FindString("fixed family", &family) == B_OK
176 				&& settings.FindString("fixed style", &style) == B_OK
177 				&& settings.FindFloat("fixed size", &size) == B_OK) {
178 				FontStyle* fontStyle = gFontManager->GetStyle(family, style);
179 				if (fontStyle != NULL && fontStyle->IsFixedWidth())
180 					fFixedFont.SetStyle(fontStyle);
181 				fFixedFont.SetSize(size);
182 			}
183 
184 			int32 hinting;
185 			if (settings.FindInt32("hinting", &hinting) == B_OK)
186 				gDefaultHintingMode = hinting;
187 
188 			gFontManager->Unlock();
189 		}
190 	}
191 
192 	// read mouse settings
193 
194 	path = basePath;
195 	path.Append("mouse");
196 
197 	status = file.SetTo(path.Path(), B_READ_ONLY);
198 	if (status == B_OK) {
199 		BMessage settings;
200 		status = settings.Unflatten(&file);
201 		if (status == B_OK) {
202 			int32 mode;
203 			if (settings.FindInt32("mode", &mode) == B_OK)
204 				fMouseMode = (mode_mouse)mode;
205 
206 			int32 focusFollowsMouseMode;
207 			if (settings.FindInt32("focus follows mouse mode",
208 					&focusFollowsMouseMode) == B_OK) {
209 				fFocusFollowsMouseMode
210 					= (mode_focus_follows_mouse)focusFollowsMouseMode;
211 			}
212 
213 			bool acceptFirstClick;
214 			if (settings.FindBool("accept first click", &acceptFirstClick)
215 					== B_OK) {
216 				fAcceptFirstClick = acceptFirstClick;
217 			}
218 		}
219 	}
220 
221 	// read appearance settings
222 
223 	path = basePath;
224 	path.Append("appearance");
225 
226 	status = file.SetTo(path.Path(), B_READ_ONLY);
227 	if (status == B_OK) {
228 		BMessage settings;
229 		status = settings.Unflatten(&file);
230 		if (status == B_OK) {
231 			// menus
232 			float fontSize;
233 			if (settings.FindFloat("font size", &fontSize) == B_OK)
234 				fMenuInfo.font_size = fontSize;
235 
236 			const char* fontFamily;
237 			if (settings.FindString("font family", &fontFamily) == B_OK)
238 				strlcpy(fMenuInfo.f_family, fontFamily, B_FONT_FAMILY_LENGTH);
239 
240 			const char* fontStyle;
241 			if (settings.FindString("font style", &fontStyle) == B_OK)
242 				strlcpy(fMenuInfo.f_style, fontStyle, B_FONT_STYLE_LENGTH);
243 
244 			rgb_color bgColor;
245 			if (settings.FindInt32("bg color", (int32*)&bgColor) == B_OK)
246 				fMenuInfo.background_color = bgColor;
247 
248 			int32 separator;
249 			if (settings.FindInt32("separator", &separator) == B_OK)
250 				fMenuInfo.separator = separator;
251 
252 			bool clickToOpen;
253 			if (settings.FindBool("click to open", &clickToOpen) == B_OK)
254 				fMenuInfo.click_to_open = clickToOpen;
255 
256 			bool triggersAlwaysShown;
257 			if (settings.FindBool("triggers always shown", &triggersAlwaysShown)
258 					 == B_OK) {
259 				fMenuInfo.triggers_always_shown = triggersAlwaysShown;
260 			}
261 
262 			// scrollbars
263 			bool proportional;
264 			if (settings.FindBool("proportional", &proportional) == B_OK)
265 				fScrollBarInfo.proportional = proportional;
266 
267 			bool doubleArrows;
268 			if (settings.FindBool("double arrows", &doubleArrows) == B_OK)
269 				fScrollBarInfo.double_arrows = doubleArrows;
270 
271 			int32 knob;
272 			if (settings.FindInt32("knob", &knob) == B_OK)
273 				fScrollBarInfo.knob = knob;
274 
275 			int32 minKnobSize;
276 			if (settings.FindInt32("min knob size", &minKnobSize) == B_OK)
277 				fScrollBarInfo.min_knob_size = minKnobSize;
278 
279 			// subpixel font rendering
280 			bool subpix;
281 			if (settings.FindBool("subpixel antialiasing", &subpix) == B_OK)
282 				gSubpixelAntialiasing = subpix;
283 
284 			int8 averageWeight;
285 			if (settings.FindInt8("subpixel average weight", &averageWeight)
286 					== B_OK) {
287 				gSubpixelAverageWeight = averageWeight;
288 			}
289 
290 			bool subpixelOrdering;
291 			if (settings.FindBool("subpixel ordering", &subpixelOrdering)
292 					== B_OK) {
293 				gSubpixelOrderingRGB = subpixelOrdering;
294 			}
295 
296 			const char* controlLook;
297 			if (settings.FindString("control look", &controlLook) == B_OK) {
298 				fControlLook = controlLook;
299 			}
300 
301 			// colors
302 			for (int32 i = 0; i < kColorWhichCount; i++) {
303 				char colorName[12];
304 				snprintf(colorName, sizeof(colorName), "color%" B_PRId32,
305 					(int32)index_to_color_which(i));
306 
307 				if (settings.FindInt32(colorName, (int32*)&fShared.colors[i]) != B_OK) {
308 					// Set obviously bad value so the Appearance app can detect it
309 					fShared.colors[i] = B_TRANSPARENT_COLOR;
310 				}
311 			}
312 		}
313 	}
314 
315 	// read dragger settings
316 
317 	path = basePath;
318 	path.Append("dragger");
319 
320 	status = file.SetTo(path.Path(), B_READ_ONLY);
321 	if (status == B_OK) {
322 		BMessage settings;
323 		status = settings.Unflatten(&file);
324 		if (status == B_OK) {
325 			if (settings.FindBool("show", &fShowAllDraggers) != B_OK)
326 				fShowAllDraggers = true;
327 		}
328 	}
329 
330 	return B_OK;
331 }
332 
333 
334 status_t
335 DesktopSettingsPrivate::Save(uint32 mask)
336 {
337 #if TEST_MODE
338 	return B_OK;
339 #endif
340 
341 	BPath basePath;
342 	status_t status = _GetPath(basePath);
343 	if (status != B_OK)
344 		return status;
345 
346 	if (mask & kWorkspacesSettings) {
347 		BPath path(basePath);
348 		if (path.Append("workspaces") == B_OK) {
349 			BMessage settings('asws');
350 			settings.AddInt32("columns", fWorkspacesColumns);
351 			settings.AddInt32("rows", fWorkspacesRows);
352 
353 			for (int32 i = 0; i < kMaxWorkspaces; i++) {
354 				settings.AddMessage("workspace", &fWorkspaceMessages[i]);
355 			}
356 
357 			BFile file;
358 			status = file.SetTo(path.Path(), B_CREATE_FILE | B_ERASE_FILE
359 				| B_READ_WRITE);
360 			if (status == B_OK) {
361 				status = settings.Flatten(&file, NULL);
362 			}
363 		}
364 	}
365 
366 	if (mask & kFontSettings) {
367 		BPath path(basePath);
368 		if (path.Append("fonts") == B_OK) {
369 			BMessage settings('asfn');
370 
371 			settings.AddString("plain family", fPlainFont.Family());
372 			settings.AddString("plain style", fPlainFont.Style());
373 			settings.AddFloat("plain size", fPlainFont.Size());
374 
375 			settings.AddString("bold family", fBoldFont.Family());
376 			settings.AddString("bold style", fBoldFont.Style());
377 			settings.AddFloat("bold size", fBoldFont.Size());
378 
379 			settings.AddString("fixed family", fFixedFont.Family());
380 			settings.AddString("fixed style", fFixedFont.Style());
381 			settings.AddFloat("fixed size", fFixedFont.Size());
382 
383 			settings.AddInt32("hinting", gDefaultHintingMode);
384 
385 			BFile file;
386 			status = file.SetTo(path.Path(), B_CREATE_FILE | B_ERASE_FILE
387 				| B_READ_WRITE);
388 			if (status == B_OK) {
389 				status = settings.Flatten(&file, NULL);
390 			}
391 		}
392 	}
393 
394 	if (mask & kMouseSettings) {
395 		BPath path(basePath);
396 		if (path.Append("mouse") == B_OK) {
397 			BMessage settings('asms');
398 			settings.AddInt32("mode", (int32)fMouseMode);
399 			settings.AddInt32("focus follows mouse mode",
400 				(int32)fFocusFollowsMouseMode);
401 			settings.AddBool("accept first click", fAcceptFirstClick);
402 
403 			BFile file;
404 			status = file.SetTo(path.Path(), B_CREATE_FILE | B_ERASE_FILE
405 				| B_READ_WRITE);
406 			if (status == B_OK) {
407 				status = settings.Flatten(&file, NULL);
408 			}
409 		}
410 	}
411 
412 	if (mask & kDraggerSettings) {
413 		BPath path(basePath);
414 		if (path.Append("dragger") == B_OK) {
415 			BMessage settings('asdg');
416 			settings.AddBool("show", fShowAllDraggers);
417 
418 			BFile file;
419 			status = file.SetTo(path.Path(), B_CREATE_FILE | B_ERASE_FILE
420 				| B_READ_WRITE);
421 			if (status == B_OK) {
422 				status = settings.Flatten(&file, NULL);
423 			}
424 		}
425 	}
426 
427 	if (mask & kAppearanceSettings) {
428 		BPath path(basePath);
429 		if (path.Append("appearance") == B_OK) {
430 			BMessage settings('aslk');
431 			settings.AddFloat("font size", fMenuInfo.font_size);
432 			settings.AddString("font family", fMenuInfo.f_family);
433 			settings.AddString("font style", fMenuInfo.f_style);
434 			settings.AddInt32("bg color",
435 				(const int32&)fMenuInfo.background_color);
436 			settings.AddInt32("separator", fMenuInfo.separator);
437 			settings.AddBool("click to open", fMenuInfo.click_to_open);
438 			settings.AddBool("triggers always shown",
439 				fMenuInfo.triggers_always_shown);
440 
441 			settings.AddBool("proportional", fScrollBarInfo.proportional);
442 			settings.AddBool("double arrows", fScrollBarInfo.double_arrows);
443 			settings.AddInt32("knob", fScrollBarInfo.knob);
444 			settings.AddInt32("min knob size", fScrollBarInfo.min_knob_size);
445 
446 			settings.AddBool("subpixel antialiasing", gSubpixelAntialiasing);
447 			settings.AddInt8("subpixel average weight", gSubpixelAverageWeight);
448 			settings.AddBool("subpixel ordering", gSubpixelOrderingRGB);
449 
450 			settings.AddString("control look", fControlLook);
451 
452 			for (int32 i = 0; i < kColorWhichCount; i++) {
453 				char colorName[12];
454 				snprintf(colorName, sizeof(colorName), "color%" B_PRId32,
455 					(int32)index_to_color_which(i));
456 				settings.AddInt32(colorName, (const int32&)fShared.colors[i]);
457 			}
458 
459 			BFile file;
460 			status = file.SetTo(path.Path(), B_CREATE_FILE | B_ERASE_FILE
461 				| B_READ_WRITE);
462 			if (status == B_OK) {
463 				status = settings.Flatten(&file, NULL);
464 			}
465 		}
466 	}
467 
468 	return status;
469 }
470 
471 
472 void
473 DesktopSettingsPrivate::SetDefaultPlainFont(const ServerFont &font)
474 {
475 	fPlainFont = font;
476 	Save(kFontSettings);
477 }
478 
479 
480 const ServerFont &
481 DesktopSettingsPrivate::DefaultPlainFont() const
482 {
483 	return fPlainFont;
484 }
485 
486 
487 void
488 DesktopSettingsPrivate::SetDefaultBoldFont(const ServerFont &font)
489 {
490 	fBoldFont = font;
491 	Save(kFontSettings);
492 }
493 
494 
495 const ServerFont &
496 DesktopSettingsPrivate::DefaultBoldFont() const
497 {
498 	return fBoldFont;
499 }
500 
501 
502 void
503 DesktopSettingsPrivate::SetDefaultFixedFont(const ServerFont &font)
504 {
505 	fFixedFont = font;
506 	Save(kFontSettings);
507 }
508 
509 
510 const ServerFont &
511 DesktopSettingsPrivate::DefaultFixedFont() const
512 {
513 	return fFixedFont;
514 }
515 
516 
517 void
518 DesktopSettingsPrivate::SetScrollBarInfo(const scroll_bar_info& info)
519 {
520 	fScrollBarInfo = info;
521 	Save(kAppearanceSettings);
522 }
523 
524 
525 const scroll_bar_info&
526 DesktopSettingsPrivate::ScrollBarInfo() const
527 {
528 	return fScrollBarInfo;
529 }
530 
531 
532 void
533 DesktopSettingsPrivate::SetMenuInfo(const menu_info& info)
534 {
535 	fMenuInfo = info;
536 	// Also update the ui_color
537 	SetUIColor(B_MENU_BACKGROUND_COLOR, info.background_color);
538 		// SetUIColor already saves the settings
539 }
540 
541 
542 const menu_info&
543 DesktopSettingsPrivate::MenuInfo() const
544 {
545 	return fMenuInfo;
546 }
547 
548 
549 void
550 DesktopSettingsPrivate::SetMouseMode(const mode_mouse mode)
551 {
552 	fMouseMode = mode;
553 	Save(kMouseSettings);
554 }
555 
556 
557 void
558 DesktopSettingsPrivate::SetFocusFollowsMouseMode(mode_focus_follows_mouse mode)
559 {
560 	fFocusFollowsMouseMode = mode;
561 	Save(kMouseSettings);
562 }
563 
564 
565 mode_mouse
566 DesktopSettingsPrivate::MouseMode() const
567 {
568 	return fMouseMode;
569 }
570 
571 
572 mode_focus_follows_mouse
573 DesktopSettingsPrivate::FocusFollowsMouseMode() const
574 {
575 	return fFocusFollowsMouseMode;
576 }
577 
578 
579 void
580 DesktopSettingsPrivate::SetAcceptFirstClick(const bool acceptFirstClick)
581 {
582 	fAcceptFirstClick = acceptFirstClick;
583 	Save(kMouseSettings);
584 }
585 
586 
587 bool
588 DesktopSettingsPrivate::AcceptFirstClick() const
589 {
590 	return fAcceptFirstClick;
591 }
592 
593 
594 void
595 DesktopSettingsPrivate::SetShowAllDraggers(bool show)
596 {
597 	fShowAllDraggers = show;
598 	Save(kDraggerSettings);
599 }
600 
601 
602 bool
603 DesktopSettingsPrivate::ShowAllDraggers() const
604 {
605 	return fShowAllDraggers;
606 }
607 
608 
609 void
610 DesktopSettingsPrivate::SetWorkspacesLayout(int32 columns, int32 rows)
611 {
612 	_ValidateWorkspacesLayout(columns, rows);
613 	fWorkspacesColumns = columns;
614 	fWorkspacesRows = rows;
615 
616 	Save(kWorkspacesSettings);
617 }
618 
619 
620 int32
621 DesktopSettingsPrivate::WorkspacesCount() const
622 {
623 	return fWorkspacesColumns * fWorkspacesRows;
624 }
625 
626 
627 int32
628 DesktopSettingsPrivate::WorkspacesColumns() const
629 {
630 	return fWorkspacesColumns;
631 }
632 
633 
634 int32
635 DesktopSettingsPrivate::WorkspacesRows() const
636 {
637 	return fWorkspacesRows;
638 }
639 
640 
641 void
642 DesktopSettingsPrivate::SetWorkspacesMessage(int32 index, BMessage& message)
643 {
644 	if (index < 0 || index >= kMaxWorkspaces)
645 		return;
646 
647 	fWorkspaceMessages[index] = message;
648 }
649 
650 
651 const BMessage*
652 DesktopSettingsPrivate::WorkspacesMessage(int32 index) const
653 {
654 	if (index < 0 || index >= kMaxWorkspaces)
655 		return NULL;
656 
657 	return &fWorkspaceMessages[index];
658 }
659 
660 
661 void
662 DesktopSettingsPrivate::SetUIColor(color_which which, const rgb_color color,
663 									bool* changed)
664 {
665 	int32 index = color_which_to_index(which);
666 	if (index < 0 || index >= kColorWhichCount)
667 		return;
668 
669 	if (changed != NULL)
670 		*changed = fShared.colors[index] != color;
671 
672 	fShared.colors[index] = color;
673 	// TODO: deprecate the background_color member of the menu_info struct,
674 	// otherwise we have to keep this duplication...
675 	if (which == B_MENU_BACKGROUND_COLOR)
676 		fMenuInfo.background_color = color;
677 
678 	Save(kAppearanceSettings);
679 }
680 
681 
682 void
683 DesktopSettingsPrivate::SetUIColors(const BMessage& colors, bool* changed)
684 {
685 	int32 count = colors.CountNames(B_RGB_32_BIT_TYPE);
686 	if (count <= 0)
687 		return;
688 
689 	int32 index = 0;
690 	int32 colorIndex = 0;
691 	char* name = NULL;
692 	type_code type;
693 	rgb_color color;
694 	color_which which = B_NO_COLOR;
695 
696 	while (colors.GetInfo(B_RGB_32_BIT_TYPE, index, &name, &type) == B_OK) {
697 		which = which_ui_color(name);
698 		colorIndex = color_which_to_index(which);
699 		if (colorIndex < 0 || colorIndex >= kColorWhichCount
700 			|| colors.FindColor(name, &color) != B_OK) {
701 			if (changed != NULL)
702 				changed[index] = false;
703 
704 			++index;
705 			continue;
706 		}
707 
708 		if (changed != NULL)
709 			changed[index] = fShared.colors[colorIndex] != color;
710 
711 		fShared.colors[colorIndex] = color;
712 
713 		if (which == (int32)B_MENU_BACKGROUND_COLOR)
714 			fMenuInfo.background_color = color;
715 
716 		++index;
717 	}
718 
719 	Save(kAppearanceSettings);
720 }
721 
722 
723 rgb_color
724 DesktopSettingsPrivate::UIColor(color_which which) const
725 {
726 	static const rgb_color invalidColor = {0, 0, 0, 0};
727 	int32 index = color_which_to_index(which);
728 	if (index < 0 || index >= kColorWhichCount)
729 		return invalidColor;
730 
731 	return fShared.colors[index];
732 }
733 
734 
735 void
736 DesktopSettingsPrivate::SetSubpixelAntialiasing(bool subpix)
737 {
738 	gSubpixelAntialiasing = subpix;
739 	Save(kAppearanceSettings);
740 }
741 
742 
743 bool
744 DesktopSettingsPrivate::SubpixelAntialiasing() const
745 {
746 	return gSubpixelAntialiasing;
747 }
748 
749 
750 void
751 DesktopSettingsPrivate::SetHinting(uint8 hinting)
752 {
753 	gDefaultHintingMode = hinting;
754 	Save(kFontSettings);
755 }
756 
757 
758 uint8
759 DesktopSettingsPrivate::Hinting() const
760 {
761 	return gDefaultHintingMode;
762 }
763 
764 
765 void
766 DesktopSettingsPrivate::SetSubpixelAverageWeight(uint8 averageWeight)
767 {
768 	gSubpixelAverageWeight = averageWeight;
769 	Save(kAppearanceSettings);
770 }
771 
772 
773 uint8
774 DesktopSettingsPrivate::SubpixelAverageWeight() const
775 {
776 	return gSubpixelAverageWeight;
777 }
778 
779 
780 void
781 DesktopSettingsPrivate::SetSubpixelOrderingRegular(bool subpixelOrdering)
782 {
783 	gSubpixelOrderingRGB = subpixelOrdering;
784 	Save(kAppearanceSettings);
785 }
786 
787 
788 bool
789 DesktopSettingsPrivate::IsSubpixelOrderingRegular() const
790 {
791 	return gSubpixelOrderingRGB;
792 }
793 
794 
795 status_t
796 DesktopSettingsPrivate::SetControlLook(const char* path)
797 {
798 	fControlLook = path;
799 	return Save(kAppearanceSettings);
800 }
801 
802 
803 const BString&
804 DesktopSettingsPrivate::ControlLook() const
805 {
806 	return fControlLook;
807 }
808 
809 
810 void
811 DesktopSettingsPrivate::_ValidateWorkspacesLayout(int32& columns,
812 	int32& rows) const
813 {
814 	if (columns < 1)
815 		columns = 1;
816 	if (rows < 1)
817 		rows = 1;
818 
819 	if (columns * rows > kMaxWorkspaces) {
820 		// Revert to defaults in case of invalid settings
821 		columns = 2;
822 		rows = 2;
823 	}
824 }
825 
826 
827 //	#pragma mark - read access
828 
829 
830 DesktopSettings::DesktopSettings(Desktop* desktop)
831 	:
832 	fSettings(desktop->fSettings)
833 {
834 
835 }
836 
837 
838 void
839 DesktopSettings::GetDefaultPlainFont(ServerFont &font) const
840 {
841 	font = fSettings->DefaultPlainFont();
842 }
843 
844 
845 void
846 DesktopSettings::GetDefaultBoldFont(ServerFont &font) const
847 {
848 	font = fSettings->DefaultBoldFont();
849 }
850 
851 
852 void
853 DesktopSettings::GetDefaultFixedFont(ServerFont &font) const
854 {
855 	font = fSettings->DefaultFixedFont();
856 }
857 
858 
859 void
860 DesktopSettings::GetScrollBarInfo(scroll_bar_info& info) const
861 {
862 	info = fSettings->ScrollBarInfo();
863 }
864 
865 
866 void
867 DesktopSettings::GetMenuInfo(menu_info& info) const
868 {
869 	info = fSettings->MenuInfo();
870 }
871 
872 
873 mode_mouse
874 DesktopSettings::MouseMode() const
875 {
876 	return fSettings->MouseMode();
877 }
878 
879 
880 mode_focus_follows_mouse
881 DesktopSettings::FocusFollowsMouseMode() const
882 {
883 	return fSettings->FocusFollowsMouseMode();
884 }
885 
886 
887 bool
888 DesktopSettings::AcceptFirstClick() const
889 {
890 	return fSettings->AcceptFirstClick();
891 }
892 
893 
894 bool
895 DesktopSettings::ShowAllDraggers() const
896 {
897 	return fSettings->ShowAllDraggers();
898 }
899 
900 
901 int32
902 DesktopSettings::WorkspacesCount() const
903 {
904 	return fSettings->WorkspacesCount();
905 }
906 
907 
908 int32
909 DesktopSettings::WorkspacesColumns() const
910 {
911 	return fSettings->WorkspacesColumns();
912 }
913 
914 
915 int32
916 DesktopSettings::WorkspacesRows() const
917 {
918 	return fSettings->WorkspacesRows();
919 }
920 
921 
922 const BMessage*
923 DesktopSettings::WorkspacesMessage(int32 index) const
924 {
925 	return fSettings->WorkspacesMessage(index);
926 }
927 
928 
929 rgb_color
930 DesktopSettings::UIColor(color_which which) const
931 {
932 	return fSettings->UIColor(which);
933 }
934 
935 
936 bool
937 DesktopSettings::SubpixelAntialiasing() const
938 {
939 	return fSettings->SubpixelAntialiasing();
940 }
941 
942 
943 uint8
944 DesktopSettings::Hinting() const
945 {
946 	return fSettings->Hinting();
947 }
948 
949 
950 uint8
951 DesktopSettings::SubpixelAverageWeight() const
952 {
953 	return fSettings->SubpixelAverageWeight();
954 }
955 
956 
957 bool
958 DesktopSettings::IsSubpixelOrderingRegular() const
959 {
960 	// True corresponds to RGB, false means BGR
961 	return fSettings->IsSubpixelOrderingRegular();
962 }
963 
964 
965 const BString&
966 DesktopSettings::ControlLook() const
967 {
968 	return fSettings->ControlLook();
969 }
970 
971 //	#pragma mark - write access
972 
973 
974 LockedDesktopSettings::LockedDesktopSettings(Desktop* desktop)
975 	:
976 	DesktopSettings(desktop),
977 	fDesktop(desktop)
978 {
979 #if DEBUG
980 	if (desktop->fWindowLock.IsReadLocked())
981 		debugger("desktop read locked when trying to change settings");
982 #endif
983 
984 	fDesktop->LockAllWindows();
985 }
986 
987 
988 LockedDesktopSettings::~LockedDesktopSettings()
989 {
990 	fDesktop->UnlockAllWindows();
991 }
992 
993 
994 void
995 LockedDesktopSettings::SetDefaultPlainFont(const ServerFont &font)
996 {
997 	fSettings->SetDefaultPlainFont(font);
998 }
999 
1000 
1001 void
1002 LockedDesktopSettings::SetDefaultBoldFont(const ServerFont &font)
1003 {
1004 	fSettings->SetDefaultBoldFont(font);
1005 	fDesktop->BroadcastToAllWindows(AS_SYSTEM_FONT_CHANGED);
1006 }
1007 
1008 
1009 void
1010 LockedDesktopSettings::SetDefaultFixedFont(const ServerFont &font)
1011 {
1012 	fSettings->SetDefaultFixedFont(font);
1013 }
1014 
1015 
1016 void
1017 LockedDesktopSettings::SetScrollBarInfo(const scroll_bar_info& info)
1018 {
1019 	fSettings->SetScrollBarInfo(info);
1020 }
1021 
1022 
1023 void
1024 LockedDesktopSettings::SetMenuInfo(const menu_info& info)
1025 {
1026 	fSettings->SetMenuInfo(info);
1027 }
1028 
1029 
1030 void
1031 LockedDesktopSettings::SetMouseMode(const mode_mouse mode)
1032 {
1033 	fSettings->SetMouseMode(mode);
1034 }
1035 
1036 
1037 void
1038 LockedDesktopSettings::SetFocusFollowsMouseMode(mode_focus_follows_mouse mode)
1039 {
1040 	fSettings->SetFocusFollowsMouseMode(mode);
1041 }
1042 
1043 
1044 void
1045 LockedDesktopSettings::SetAcceptFirstClick(const bool acceptFirstClick)
1046 {
1047 	fSettings->SetAcceptFirstClick(acceptFirstClick);
1048 }
1049 
1050 
1051 void
1052 LockedDesktopSettings::SetShowAllDraggers(bool show)
1053 {
1054 	fSettings->SetShowAllDraggers(show);
1055 }
1056 
1057 
1058 void
1059 LockedDesktopSettings::SetUIColors(const BMessage& colors, bool* changed)
1060 {
1061 	fSettings->SetUIColors(colors, &changed[0]);
1062 }
1063 
1064 
1065 void
1066 LockedDesktopSettings::SetSubpixelAntialiasing(bool subpix)
1067 {
1068 	fSettings->SetSubpixelAntialiasing(subpix);
1069 }
1070 
1071 
1072 void
1073 LockedDesktopSettings::SetHinting(uint8 hinting)
1074 {
1075 	fSettings->SetHinting(hinting);
1076 }
1077 
1078 
1079 void
1080 LockedDesktopSettings::SetSubpixelAverageWeight(uint8 averageWeight)
1081 {
1082 	fSettings->SetSubpixelAverageWeight(averageWeight);
1083 }
1084 
1085 void
1086 LockedDesktopSettings::SetSubpixelOrderingRegular(bool subpixelOrdering)
1087 {
1088 	fSettings->SetSubpixelOrderingRegular(subpixelOrdering);
1089 }
1090 
1091 
1092 status_t
1093 LockedDesktopSettings::SetControlLook(const char* path)
1094 {
1095 	return fSettings->SetControlLook(path);
1096 }
1097 
1098