* Copyright 2005-2009, Axel Dörfler, axeld@pinc-software.de.
* This file may be used under the terms of the MIT License.
*/
#include "ScreenConfigurations.h"
#include <new>
#include <string.h>
#include <strings.h>
#include <Message.h>
ScreenConfigurations::ScreenConfigurations()
:
fConfigurations(10)
{
}
ScreenConfigurations::~ScreenConfigurations()
{
}
screen_configuration*
ScreenConfigurations::CurrentByID(int32 id) const
{
for (int32 i = fConfigurations.CountItems(); i-- > 0;) {
screen_configuration* configuration = fConfigurations.ItemAt(i);
if (configuration->id == id && configuration->is_current)
return configuration;
}
return NULL;
}
screen_configuration*
ScreenConfigurations::BestFit(int32 id, const monitor_info* info,
bool* _exactMatch) const
{
if (info == NULL) {
for (uint32 pass = 0; pass < 2; pass++) {
for (int32 i = fConfigurations.CountItems(); i-- > 0;) {
screen_configuration* configuration = fConfigurations.ItemAt(i);
if ((pass != 0 || !configuration->has_info)
&& id == configuration->id)
return configuration;
}
}
return NULL;
}
bool exactMatch = false;
int32 bestScore = 0;
int32 bestIndex = -1;
BMessage stored;
for (int32 i = fConfigurations.CountItems(); i-- > 0;) {
screen_configuration* configuration = fConfigurations.ItemAt(i);
if (!configuration->has_info)
continue;
int32 score = 0;
if (!strcasecmp(configuration->info.vendor, info->vendor)
&& !strcasecmp(configuration->info.name, info->name)
&& configuration->info.product_id == info->product_id) {
score += 2;
if (strcmp(configuration->info.serial_number,
info->serial_number) == 0) {
exactMatch = true;
score += 2;
}
if (configuration->info.produced.year == info->produced.year
&& configuration->info.produced.week == info->produced.week)
score++;
}
if (score > bestScore) {
bestScore = score;
bestIndex = i;
}
}
if (bestIndex < 0)
return NULL;
if (_exactMatch != NULL)
*_exactMatch = exactMatch;
return fConfigurations.ItemAt(bestIndex);
}
status_t
ScreenConfigurations::Set(int32 id, const monitor_info* info,
const BRect& frame, const display_mode& mode)
{
bool exactMatch;
screen_configuration* configuration = BestFit(id, info, &exactMatch);
if (configuration != NULL && configuration->has_info && !exactMatch) {
configuration->is_current = false;
configuration = NULL;
}
if (configuration == NULL) {
configuration = new (std::nothrow) screen_configuration;
if (configuration == NULL)
return B_NO_MEMORY;
fConfigurations.AddItem(configuration);
}
configuration->id = id;
configuration->frame = frame;
configuration->is_current = true;
if (info != NULL) {
memcpy(&configuration->info, info, sizeof(monitor_info));
configuration->has_info = true;
} else
configuration->has_info = false;
memcpy(&configuration->mode, &mode, sizeof(display_mode));
return B_OK;
}
void
ScreenConfigurations::SetBrightness(int32 id, float brightness)
{
for (int32 i = fConfigurations.CountItems(); i-- > 0;) {
screen_configuration* configuration = fConfigurations.ItemAt(i);
configuration->brightness = brightness;
}
}
float
ScreenConfigurations::Brightness(int32 id)
{
screen_configuration* configuration = fConfigurations.ItemAt(0);
if (configuration == NULL)
return -1;
return configuration->brightness;
}
void
ScreenConfigurations::Remove(screen_configuration* configuration)
{
if (configuration == NULL)
return;
fConfigurations.RemoveItem(configuration);
}
\a settings container.
*/
status_t
ScreenConfigurations::Store(BMessage& settings) const
{
for (int32 i = 0; i < fConfigurations.CountItems(); i++) {
screen_configuration* configuration = fConfigurations.ItemAt(i);
BMessage screenSettings;
screenSettings.AddInt32("id", configuration->id);
if (configuration->has_info) {
screenSettings.AddString("vendor", configuration->info.vendor);
screenSettings.AddString("name", configuration->info.name);
screenSettings.AddInt32("product id",
configuration->info.product_id);
screenSettings.AddString("serial",
configuration->info.serial_number);
screenSettings.AddInt32("produced week",
configuration->info.produced.week);
screenSettings.AddInt32("produced year",
configuration->info.produced.year);
}
screenSettings.AddRect("frame", configuration->frame);
screenSettings.AddData("mode", B_RAW_TYPE, &configuration->mode,
sizeof(display_mode));
screenSettings.AddFloat("brightness", configuration->brightness);
settings.AddMessage("screen", &screenSettings);
}
return B_OK;
}
status_t
ScreenConfigurations::Restore(const BMessage& settings)
{
fConfigurations.MakeEmpty();
BMessage stored;
for (int32 i = 0; settings.FindMessage("screen", i, &stored) == B_OK; i++) {
const display_mode* mode;
ssize_t size;
int32 id;
if (stored.FindInt32("id", &id) != B_OK
|| stored.FindData("mode", B_RAW_TYPE, (const void**)&mode,
&size) != B_OK
|| size != sizeof(display_mode))
continue;
screen_configuration* configuration
= new(std::nothrow) screen_configuration;
if (configuration == NULL)
return B_NO_MEMORY;
configuration->id = id;
configuration->is_current = false;
const char* vendor;
const char* name;
uint32 productID;
const char* serial;
int32 week, year;
if (stored.FindString("vendor", &vendor) == B_OK
&& stored.FindString("name", &name) == B_OK
&& stored.FindInt32("product id", (int32*)&productID) == B_OK
&& stored.FindString("serial", &serial) == B_OK
&& stored.FindInt32("produced week", &week) == B_OK
&& stored.FindInt32("produced year", &year) == B_OK) {
strlcpy(configuration->info.vendor, vendor,
sizeof(configuration->info.vendor));
strlcpy(configuration->info.name, name,
sizeof(configuration->info.name));
strlcpy(configuration->info.serial_number, serial,
sizeof(configuration->info.serial_number));
configuration->info.product_id = productID;
configuration->info.produced.week = week;
configuration->info.produced.year = year;
configuration->has_info = true;
} else
configuration->has_info = false;
stored.FindRect("frame", &configuration->frame);
memcpy(&configuration->mode, mode, sizeof(display_mode));
if (stored.FindFloat("brightness", &configuration->brightness) != B_OK)
configuration->brightness = 1.0f;
fConfigurations.AddItem(configuration);
}
return B_OK;
}