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