vfs: check userland buffers before reading them.
[haiku.git] / src / servers / app / ScreenConfigurations.cpp
blob643bb169e9c523913c13e9bfbec182b7d313858b
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 */
7 #include "ScreenConfigurations.h"
9 #include <new>
10 #include <string.h>
11 #include <strings.h>
13 #include <Message.h>
16 ScreenConfigurations::ScreenConfigurations()
18 fConfigurations(10, true)
23 ScreenConfigurations::~ScreenConfigurations()
28 screen_configuration*
29 ScreenConfigurations::CurrentByID(int32 id) const
31 for (int32 i = fConfigurations.CountItems(); i-- > 0;) {
32 screen_configuration* configuration = fConfigurations.ItemAt(i);
34 if (configuration->id == id && configuration->is_current)
35 return configuration;
38 return NULL;
42 screen_configuration*
43 ScreenConfigurations::BestFit(int32 id, const monitor_info* info,
44 bool* _exactMatch) const
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);
52 if ((pass != 0 || !configuration->has_info)
53 && id == configuration->id)
54 return configuration;
58 return NULL;
61 // Look for a configuration that matches the monitor
63 bool exactMatch = false;
64 int32 bestScore = 0;
65 int32 bestIndex = -1;
66 BMessage stored;
68 for (int32 i = fConfigurations.CountItems(); i-- > 0;) {
69 screen_configuration* configuration = fConfigurations.ItemAt(i);
70 if (!configuration->has_info)
71 continue;
73 int32 score = 0;
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 (info->serial_number[0] != '\0'
80 && !strcmp(configuration->info.serial_number,
81 info->serial_number)) {
82 exactMatch = true;
83 score += 2;
85 if (configuration->info.produced.year == info->produced.year
86 && configuration->info.produced.week == info->produced.week)
87 score++;
90 if (score > bestScore) {
91 bestScore = score;
92 bestIndex = i;
96 if (bestIndex < 0)
97 return NULL;
99 if (_exactMatch != NULL)
100 *_exactMatch = exactMatch;
102 return fConfigurations.ItemAt(bestIndex);
106 status_t
107 ScreenConfigurations::Set(int32 id, const monitor_info* info,
108 const BRect& frame, const display_mode& mode)
110 // Find configuration that we can overwrite
112 bool exactMatch;
113 screen_configuration* configuration = BestFit(id, info, &exactMatch);
115 if (configuration != NULL && configuration->has_info && !exactMatch) {
116 // only overwrite exact or unspecified configurations
117 configuration->is_current = false;
118 // TODO: provide a more obvious current mechanism...
119 configuration = NULL;
122 if (configuration == NULL) {
123 // we need a new configuration to store
124 configuration = new (std::nothrow) screen_configuration;
125 if (configuration == NULL)
126 return B_NO_MEMORY;
128 fConfigurations.AddItem(configuration);
131 configuration->id = id;
132 configuration->frame = frame;
133 configuration->is_current = true;
135 if (info != NULL) {
136 memcpy(&configuration->info, info, sizeof(monitor_info));
137 configuration->has_info = true;
138 } else
139 configuration->has_info = false;
141 memcpy(&configuration->mode, &mode, sizeof(display_mode));
143 return B_OK;
147 void
148 ScreenConfigurations::Remove(screen_configuration* configuration)
150 if (configuration == NULL)
151 return;
153 fConfigurations.RemoveItem(configuration);
154 // this also deletes the configuration
158 /*! Stores all configurations as separate BMessages into the provided
159 \a settings container.
161 status_t
162 ScreenConfigurations::Store(BMessage& settings) const
164 // Store the configuration of all current screens
166 for (int32 i = 0; i < fConfigurations.CountItems(); i++) {
167 screen_configuration* configuration = fConfigurations.ItemAt(i);
169 BMessage screenSettings;
170 screenSettings.AddInt32("id", configuration->id);
172 if (configuration->has_info) {
173 screenSettings.AddString("vendor", configuration->info.vendor);
174 screenSettings.AddString("name", configuration->info.name);
175 screenSettings.AddInt32("product id",
176 configuration->info.product_id);
177 screenSettings.AddString("serial",
178 configuration->info.serial_number);
179 screenSettings.AddInt32("produced week",
180 configuration->info.produced.week);
181 screenSettings.AddInt32("produced year",
182 configuration->info.produced.year);
185 screenSettings.AddRect("frame", configuration->frame);
186 screenSettings.AddData("mode", B_RAW_TYPE, &configuration->mode,
187 sizeof(display_mode));
189 settings.AddMessage("screen", &screenSettings);
192 return B_OK;
196 status_t
197 ScreenConfigurations::Restore(const BMessage& settings)
199 fConfigurations.MakeEmpty();
201 BMessage stored;
202 for (int32 i = 0; settings.FindMessage("screen", i, &stored) == B_OK; i++) {
203 const display_mode* mode;
204 ssize_t size;
205 int32 id;
206 if (stored.FindInt32("id", &id) != B_OK
207 || stored.FindData("mode", B_RAW_TYPE, (const void**)&mode,
208 &size) != B_OK
209 || size != sizeof(display_mode))
210 continue;
212 screen_configuration* configuration
213 = new(std::nothrow) screen_configuration;
214 if (configuration == NULL)
215 return B_NO_MEMORY;
217 configuration->id = id;
218 configuration->is_current = false;
220 const char* vendor;
221 const char* name;
222 uint32 productID;
223 const char* serial;
224 int32 week, year;
225 if (stored.FindString("vendor", &vendor) == B_OK
226 && stored.FindString("name", &name) == B_OK
227 && stored.FindInt32("product id", (int32*)&productID) == B_OK
228 && stored.FindString("serial", &serial) == B_OK
229 && stored.FindInt32("produced week", &week) == B_OK
230 && stored.FindInt32("produced year", &year) == B_OK) {
231 // create monitor info
232 strlcpy(configuration->info.vendor, vendor,
233 sizeof(configuration->info.vendor));
234 strlcpy(configuration->info.name, name, sizeof(configuration->info.name));
235 strlcpy(configuration->info.serial_number, serial,
236 sizeof(configuration->info.serial_number));
237 configuration->info.product_id = productID;
238 configuration->info.produced.week = week;
239 configuration->info.produced.year = year;
240 configuration->has_info = true;
241 } else
242 configuration->has_info = false;
244 stored.FindRect("frame", &configuration->frame);
245 memcpy(&configuration->mode, mode, sizeof(display_mode));
247 fConfigurations.AddItem(configuration);
250 return B_OK;