xref: /haiku/src/servers/app/DesktopSettings.cpp (revision cd552c7a15cc10c36dae8d7439ba1d6c0bb168c5)
1 /*
2  * Copyright 2005-2006, 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 DesktopSettings::Private::Private(server_read_only_memory* shared)
27 	: BLocker("DesktopSettings_Private"),
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 DesktopSettings::Private::~Private()
37 {
38 }
39 
40 
41 void
42 DesktopSettings::Private::_SetDefaults()
43 {
44 	fPlainFont = *gFontManager->DefaultPlainFont();
45 	fBoldFont = *gFontManager->DefaultBoldFont();
46 	fFixedFont = *gFontManager->DefaultFixedFont();
47 
48 	fMouseMode = B_NORMAL_MOUSE;
49 
50 	// init scrollbar info
51 	fScrollBarInfo.proportional = true;
52 	fScrollBarInfo.double_arrows = false;
53 	// look of the knob (R5: (0, 1, 2), 1 = default)
54 	fScrollBarInfo.knob = 1;
55 	fScrollBarInfo.min_knob_size = 15;
56 
57 	// init menu info
58 	strlcpy(fMenuInfo.f_family, fPlainFont.Family(), B_FONT_FAMILY_LENGTH);
59 	strlcpy(fMenuInfo.f_style, fPlainFont.Style(), B_FONT_STYLE_LENGTH);
60 	fMenuInfo.font_size = fPlainFont.Size();
61 	fMenuInfo.background_color.set_to(216, 216, 216);
62 
63 	// look of the separator (R5: (0, 1, 2), default 0)
64 	// TODO: we could just choose a nice one and remove the others
65 	fMenuInfo.separator = 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 DesktopSettings::Private::_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 DesktopSettings::Private::_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 DesktopSettings::Private::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 & kAppearanceSettings) {
292 		BPath path(basePath);
293 		if (path.Append("appearance") == B_OK) {
294 			BMessage settings('aslk');
295 			settings.AddFloat("font size", fMenuInfo.font_size);
296 			settings.AddString("font family", fMenuInfo.f_family);
297 			settings.AddString("font style", fMenuInfo.f_style);
298 			settings.AddInt32("bg color", (const int32&)fMenuInfo.background_color);
299 			settings.AddInt32("separator", fMenuInfo.separator);
300 			settings.AddBool("click to open", fMenuInfo.click_to_open);
301 			settings.AddBool("triggers always shown", fMenuInfo.triggers_always_shown);
302 			// TODO: more appearance settings
303 
304 			BFile file;
305 			status = file.SetTo(path.Path(), B_CREATE_FILE | B_ERASE_FILE | B_READ_WRITE);
306 			if (status == B_OK) {
307 				status = settings.Flatten(&file, NULL);
308 			}
309 		}
310 	}
311 
312 	return status;
313 }
314 
315 
316 void
317 DesktopSettings::Private::SetDefaultPlainFont(const ServerFont &font)
318 {
319 	fPlainFont = font;
320 	Save(kFontSettings);
321 }
322 
323 
324 const ServerFont &
325 DesktopSettings::Private::DefaultPlainFont() const
326 {
327 	return fPlainFont;
328 }
329 
330 
331 void
332 DesktopSettings::Private::SetDefaultBoldFont(const ServerFont &font)
333 {
334 	fBoldFont = font;
335 	Save(kFontSettings);
336 }
337 
338 
339 const ServerFont &
340 DesktopSettings::Private::DefaultBoldFont() const
341 {
342 	return fBoldFont;
343 }
344 
345 
346 void
347 DesktopSettings::Private::SetDefaultFixedFont(const ServerFont &font)
348 {
349 	fFixedFont = font;
350 	Save(kFontSettings);
351 }
352 
353 
354 const ServerFont &
355 DesktopSettings::Private::DefaultFixedFont() const
356 {
357 	return fFixedFont;
358 }
359 
360 
361 void
362 DesktopSettings::Private::SetScrollBarInfo(const scroll_bar_info& info)
363 {
364 	fScrollBarInfo = info;
365 	Save(kAppearanceSettings);
366 }
367 
368 
369 const scroll_bar_info&
370 DesktopSettings::Private::ScrollBarInfo() const
371 {
372 	return fScrollBarInfo;
373 }
374 
375 
376 void
377 DesktopSettings::Private::SetMenuInfo(const menu_info& info)
378 {
379 	fMenuInfo = info;
380 	Save(kAppearanceSettings);
381 }
382 
383 
384 const menu_info&
385 DesktopSettings::Private::MenuInfo() const
386 {
387 	return fMenuInfo;
388 }
389 
390 
391 void
392 DesktopSettings::Private::SetMouseMode(const mode_mouse mode)
393 {
394 	fMouseMode = mode;
395 	Save(kMouseSettings);
396 }
397 
398 
399 mode_mouse
400 DesktopSettings::Private::MouseMode() const
401 {
402 	return fMouseMode;
403 }
404 
405 
406 bool
407 DesktopSettings::Private::FocusFollowsMouse() const
408 {
409 	return MouseMode() != B_NORMAL_MOUSE;
410 }
411 
412 
413 void
414 DesktopSettings::Private::SetWorkspacesCount(int32 number)
415 {
416 	if (number < 1)
417 		number = 1;
418 	else if (number > kMaxWorkspaces)
419 		number = kMaxWorkspaces;
420 
421 	fWorkspacesCount = number;
422 }
423 
424 
425 int32
426 DesktopSettings::Private::WorkspacesCount() const
427 {
428 	return fWorkspacesCount;
429 }
430 
431 
432 void
433 DesktopSettings::Private::SetWorkspacesMessage(int32 index, BMessage& message)
434 {
435 	if (index < 0 || index > kMaxWorkspaces)
436 		return;
437 
438 	fWorkspaceMessages[index] = message;
439 }
440 
441 
442 const BMessage*
443 DesktopSettings::Private::WorkspacesMessage(int32 index) const
444 {
445 	if (index < 0 || index > kMaxWorkspaces)
446 		return NULL;
447 
448 	return &fWorkspaceMessages[index];
449 }
450 
451 
452 
453 //	#pragma mark -
454 
455 
456 DesktopSettings::DesktopSettings(Desktop* desktop)
457 {
458 	fSettings = desktop->fSettings;
459 	fSettings->Lock();
460 }
461 
462 
463 DesktopSettings::~DesktopSettings()
464 {
465 	fSettings->Unlock();
466 }
467 
468 
469 void
470 DesktopSettings::SetDefaultPlainFont(const ServerFont &font)
471 {
472 	fSettings->SetDefaultPlainFont(font);
473 }
474 
475 
476 void
477 DesktopSettings::GetDefaultPlainFont(ServerFont &font) const
478 {
479 	font = fSettings->DefaultPlainFont();
480 }
481 
482 
483 void
484 DesktopSettings::SetDefaultBoldFont(const ServerFont &font)
485 {
486 	fSettings->SetDefaultBoldFont(font);
487 }
488 
489 
490 void
491 DesktopSettings::GetDefaultBoldFont(ServerFont &font) const
492 {
493 	font = fSettings->DefaultBoldFont();
494 }
495 
496 
497 void
498 DesktopSettings::SetDefaultFixedFont(const ServerFont &font)
499 {
500 	fSettings->SetDefaultFixedFont(font);
501 }
502 
503 
504 void
505 DesktopSettings::GetDefaultFixedFont(ServerFont &font) const
506 {
507 	font = fSettings->DefaultFixedFont();
508 }
509 
510 
511 void
512 DesktopSettings::SetScrollBarInfo(const scroll_bar_info& info)
513 {
514 	fSettings->SetScrollBarInfo(info);
515 }
516 
517 
518 void
519 DesktopSettings::GetScrollBarInfo(scroll_bar_info& info) const
520 {
521 	info = fSettings->ScrollBarInfo();
522 }
523 
524 
525 void
526 DesktopSettings::SetMenuInfo(const menu_info& info)
527 {
528 	fSettings->SetMenuInfo(info);
529 }
530 
531 
532 void
533 DesktopSettings::GetMenuInfo(menu_info& info) const
534 {
535 	info = fSettings->MenuInfo();
536 }
537 
538 
539 void
540 DesktopSettings::SetMouseMode(const mode_mouse mode)
541 {
542 	fSettings->SetMouseMode(mode);
543 }
544 
545 
546 mode_mouse
547 DesktopSettings::MouseMode() const
548 {
549 	return fSettings->MouseMode();
550 }
551 
552 
553 bool
554 DesktopSettings::FocusFollowsMouse() const
555 {
556 	return fSettings->FocusFollowsMouse();
557 }
558 
559 
560 void
561 DesktopSettings::SetWorkspacesCount(int32 number)
562 {
563 	fSettings->SetWorkspacesCount(number);
564 }
565 
566 
567 int32
568 DesktopSettings::WorkspacesCount() const
569 {
570 	return fSettings->WorkspacesCount();
571 }
572 
573 
574 void
575 DesktopSettings::SetWorkspacesMessage(int32 index, BMessage& message)
576 {
577 	fSettings->SetWorkspacesMessage(index, message);
578 }
579 
580 
581 const BMessage*
582 DesktopSettings::WorkspacesMessage(int32 index) const
583 {
584 	return fSettings->WorkspacesMessage(index);
585 }
586 
587