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