2 * Copyright 2005-2009, Axel Dörfler, axeld@pinc-software.de.
3 * This file may be used under the terms of the MIT License.
7 #include "ScreenConfigurations.h"
16 ScreenConfigurations::ScreenConfigurations()
18 fConfigurations(10, true)
23 ScreenConfigurations::~ScreenConfigurations()
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
)
43 ScreenConfigurations::BestFit(int32 id
, const monitor_info
* info
,
44 bool* _exactMatch
) const
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
)
61 // Look for a configuration that matches the monitor
63 bool exactMatch
= false;
68 for (int32 i
= fConfigurations
.CountItems(); i
-- > 0;) {
69 screen_configuration
* configuration
= fConfigurations
.ItemAt(i
);
70 if (!configuration
->has_info
)
75 if (!strcasecmp(configuration
->info
.vendor
, info
->vendor
)
76 && !strcasecmp(configuration
->info
.name
, info
->name
)
77 && configuration
->info
.product_id
== info
->product_id
) {
79 if (info
->serial_number
[0] != '\0'
80 && !strcmp(configuration
->info
.serial_number
,
81 info
->serial_number
)) {
85 if (configuration
->info
.produced
.year
== info
->produced
.year
86 && configuration
->info
.produced
.week
== info
->produced
.week
)
90 if (score
> bestScore
) {
99 if (_exactMatch
!= NULL
)
100 *_exactMatch
= exactMatch
;
102 return fConfigurations
.ItemAt(bestIndex
);
107 ScreenConfigurations::Set(int32 id
, const monitor_info
* info
,
108 const BRect
& frame
, const display_mode
& mode
)
110 // Find configuration that we can overwrite
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
)
128 fConfigurations
.AddItem(configuration
);
131 configuration
->id
= id
;
132 configuration
->frame
= frame
;
133 configuration
->is_current
= true;
136 memcpy(&configuration
->info
, info
, sizeof(monitor_info
));
137 configuration
->has_info
= true;
139 configuration
->has_info
= false;
141 memcpy(&configuration
->mode
, &mode
, sizeof(display_mode
));
148 ScreenConfigurations::Remove(screen_configuration
* configuration
)
150 if (configuration
== NULL
)
153 fConfigurations
.RemoveItem(configuration
);
154 // this also deletes the configuration
158 /*! Stores all configurations as separate BMessages into the provided
159 \a settings container.
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
);
197 ScreenConfigurations::Restore(const BMessage
& settings
)
199 fConfigurations
.MakeEmpty();
202 for (int32 i
= 0; settings
.FindMessage("screen", i
, &stored
) == B_OK
; i
++) {
203 const display_mode
* mode
;
206 if (stored
.FindInt32("id", &id
) != B_OK
207 || stored
.FindData("mode", B_RAW_TYPE
, (const void**)&mode
,
209 || size
!= sizeof(display_mode
))
212 screen_configuration
* configuration
213 = new(std::nothrow
) screen_configuration
;
214 if (configuration
== NULL
)
217 configuration
->id
= id
;
218 configuration
->is_current
= false;
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;
242 configuration
->has_info
= false;
244 stored
.FindRect("frame", &configuration
->frame
);
245 memcpy(&configuration
->mode
, mode
, sizeof(display_mode
));
247 fConfigurations
.AddItem(configuration
);