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 16 ScreenConfigurations::ScreenConfigurations() 17 : 18 fConfigurations(10, true) 19 { 20 } 21 22 23 ScreenConfigurations::~ScreenConfigurations() 24 { 25 } 26 27 28 screen_configuration* 29 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* 43 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 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 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 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 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 183 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 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