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