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