| OLD | NEW |
| (Empty) | |
| 1 // Copyright 2017 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #include "ui/display/win/color_profile_reader.h" |
| 6 |
| 7 #include <stddef.h> |
| 8 #include <windows.h> |
| 9 |
| 10 #include "base/files/file_util.h" |
| 11 #include "base/task_scheduler/post_task.h" |
| 12 #include "base/threading/sequenced_worker_pool.h" |
| 13 #include "ui/display/win/display_info.h" |
| 14 #include "ui/gfx/icc_profile.h" |
| 15 |
| 16 namespace display { |
| 17 namespace win { |
| 18 namespace { |
| 19 |
| 20 BOOL CALLBACK EnumMonitorCallback(HMONITOR monitor, |
| 21 HDC input_hdc, |
| 22 LPRECT rect, |
| 23 LPARAM data) { |
| 24 base::string16 device_name; |
| 25 MONITORINFOEX monitor_info; |
| 26 ::ZeroMemory(&monitor_info, sizeof(monitor_info)); |
| 27 monitor_info.cbSize = sizeof(monitor_info); |
| 28 ::GetMonitorInfo(monitor, &monitor_info); |
| 29 device_name = base::string16(monitor_info.szDevice); |
| 30 |
| 31 base::string16 profile_path; |
| 32 HDC hdc = ::CreateDC(monitor_info.szDevice, NULL, NULL, NULL); |
| 33 if (hdc) { |
| 34 DWORD path_length = MAX_PATH; |
| 35 WCHAR path[MAX_PATH + 1]; |
| 36 BOOL result = ::GetICMProfile(hdc, &path_length, path); |
| 37 ::DeleteDC(hdc); |
| 38 if (result) |
| 39 profile_path = base::string16(path); |
| 40 } |
| 41 |
| 42 std::map<base::string16, base::string16>* device_to_path_map = |
| 43 reinterpret_cast<std::map<base::string16, base::string16>*>(data); |
| 44 (*device_to_path_map)[device_name] = profile_path; |
| 45 return TRUE; |
| 46 } |
| 47 |
| 48 } // namespace |
| 49 |
| 50 ColorProfileReader::ColorProfileReader(Client* client) |
| 51 : client_(client), weak_factory_(this) {} |
| 52 |
| 53 ColorProfileReader::~ColorProfileReader() {} |
| 54 |
| 55 void ColorProfileReader::UpdateIfNeeded() { |
| 56 if (update_in_flight_) |
| 57 return; |
| 58 |
| 59 DeviceToPathMap new_device_to_path_map = BuildDeviceToPathMap(); |
| 60 if (device_to_path_map_ == new_device_to_path_map) |
| 61 return; |
| 62 |
| 63 if (!base::SequencedWorkerPool::IsEnabled()) |
| 64 return; |
| 65 |
| 66 update_in_flight_ = true; |
| 67 base::PostTaskWithTraitsAndReplyWithResult( |
| 68 FROM_HERE, {base::MayBlock(), base::TaskPriority::BACKGROUND}, |
| 69 base::Bind(&ColorProfileReader::ReadProfilesOnBackgroundThread, |
| 70 new_device_to_path_map), |
| 71 base::Bind(&ColorProfileReader::ReadProfilesCompleted, |
| 72 weak_factory_.GetWeakPtr())); |
| 73 } |
| 74 |
| 75 // static |
| 76 ColorProfileReader::DeviceToPathMap ColorProfileReader::BuildDeviceToPathMap() { |
| 77 DeviceToPathMap device_to_path_map; |
| 78 EnumDisplayMonitors(nullptr, nullptr, EnumMonitorCallback, |
| 79 reinterpret_cast<LPARAM>(&device_to_path_map)); |
| 80 return device_to_path_map; |
| 81 } |
| 82 |
| 83 // static |
| 84 ColorProfileReader::DeviceToDataMap |
| 85 ColorProfileReader::ReadProfilesOnBackgroundThread( |
| 86 DeviceToPathMap new_device_to_path_map) { |
| 87 DeviceToDataMap new_device_to_data_map; |
| 88 for (auto entry : new_device_to_path_map) { |
| 89 const base::string16& device_name = entry.first; |
| 90 const base::string16& profile_path = entry.second; |
| 91 std::string profile_data; |
| 92 base::ReadFileToString(base::FilePath(profile_path), &profile_data); |
| 93 new_device_to_data_map[device_name] = profile_data; |
| 94 } |
| 95 return new_device_to_data_map; |
| 96 } |
| 97 |
| 98 void ColorProfileReader::ReadProfilesCompleted( |
| 99 DeviceToDataMap device_to_data_map) { |
| 100 DCHECK(update_in_flight_); |
| 101 update_in_flight_ = false; |
| 102 |
| 103 display_id_to_color_space_map_.clear(); |
| 104 for (auto entry : device_to_data_map) { |
| 105 const base::string16& device_name = entry.first; |
| 106 const std::string& profile_data = entry.second; |
| 107 int64_t display_id = |
| 108 DisplayInfo::DeviceIdFromDeviceName(device_name.c_str()); |
| 109 |
| 110 if (profile_data.empty()) { |
| 111 display_id_to_color_space_map_[display_id] = default_color_space_; |
| 112 } else { |
| 113 display_id_to_color_space_map_[display_id] = |
| 114 gfx::ICCProfile::FromData(profile_data.data(), profile_data.size()) |
| 115 .GetColorSpace(); |
| 116 } |
| 117 } |
| 118 |
| 119 client_->OnColorProfilesChanged(); |
| 120 } |
| 121 |
| 122 const gfx::ColorSpace& ColorProfileReader::GetDisplayColorSpace( |
| 123 int64_t display_id) const { |
| 124 auto found = display_id_to_color_space_map_.find(display_id); |
| 125 if (found == display_id_to_color_space_map_.end()) |
| 126 return default_color_space_; |
| 127 return found->second; |
| 128 } |
| 129 |
| 130 } // namespace win |
| 131 } // namespace display |
| OLD | NEW |