Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(139)

Side by Side Diff: ui/gfx/win/physical_size.cc

Issue 1563183008: Added capability on Windows to get the physical dimensions of your attached monitors. Also added th… (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: . Created 4 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« ui/gfx/win/physical_size.h ('K') | « ui/gfx/win/physical_size.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2016 The Chromium Authors. All rights reserved.
scottmg 2016/01/09 01:00:05 I think there's not supposed to be any "(c)" any m
Bret 2016/01/12 00:23:47 Done.
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/gfx/win/physical_size.h"
6
7 #include <windows.h>
8 #include <setupapi.h>
9 #include <tchar.h>
10
11 #include "base/logging.h"
12 #include "base/memory/scoped_ptr.h"
13 #include "base/scoped_generic.h"
14
15 const GUID GUID_DEVICEINTERFACE_MONITOR = {
scottmg 2016/01/09 01:00:05 Any documentation URL you could add for this magic
Bret 2016/01/12 00:23:47 Done.
16 0xE6F07B5F, 0xEE97, 0x4A90, 0xB0, 0x76, 0x33, 0xF5, 0x7B, 0xF4, 0xEA, 0xA7};
17
18 namespace {
19
20 struct DeviceInfoListScopedTraits {
21 static HDEVINFO InvalidValue() { return INVALID_HANDLE_VALUE; }
22
23 static void Free(HDEVINFO h) { SetupDiDestroyDeviceInfoList(h); }
24 };
25
26 bool GetSizeFromRegistry(HDEVINFO device_info_list,
27 SP_DEVINFO_DATA& device_info,
28 int* width_mm,
29 int* height_mm) {
30 HKEY reg_key = SetupDiOpenDevRegKey(device_info_list, &device_info,
31 DICS_FLAG_GLOBAL, 0, DIREG_DEV, KEY_READ);
32
33 if (reg_key == INVALID_HANDLE_VALUE)
34 return false;
35
36 TCHAR value_name[256];
scottmg 2016/01/09 01:00:05 We don't generally use TCHAR, _t, etc., just wchar
Bret 2016/01/12 00:23:47 Done.
37 DWORD value_name_length = sizeof(value_name);
38 DWORD data_type;
39 BYTE data[128];
40 DWORD data_length = sizeof(data);
41
42 bool found = false;
43 int reg_value_index = 0;
44 while (ERROR_SUCCESS == RegEnumValue(reg_key, reg_value_index, &value_name[0],
scottmg 2016/01/09 01:00:05 Can you use base/win/registry.h RegKey for this? ~
Bret 2016/01/12 00:23:47 Done.
45 &value_name_length, NULL, &data_type,
scottmg 2016/01/09 01:00:06 NULL -> nullptr throughout.
Bret 2016/01/12 00:23:47 Done.
46 &data[0], &data_length)) {
47 if (_tcscmp(_T("EDID"), value_name) == 0) {
48 // byte 54 is the start of the required descriptor block that contains the
49 // required timing information with the highest preference, and 12 bytes
50 // into that block is the size information
51 // 66: width least significant bits
52 // 67: height least significant bits
53 // 68: 4 bits for each of height and width (respectively) most
scottmg 2016/01/09 01:00:05 "height and width (respectively)" sounds to me lik
Bret 2016/01/12 00:23:47 Yeah that's confusing. I'll just let the bitmask s
54 // significant bits
55 *width_mm = ((data[68] & 0xF0) << 4) + data[66];
56 *height_mm = ((data[68] & 0x0F) << 8) + data[67];
57 found = true;
scottmg 2016/01/09 01:00:05 Break here?
Bret 2016/01/12 00:23:47 Done.
58 }
59 ++reg_value_index;
60 }
61
62 RegCloseKey(reg_key);
63 return found;
64 }
65
66 void GetInterfaceDetailAndDeviceInfo(
67 HDEVINFO device_info_list,
68 SP_DEVICE_INTERFACE_DATA& interface_data,
69 scoped_ptr<SP_DEVICE_INTERFACE_DETAIL_DATA, base::FreeDeleter>*
70 interface_detail,
71 SP_DEVINFO_DATA* device_info) {
72 device_info->cbSize = sizeof(SP_DEVINFO_DATA);
73 int buffer_size;
74 SetupDiGetDeviceInterfaceDetail(device_info_list, &interface_data, NULL, 0,
75 (PDWORD)&buffer_size, device_info);
scottmg 2016/01/09 01:00:05 Check that this returns false and GetLastError() i
scottmg 2016/01/09 01:00:06 No c-style casts. I think buffer_size can just be
Bret 2016/01/12 00:23:47 Done.
Bret 2016/01/12 00:23:47 Done.
76 interface_detail->reset(
77 reinterpret_cast<SP_DEVICE_INTERFACE_DETAIL_DATA*>(malloc(buffer_size)));
78 (*interface_detail)->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
79 SetupDiGetDeviceInterfaceDetail(device_info_list, &interface_data,
80 interface_detail->get(), buffer_size, NULL,
81 NULL);
scottmg 2016/01/09 01:00:05 And that this one succeeds.
Bret 2016/01/12 00:23:47 Done.
82 }
83
84 } // namespace
85
86 namespace gfx {
87
88 void GetPhysicalSizeForDisplays(std::vector<DisplaySize>* out) {
robliao 2016/01/11 18:42:20 Can this be part of ScreenWin Display generation?
Bret 2016/01/12 00:23:47 It could, but I'm not clear on what the advantage
robliao 2016/01/12 01:00:37 Most, if not all calls to Display are quick cached
89 DCHECK(out);
90
91 // get a handle to the list of device interfaces that are monitors via Setup
scottmg 2016/01/09 01:00:05 Capitals start and periods at the end of comments/
Bret 2016/01/12 00:23:47 Done.
92 base::ScopedGeneric<HDEVINFO, DeviceInfoListScopedTraits> device_info_list(
93 SetupDiGetClassDevs(&GUID_DEVICEINTERFACE_MONITOR, NULL, NULL,
94 DIGCF_PRESENT | DIGCF_DEVICEINTERFACE));
95
96 if (!device_info_list.is_valid())
97 return;
98
99 // loop over the device interfaces present according to Setup
100 SP_DEVICE_INTERFACE_DATA interface_data = {0};
101 interface_data.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
102 int interface_index = 0;
103 while (SetupDiEnumDeviceInterfaces(device_info_list.get(), NULL,
104 &GUID_DEVICEINTERFACE_MONITOR,
105 interface_index, &interface_data)) {
106 scoped_ptr<SP_DEVICE_INTERFACE_DETAIL_DATA, base::FreeDeleter>
107 interface_detail;
108 SP_DEVINFO_DATA device_info = {0};
109 // this gives us the device path that we need to associate the device
110 // interface from Setup with the display device from EnumDisplayDevices
111 GetInterfaceDetailAndDeviceInfo(device_info_list.get(), interface_data,
112 &interface_detail, &device_info);
113
114 // loop over the display interfaces via EnumDisplayDevices. this will give
115 // us the device name and allow us to loop over its attached monitors
116 DISPLAY_DEVICE display_device = {0};
117 display_device.cb = sizeof(DISPLAY_DEVICE);
118 int display_index = 0;
119 while (EnumDisplayDevices(NULL, display_index, &display_device,
120 EDD_GET_DEVICE_INTERFACE_NAME)) {
121 // loop over the monitors attached to the display interface. this gives us
122 // the device ID that associates the monitor with the setup device path
123 // from the earlier step
124 DISPLAY_DEVICE attached_device = {0};
125 attached_device.cb = sizeof(DISPLAY_DEVICE);
126 int attached_index = 0;
127 while (EnumDisplayDevices(display_device.DeviceName, attached_index,
128 &attached_device,
129 EDD_GET_DEVICE_INTERFACE_NAME)) {
130 TCHAR* attached_device_id = attached_device.DeviceID;
131 TCHAR* setup_device_path = interface_detail->DevicePath;
132 if (_tcsicmp(attached_device_id, setup_device_path) == 0) {
133 // we've found the monitor that matches the Setup device
134 int width_mm;
135 int height_mm;
136 bool found = GetSizeFromRegistry(device_info_list.get(), device_info,
137 &width_mm, &height_mm);
138 if (found) {
139 DisplaySize size(display_device.DeviceName, width_mm, height_mm);
140 out->push_back(size);
141 }
142 break;
143 }
144 ++attached_index;
145 }
146
147 ++display_index;
148 }
149
150 ++interface_index;
151 }
152 }
153
154 } // namespace gfx
OLDNEW
« ui/gfx/win/physical_size.h ('K') | « ui/gfx/win/physical_size.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698