// Copyright (c) 2013 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "ash/display/display_layout.h" #include "ash/display/display_pref_util.h" #include "base/json/json_value_converter.h" #include "base/logging.h" #include "base/strings/string_number_conversions.h" #include "base/strings/string_piece.h" #include "base/strings/stringprintf.h" #include "base/values.h" #include "ui/gfx/display.h" namespace ash { namespace { // The maximum value for 'offset' in DisplayLayout in case of outliers. Need // to change this value in case to support even larger displays. const int kMaxValidOffset = 10000; // Persistent key names const char kPositionKey[] = "position"; const char kOffsetKey[] = "offset"; const char kMirroredKey[] = "mirrored"; const char kPrimaryIdKey[] = "primary-id"; typedef std::map<DisplayLayout::Position, std::string> PositionToStringMap; const PositionToStringMap* GetPositionToStringMap() { static const PositionToStringMap* map = CreateToStringMap( DisplayLayout::TOP, "top", DisplayLayout::BOTTOM, "bottom", DisplayLayout::RIGHT, "right", DisplayLayout::LEFT, "left"); return map; } bool GetPositionFromString(const base::StringPiece& position, DisplayLayout::Position* field) { if (ReverseFind(GetPositionToStringMap(), position, field)) return true; LOG(ERROR) << "Invalid position value:" << position; return false; } std::string GetStringFromPosition(DisplayLayout::Position position) { const PositionToStringMap* map = GetPositionToStringMap(); PositionToStringMap::const_iterator iter = map->find(position); return iter != map->end() ? iter->second : std::string("unknown"); } bool GetDisplayIdFromString(const base::StringPiece& position, int64* field) { return base::StringToInt64(position, field); } } // namespace //////////////////////////////////////////////////////////////////////////////// // DisplayLayout // static DisplayLayout DisplayLayout::FromInts(int position, int offsets) { return DisplayLayout(static_cast<Position>(position), offsets); } DisplayLayout::DisplayLayout() : position(RIGHT), offset(0), mirrored(false), primary_id(gfx::Display::kInvalidDisplayID) { } DisplayLayout::DisplayLayout(DisplayLayout::Position position, int offset) : position(position), offset(offset), mirrored(false), primary_id(gfx::Display::kInvalidDisplayID) { DCHECK_LE(TOP, position); DCHECK_GE(LEFT, position); // Set the default value to |position| in case position is invalid. DCHECKs // above doesn't stop in Release builds. if (TOP > position || LEFT < position) this->position = RIGHT; DCHECK_GE(kMaxValidOffset, abs(offset)); } DisplayLayout DisplayLayout::Invert() const { Position inverted_position = RIGHT; switch (position) { case TOP: inverted_position = BOTTOM; break; case BOTTOM: inverted_position = TOP; break; case RIGHT: inverted_position = LEFT; break; case LEFT: inverted_position = RIGHT; break; } DisplayLayout ret = DisplayLayout(inverted_position, -offset); ret.primary_id = primary_id; return ret; } // static bool DisplayLayout::ConvertFromValue(const base::Value& value, DisplayLayout* layout) { base::JSONValueConverter<DisplayLayout> converter; return converter.Convert(value, layout); } // static bool DisplayLayout::ConvertToValue(const DisplayLayout& layout, base::Value* value) { base::DictionaryValue* dict_value = NULL; if (!value->GetAsDictionary(&dict_value) || dict_value == NULL) return false; const std::string position_str = GetStringFromPosition(layout.position); dict_value->SetString(kPositionKey, position_str); dict_value->SetInteger(kOffsetKey, layout.offset); dict_value->SetBoolean(kMirroredKey, layout.mirrored); dict_value->SetString(kPrimaryIdKey, base::Int64ToString(layout.primary_id)); return true; } std::string DisplayLayout::ToString() const { const std::string position_str = GetStringFromPosition(position); return base::StringPrintf( "%s, %d%s", position_str.c_str(), offset, mirrored ? ", mirrored" : ""); } // static void DisplayLayout::RegisterJSONConverter( base::JSONValueConverter<DisplayLayout>* converter) { converter->RegisterCustomField<Position>( kPositionKey, &DisplayLayout::position, &GetPositionFromString); converter->RegisterIntField(kOffsetKey, &DisplayLayout::offset); converter->RegisterBoolField(kMirroredKey, &DisplayLayout::mirrored); converter->RegisterCustomField<int64>( kPrimaryIdKey, &DisplayLayout::primary_id, &GetDisplayIdFromString); } } // namespace ash