xref: /haiku/src/servers/app/DesktopSettings.cpp (revision b028e77473189065f2baefc6f5e10d451cf591e2)
1 /*
2  * Copyright 2005-2007, 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  */
9 
10 
11 #include "DesktopSettings.h"
12 #include "DesktopSettingsPrivate.h"
13 #include "Desktop.h"
14 #include "FontManager.h"
15 #include "ServerConfig.h"
16 
17 #include <DefaultColors.h>
18 #include <ServerReadOnlyMemory.h>
19 
20 #include <Directory.h>
21 #include <File.h>
22 #include <FindDirectory.h>
23 #include <Path.h>
24 
25 
26 DesktopSettingsPrivate::DesktopSettingsPrivate(server_read_only_memory* shared)
27 	:
28 	fShared(*shared)
29 {
30 	// if the on-disk settings are not complete, the defaults will be kept
31 	_SetDefaults();
32 	_Load();
33 }
34 
35 
36 DesktopSettingsPrivate::~DesktopSettingsPrivate()
37 {
38 }
39 
40 
41 void
42 DesktopSettingsPrivate::_SetDefaults()
43 {
44 	fPlainFont = *gFontManager->DefaultPlainFont();
45 	fBoldFont = *gFontManager->DefaultBoldFont();
46 	fFixedFont = *gFontManager->DefaultFixedFont();
47 
48 	fMouseMode = B_NORMAL_MOUSE;
49 	fShowAllDraggers = true;
50 
51 	// init scrollbar info
52 	fScrollBarInfo.proportional = true;
53 	fScrollBarInfo.double_arrows = false;
54 	fScrollBarInfo.knob = 1;
55 		// look of the knob (R5: (0, 1, 2), 1 = default)
56 	fScrollBarInfo.min_knob_size = 15;
57 
58 	// init menu info
59 	strlcpy(fMenuInfo.f_family, fPlainFont.Family(), B_FONT_FAMILY_LENGTH);
60 	strlcpy(fMenuInfo.f_style, fPlainFont.Style(), B_FONT_STYLE_LENGTH);
61 	fMenuInfo.font_size = fPlainFont.Size();
62 	fMenuInfo.background_color.set_to(216, 216, 216);
63 
64 	fMenuInfo.separator = 0;
65 		// look of the separator (R5: (0, 1, 2), default 0)
66 	fMenuInfo.click_to_open = true; // always true
67 	fMenuInfo.triggers_always_shown = false;
68 
69 	fWorkspacesCount = 4;
70 
71 	memcpy(fShared.colors, BPrivate::kDefaultColors, sizeof(rgb_color) * kNumColors);
72 }
73 
74 
75 status_t
76 DesktopSettingsPrivate::_GetPath(BPath& path)
77 {
78 	status_t status = find_directory(B_USER_SETTINGS_DIRECTORY, &path);
79 	if (status < B_OK)
80 		return status;
81 
82 	status = path.Append("system/app_server");
83 	if (status < B_OK)
84 		return status;
85 
86 	return create_directory(path.Path(), 0755);
87 }
88 
89 
90 status_t
91 DesktopSettingsPrivate::_Load()
92 {
93 	// TODO: add support for old app_server_settings file as well
94 
95 	BPath basePath;
96 	status_t status = _GetPath(basePath);
97 	if (status < B_OK)
98 		return status;
99 
100 	// read workspaces settings
101 
102 	BPath path(basePath);
103 	path.Append("workspaces");
104 
105 	BFile file;
106 	status = file.SetTo(path.Path(), B_READ_ONLY);
107 	if (status == B_OK) {
108 		BMessage settings;
109 		status = settings.Unflatten(&file);
110 		if (status == B_OK) {
111 			int32 count;
112 			if (settings.FindInt32("count", &count) == B_OK) {
113 				fWorkspacesCount = count;
114 				if (fWorkspacesCount < 1 || fWorkspacesCount > 32)
115 					fWorkspacesCount = 4;
116 			}
117 
118 			int32 i = 0;
119 			while (i < kMaxWorkspaces
120 				&& settings.FindMessage("workspace", i, &fWorkspaceMessages[i]) == B_OK) {
121 				i++;
122 			}
123 		}
124 	}
125 
126 	// read font settings
127 
128 	path = basePath;
129 	path.Append("fonts");
130 
131 	status = file.SetTo(path.Path(), B_READ_ONLY);
132 	if (status == B_OK) {
133 		BMessage settings;
134 		status = settings.Unflatten(&file);
135 		if (status == B_OK && gFontManager->Lock()) {
136 			const char* family;
137 			const char* style;
138 			float size;
139 			if (settings.FindString("plain family", &family) == B_OK
140 				&& settings.FindString("plain style", &style) == B_OK
141 				&& settings.FindFloat("plain size", &size) == B_OK) {
142 				FontStyle* fontStyle = gFontManager->GetStyle(family, style);
143 				fPlainFont.SetStyle(fontStyle);
144 				fPlainFont.SetSize(size);
145 			}
146 			if (settings.FindString("bold family", &family) == B_OK
147 				&& settings.FindString("bold style", &style) == B_OK
148 				&& settings.FindFloat("bold size", &size) == B_OK) {
149 				FontStyle* fontStyle = gFontManager->GetStyle(family, style);
150 				fBoldFont.SetStyle(fontStyle);
151 				fBoldFont.SetSize(size);
152 			}
153 			if (settings.FindString("fixed family", &family) == B_OK
154 				&& settings.FindString("fixed style", &style) == B_OK
155 				&& settings.FindFloat("fixed size", &size) == B_OK) {
156 				FontStyle* fontStyle = gFontManager->GetStyle(family, style);
157 				if (fontStyle->IsFixedWidth())
158 					fFixedFont.SetStyle(fontStyle);
159 				fFixedFont.SetSize(size);
160 			}
161 			gFontManager->Unlock();
162 		}
163 	}
164 
165 	// read mouse settings
166 
167 	path = basePath;
168 	path.Append("mouse");
169 
170 	status = file.SetTo(path.Path(), B_READ_ONLY);
171 	if (status == B_OK) {
172 		BMessage settings;
173 		status = settings.Unflatten(&file);
174 		if (status == B_OK) {
175 			int32 mode;
176 			if (settings.FindInt32("mode", &mode) == B_OK) {
177 				fMouseMode = (mode_mouse)mode;
178 			}
179 		}
180 	}
181 
182 	// read appearance settings
183 
184 	path = basePath;
185 	path.Append("appearance");
186 
187 	status = file.SetTo(path.Path(), B_READ_ONLY);
188 	if (status == B_OK) {
189 		BMessage settings;
190 		status = settings.Unflatten(&file);
191 		if (status == B_OK) {
192 			float fontSize;
193 			if (settings.FindFloat("font size", &fontSize) == B_OK)
194 				fMenuInfo.font_size = fontSize;
195 
196 			const char* fontFamily;
197 			if (settings.FindString("font family", &fontFamily) == B_OK)
198 				strlcpy(fMenuInfo.f_family, fontFamily, B_FONT_FAMILY_LENGTH);
199 
200 			const char* fontStyle;
201 			if (settings.FindString("font style", &fontStyle) == B_OK)
202 				strlcpy(fMenuInfo.f_style, fontStyle, B_FONT_STYLE_LENGTH);
203 
204 			rgb_color bgColor;
205 			if (settings.FindInt32("bg color", (int32*)&bgColor) == B_OK)
206 				fMenuInfo.background_color = bgColor;
207 
208 			int32 separator;
209 			if (settings.FindInt32("separator", &separator) == B_OK)
210 				fMenuInfo.separator = separator;
211 
212 			bool clickToOpen;
213 			if (settings.FindBool("click to open", &clickToOpen) == B_OK)
214 				fMenuInfo.click_to_open = clickToOpen;
215 
216 			bool triggersAlwaysShown;
217 			if (settings.FindBool("triggers always shown", &triggersAlwaysShown) == B_OK)
218 				fMenuInfo.triggers_always_shown = triggersAlwaysShown;
219 		}
220 	}
221 
222 	return B_OK;
223 }
224 
225 
226 status_t
227 DesktopSettingsPrivate::Save(uint32 mask)
228 {
229 	BPath basePath;
230 	status_t status = _GetPath(basePath);
231 	if (status < B_OK)
232 		return status;
233 
234 	if (mask & kWorkspacesSettings) {
235 		BPath path(basePath);
236 		if (path.Append("workspaces") == B_OK) {
237 			BMessage settings('asws');
238 			settings.AddInt32("count", fWorkspacesCount);
239 
240 			for (int32 i = 0; i < kMaxWorkspaces; i++) {
241 				settings.AddMessage("workspace", &fWorkspaceMessages[i]);
242 			}
243 
244 			BFile file;
245 			status = file.SetTo(path.Path(), B_CREATE_FILE | B_ERASE_FILE | B_READ_WRITE);
246 			if (status == B_OK) {
247 				status = settings.Flatten(&file, NULL);
248 			}
249 		}
250 	}
251 
252 	if (mask & kFontSettings) {
253 		BPath path(basePath);
254 		if (path.Append("fonts") == B_OK) {
255 			BMessage settings('asfn');
256 
257 			settings.AddString("plain family", fPlainFont.Family());
258 			settings.AddString("plain style", fPlainFont.Style());
259 			settings.AddFloat("plain size", fPlainFont.Size());
260 
261 			settings.AddString("bold family", fBoldFont.Family());
262 			settings.AddString("bold style", fBoldFont.Style());
263 			settings.AddFloat("bold size", fBoldFont.Size());
264 
265 			settings.AddString("fixed family", fFixedFont.Family());
266 			settings.AddString("fixed style", fFixedFont.Style());
267 			settings.AddFloat("fixed size", fFixedFont.Size());
268 
269 			BFile file;
270 			status = file.SetTo(path.Path(), B_CREATE_FILE | B_ERASE_FILE | B_READ_WRITE);
271 			if (status == B_OK) {
272 				status = settings.Flatten(&file, NULL);
273 			}
274 		}
275 	}
276 
277 	if (mask & kMouseSettings) {
278 		BPath path(basePath);
279 		if (path.Append("mouse") == B_OK) {
280 			BMessage settings('asms');
281 			settings.AddInt32("mode", (int32)fMouseMode);
282 
283 			BFile file;
284 			status = file.SetTo(path.Path(), B_CREATE_FILE | B_ERASE_FILE | B_READ_WRITE);
285 			if (status == B_OK) {
286 				status = settings.Flatten(&file, NULL);
287 			}
288 		}
289 	}
290 
291 	if (mask & kDraggerSettings) {
292 		BPath path(basePath);
293 		if (path.Append("dragger") == B_OK) {
294 			BMessage settings('asdg');
295 			settings.AddBool("show", fShowAllDraggers);
296 
297 			BFile file;
298 			status = file.SetTo(path.Path(), B_CREATE_FILE | B_ERASE_FILE | B_READ_WRITE);
299 			if (status == B_OK) {
300 				status = settings.Flatten(&file, NULL);
301 			}
302 		}
303 	}
304 
305 	if (mask & kAppearanceSettings) {
306 		BPath path(basePath);
307 		if (path.Append("appearance") == B_OK) {
308 			BMessage settings('aslk');
309 			settings.AddFloat("font size", fMenuInfo.font_size);
310 			settings.AddString("font family", fMenuInfo.f_family);
311 			settings.AddString("font style", fMenuInfo.f_style);
312 			settings.AddInt32("bg color", (const int32&)fMenuInfo.background_color);
313 			settings.AddInt32("separator", fMenuInfo.separator);
314 			settings.AddBool("click to open", fMenuInfo.click_to_open);
315 			settings.AddBool("triggers always shown", fMenuInfo.triggers_always_shown);
316 			// TODO: more appearance settings
317 
318 			BFile file;
319 			status = file.SetTo(path.Path(), B_CREATE_FILE | B_ERASE_FILE | B_READ_WRITE);
320 			if (status == B_OK) {
321 				status = settings.Flatten(&file, NULL);
322 			}
323 		}
324 	}
325 
326 	return status;
327 }
328 
329 
330 void
331 DesktopSettingsPrivate::SetDefaultPlainFont(const ServerFont &font)
332 {
333 	fPlainFont = font;
334 	Save(kFontSettings);
335 }
336 
337 
338 const ServerFont &
339 DesktopSettingsPrivate::DefaultPlainFont() const
340 {
341 	return fPlainFont;
342 }
343 
344 
345 void
346 DesktopSettingsPrivate::SetDefaultBoldFont(const ServerFont &font)
347 {
348 	fBoldFont = font;
349 	Save(kFontSettings);
350 }
351 
352 
353 const ServerFont &
354 DesktopSettingsPrivate::DefaultBoldFont() const
355 {
356 	return fBoldFont;
357 }
358 
359 
360 void
361 DesktopSettingsPrivate::SetDefaultFixedFont(const ServerFont &font)
362 {
363 	fFixedFont = font;
364 	Save(kFontSettings);
365 }
366 
367 
368 const ServerFont &
369 DesktopSettingsPrivate::DefaultFixedFont() const
370 {
371 	return fFixedFont;
372 }
373 
374 
375 void
376 DesktopSettingsPrivate::SetScrollBarInfo(const scroll_bar_info& info)
377 {
378 	fScrollBarInfo = info;
379 	Save(kAppearanceSettings);
380 }
381 
382 
383 const scroll_bar_info&
384 DesktopSettingsPrivate::ScrollBarInfo() const
385 {
386 	return fScrollBarInfo;
387 }
388 
389 
390 void
391 DesktopSettingsPrivate::SetMenuInfo(const menu_info& info)
392 {
393 	fMenuInfo = info;
394 	Save(kAppearanceSettings);
395 }
396 
397 
398 const menu_info&
399 DesktopSettingsPrivate::MenuInfo() const
400 {
401 	return fMenuInfo;
402 }
403 
404 
405 void
406 DesktopSettingsPrivate::SetMouseMode(const mode_mouse mode)
407 {
408 	fMouseMode = mode;
409 	Save(kMouseSettings);
410 }
411 
412 
413 mode_mouse
414 DesktopSettingsPrivate::MouseMode() const
415 {
416 	return fMouseMode;
417 }
418 
419 
420 bool
421 DesktopSettingsPrivate::FocusFollowsMouse() const
422 {
423 	return MouseMode() != B_NORMAL_MOUSE;
424 }
425 
426 
427 void
428 DesktopSettingsPrivate::SetShowAllDraggers(bool show)
429 {
430 	fShowAllDraggers = show;
431 	Save(kDraggerSettings);
432 }
433 
434 
435 bool
436 DesktopSettingsPrivate::ShowAllDraggers() const
437 {
438 	return fShowAllDraggers;
439 }
440 
441 
442 void
443 DesktopSettingsPrivate::SetWorkspacesCount(int32 number)
444 {
445 	if (number < 1)
446 		number = 1;
447 	else if (number > kMaxWorkspaces)
448 		number = kMaxWorkspaces;
449 
450 	fWorkspacesCount = number;
451 }
452 
453 
454 int32
455 DesktopSettingsPrivate::WorkspacesCount() const
456 {
457 	return fWorkspacesCount;
458 }
459 
460 
461 void
462 DesktopSettingsPrivate::SetWorkspacesMessage(int32 index, BMessage& message)
463 {
464 	if (index < 0 || index > kMaxWorkspaces)
465 		return;
466 
467 	fWorkspaceMessages[index] = message;
468 }
469 
470 
471 const BMessage*
472 DesktopSettingsPrivate::WorkspacesMessage(int32 index) const
473 {
474 	if (index < 0 || index > kMaxWorkspaces)
475 		return NULL;
476 
477 	return &fWorkspaceMessages[index];
478 }
479 
480 
481 //	#pragma mark - read access
482 
483 
484 DesktopSettings::DesktopSettings(Desktop* desktop)
485 	:
486 	fSettings(desktop->fSettings)
487 {
488 #if DEBUG
489 	if (!desktop->fWindowLock.IsWriteLocked()
490 		&& !desktop->fWindowLock.IsReadLocked())
491 		debugger("desktop not locked when trying to access settings");
492 #endif
493 }
494 
495 
496 void
497 DesktopSettings::GetDefaultPlainFont(ServerFont &font) const
498 {
499 	font = fSettings->DefaultPlainFont();
500 }
501 
502 
503 void
504 DesktopSettings::GetDefaultBoldFont(ServerFont &font) const
505 {
506 	font = fSettings->DefaultBoldFont();
507 }
508 
509 
510 void
511 DesktopSettings::GetDefaultFixedFont(ServerFont &font) const
512 {
513 	font = fSettings->DefaultFixedFont();
514 }
515 
516 
517 void
518 DesktopSettings::GetScrollBarInfo(scroll_bar_info& info) const
519 {
520 	info = fSettings->ScrollBarInfo();
521 }
522 
523 
524 void
525 DesktopSettings::GetMenuInfo(menu_info& info) const
526 {
527 	info = fSettings->MenuInfo();
528 }
529 
530 
531 mode_mouse
532 DesktopSettings::MouseMode() const
533 {
534 	return fSettings->MouseMode();
535 }
536 
537 
538 bool
539 DesktopSettings::FocusFollowsMouse() const
540 {
541 	return fSettings->FocusFollowsMouse();
542 }
543 
544 
545 bool
546 DesktopSettings::ShowAllDraggers() const
547 {
548 	return fSettings->ShowAllDraggers();
549 }
550 
551 
552 int32
553 DesktopSettings::WorkspacesCount() const
554 {
555 	return fSettings->WorkspacesCount();
556 }
557 
558 
559 const BMessage*
560 DesktopSettings::WorkspacesMessage(int32 index) const
561 {
562 	return fSettings->WorkspacesMessage(index);
563 }
564 
565 
566 //	#pragma mark - write access
567 
568 
569 LockedDesktopSettings::LockedDesktopSettings(Desktop* desktop)
570 	: DesktopSettings(desktop),
571 	fDesktop(desktop)
572 {
573 #if DEBUG
574 	if (desktop->fWindowLock.IsReadLocked())
575 		debugger("desktop read locked when trying to change settings");
576 #endif
577 
578 	fDesktop->LockAllWindows();
579 }
580 
581 
582 LockedDesktopSettings::~LockedDesktopSettings()
583 {
584 	fDesktop->UnlockAllWindows();
585 }
586 
587 
588 void
589 LockedDesktopSettings::SetDefaultPlainFont(const ServerFont &font)
590 {
591 	fSettings->SetDefaultPlainFont(font);
592 }
593 
594 
595 void
596 LockedDesktopSettings::SetDefaultBoldFont(const ServerFont &font)
597 {
598 	fSettings->SetDefaultBoldFont(font);
599 }
600 
601 
602 void
603 LockedDesktopSettings::SetDefaultFixedFont(const ServerFont &font)
604 {
605 	fSettings->SetDefaultFixedFont(font);
606 }
607 
608 
609 void
610 LockedDesktopSettings::SetScrollBarInfo(const scroll_bar_info& info)
611 {
612 	fSettings->SetScrollBarInfo(info);
613 }
614 
615 
616 void
617 LockedDesktopSettings::SetMenuInfo(const menu_info& info)
618 {
619 	fSettings->SetMenuInfo(info);
620 }
621 
622 
623 void
624 LockedDesktopSettings::SetMouseMode(const mode_mouse mode)
625 {
626 	fSettings->SetMouseMode(mode);
627 }
628 
629 
630 void
631 LockedDesktopSettings::SetShowAllDraggers(bool show)
632 {
633 	fSettings->SetShowAllDraggers(show);
634 }
635 
636