xref: /haiku/src/servers/app/ScreenConfigurations.cpp (revision 0d87f2555a39e4f0f6c1faa0e3b4044bd3ab6599)
1 /*
2  * Copyright 2005-2009, Axel Dörfler, axeld@pinc-software.de.
3  * This file may be used under the terms of the MIT License.
4  */
5 
6 
7 #include "ScreenConfigurations.h"
8 
9 #include <new>
10 #include <string.h>
11 #include <strings.h>
12 
13 #include <Message.h>
14 
15 
ScreenConfigurations()16 ScreenConfigurations::ScreenConfigurations()
17 	:
18 	fConfigurations(10, true)
19 {
20 }
21 
22 
~ScreenConfigurations()23 ScreenConfigurations::~ScreenConfigurations()
24 {
25 }
26 
27 
28 screen_configuration*
CurrentByID(int32 id) const29 ScreenConfigurations::CurrentByID(int32 id) const
30 {
31 	for (int32 i = fConfigurations.CountItems(); i-- > 0;) {
32 		screen_configuration* configuration = fConfigurations.ItemAt(i);
33 
34 		if (configuration->id == id && configuration->is_current)
35 			return configuration;
36 	}
37 
38 	return NULL;
39 }
40 
41 
42 screen_configuration*
BestFit(int32 id,const monitor_info * info,bool * _exactMatch) const43 ScreenConfigurations::BestFit(int32 id, const monitor_info* info,
44 	bool* _exactMatch) const
45 {
46 	if (info == NULL) {
47 		// Only look for a matching ID - this is all we have
48 		for (uint32 pass = 0; pass < 2; pass++) {
49 			for (int32 i = fConfigurations.CountItems(); i-- > 0;) {
50 				screen_configuration* configuration = fConfigurations.ItemAt(i);
51 
52 				if ((pass != 0 || !configuration->has_info)
53 					&& id == configuration->id)
54 					return configuration;
55 			}
56 		}
57 
58 		return NULL;
59 	}
60 
61 	// Look for a configuration that matches the monitor
62 
63 	bool exactMatch = false;
64 	int32 bestScore = 0;
65 	int32 bestIndex = -1;
66 	BMessage stored;
67 
68 	for (int32 i = fConfigurations.CountItems(); i-- > 0;) {
69 		screen_configuration* configuration = fConfigurations.ItemAt(i);
70 		if (!configuration->has_info)
71 			continue;
72 
73 		int32 score = 0;
74 
75 		if (!strcasecmp(configuration->info.vendor, info->vendor)
76 			&& !strcasecmp(configuration->info.name, info->name)
77 			&& configuration->info.product_id == info->product_id) {
78 			score += 2;
79 			if (strcmp(configuration->info.serial_number,
80 					info->serial_number) == 0) {
81 				exactMatch = true;
82 				score += 2;
83 			}
84 			if (configuration->info.produced.year == info->produced.year
85 				&& configuration->info.produced.week == info->produced.week)
86 				score++;
87 		}
88 
89 		if (score > bestScore) {
90 			bestScore = score;
91 			bestIndex = i;
92 		}
93 	}
94 
95 	if (bestIndex < 0)
96 		return NULL;
97 
98 	if (_exactMatch != NULL)
99 		*_exactMatch = exactMatch;
100 
101 	return fConfigurations.ItemAt(bestIndex);
102 }
103 
104 
105 status_t
Set(int32 id,const monitor_info * info,const BRect & frame,const display_mode & mode)106 ScreenConfigurations::Set(int32 id, const monitor_info* info,
107 	const BRect& frame, const display_mode& mode)
108 {
109 	// Find configuration that we can overwrite
110 
111 	bool exactMatch;
112 	screen_configuration* configuration = BestFit(id, info, &exactMatch);
113 
114 	if (configuration != NULL && configuration->has_info && !exactMatch) {
115 		// only overwrite exact or unspecified configurations
116 		configuration->is_current = false;
117 			// TODO: provide a more obvious current mechanism...
118 		configuration = NULL;
119 	}
120 
121 	if (configuration == NULL) {
122 		// we need a new configuration to store
123 		configuration = new (std::nothrow) screen_configuration;
124 		if (configuration == NULL)
125 			return B_NO_MEMORY;
126 
127 		fConfigurations.AddItem(configuration);
128 	}
129 
130 	configuration->id = id;
131 	configuration->frame = frame;
132 	configuration->is_current = true;
133 
134 	if (info != NULL) {
135 		memcpy(&configuration->info, info, sizeof(monitor_info));
136 		configuration->has_info = true;
137 	} else
138 		configuration->has_info = false;
139 
140 	memcpy(&configuration->mode, &mode, sizeof(display_mode));
141 
142 	return B_OK;
143 }
144 
145 
146 void
SetBrightness(int32 id,float brightness)147 ScreenConfigurations::SetBrightness(int32 id, float brightness)
148 {
149 	for (int32 i = fConfigurations.CountItems(); i-- > 0;) {
150 		screen_configuration* configuration = fConfigurations.ItemAt(i);
151 		configuration->brightness = brightness;
152 	}
153 }
154 
155 
156 float
Brightness(int32 id)157 ScreenConfigurations::Brightness(int32 id)
158 {
159 	screen_configuration* configuration = fConfigurations.ItemAt(0);
160 
161 	if (configuration == NULL)
162 		return -1;
163 
164 	return configuration->brightness;
165 }
166 
167 
168 void
Remove(screen_configuration * configuration)169 ScreenConfigurations::Remove(screen_configuration* configuration)
170 {
171 	if (configuration == NULL)
172 		return;
173 
174 	fConfigurations.RemoveItem(configuration);
175 		// this also deletes the configuration
176 }
177 
178 
179 /*!	Stores all configurations as separate BMessages into the provided
180 	\a settings container.
181 */
182 status_t
Store(BMessage & settings) const183 ScreenConfigurations::Store(BMessage& settings) const
184 {
185 	// Store the configuration of all current screens
186 
187 	for (int32 i = 0; i < fConfigurations.CountItems(); i++) {
188 		screen_configuration* configuration = fConfigurations.ItemAt(i);
189 
190 		BMessage screenSettings;
191 		screenSettings.AddInt32("id", configuration->id);
192 
193 		if (configuration->has_info) {
194 			screenSettings.AddString("vendor", configuration->info.vendor);
195 			screenSettings.AddString("name", configuration->info.name);
196 			screenSettings.AddInt32("product id",
197 				configuration->info.product_id);
198 			screenSettings.AddString("serial",
199 				configuration->info.serial_number);
200 			screenSettings.AddInt32("produced week",
201 				configuration->info.produced.week);
202 			screenSettings.AddInt32("produced year",
203 				configuration->info.produced.year);
204 		}
205 
206 		screenSettings.AddRect("frame", configuration->frame);
207 		screenSettings.AddData("mode", B_RAW_TYPE, &configuration->mode,
208 			sizeof(display_mode));
209 		screenSettings.AddFloat("brightness", configuration->brightness);
210 
211 		settings.AddMessage("screen", &screenSettings);
212 	}
213 
214 	return B_OK;
215 }
216 
217 
218 status_t
Restore(const BMessage & settings)219 ScreenConfigurations::Restore(const BMessage& settings)
220 {
221 	fConfigurations.MakeEmpty();
222 
223 	BMessage stored;
224 	for (int32 i = 0; settings.FindMessage("screen", i, &stored) == B_OK; i++) {
225 		const display_mode* mode;
226 		ssize_t size;
227 		int32 id;
228 		if (stored.FindInt32("id", &id) != B_OK
229 			|| stored.FindData("mode", B_RAW_TYPE, (const void**)&mode,
230 					&size) != B_OK
231 			|| size != sizeof(display_mode))
232 			continue;
233 
234 		screen_configuration* configuration
235 			= new(std::nothrow) screen_configuration;
236 		if (configuration == NULL)
237 			return B_NO_MEMORY;
238 
239 		configuration->id = id;
240 		configuration->is_current = false;
241 
242 		const char* vendor;
243 		const char* name;
244 		uint32 productID;
245 		const char* serial;
246 		int32 week, year;
247 		if (stored.FindString("vendor", &vendor) == B_OK
248 			&& stored.FindString("name", &name) == B_OK
249 			&& stored.FindInt32("product id", (int32*)&productID) == B_OK
250 			&& stored.FindString("serial", &serial) == B_OK
251 			&& stored.FindInt32("produced week", &week) == B_OK
252 			&& stored.FindInt32("produced year", &year) == B_OK) {
253 			// create monitor info
254 			strlcpy(configuration->info.vendor, vendor,
255 				sizeof(configuration->info.vendor));
256 			strlcpy(configuration->info.name, name,
257 				sizeof(configuration->info.name));
258 			strlcpy(configuration->info.serial_number, serial,
259 				sizeof(configuration->info.serial_number));
260 			configuration->info.product_id = productID;
261 			configuration->info.produced.week = week;
262 			configuration->info.produced.year = year;
263 			configuration->has_info = true;
264 		} else
265 			configuration->has_info = false;
266 
267 		stored.FindRect("frame", &configuration->frame);
268 		memcpy(&configuration->mode, mode, sizeof(display_mode));
269 
270 		if (stored.FindFloat("brightness", &configuration->brightness) != B_OK)
271 			configuration->brightness = 1.0f;
272 
273 		fConfigurations.AddItem(configuration);
274 	}
275 
276 	return B_OK;
277 }
278