OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "base/win/win_util.h" | 5 #include "base/win/win_util.h" |
6 | 6 |
7 #include <aclapi.h> | 7 #include <aclapi.h> |
8 #include <cfgmgr32.h> | |
8 #include <lm.h> | 9 #include <lm.h> |
9 #include <powrprof.h> | 10 #include <powrprof.h> |
10 #include <shellapi.h> | 11 #include <shellapi.h> |
11 #include <shlobj.h> | 12 #include <shlobj.h> |
12 #include <shobjidl.h> // Must be before propkey. | 13 #include <shobjidl.h> // Must be before propkey. |
13 #include <initguid.h> | 14 #include <initguid.h> |
14 #include <propkey.h> | 15 #include <propkey.h> |
15 #include <propvarutil.h> | 16 #include <propvarutil.h> |
16 #include <sddl.h> | 17 #include <sddl.h> |
18 #include <setupapi.h> | |
17 #include <signal.h> | 19 #include <signal.h> |
18 #include <stdlib.h> | 20 #include <stdlib.h> |
19 | 21 |
20 #include "base/lazy_instance.h" | 22 #include "base/lazy_instance.h" |
21 #include "base/logging.h" | 23 #include "base/logging.h" |
22 #include "base/memory/scoped_ptr.h" | 24 #include "base/memory/scoped_ptr.h" |
23 #include "base/strings/string_util.h" | 25 #include "base/strings/string_util.h" |
24 #include "base/strings/stringprintf.h" | 26 #include "base/strings/stringprintf.h" |
25 #include "base/threading/thread_restrictions.h" | 27 #include "base/threading/thread_restrictions.h" |
26 #include "base/win/metro.h" | 28 #include "base/win/metro.h" |
(...skipping 19 matching lines...) Expand all Loading... | |
46 } | 48 } |
47 | 49 |
48 void __cdecl ForceCrashOnSigAbort(int) { | 50 void __cdecl ForceCrashOnSigAbort(int) { |
49 *((int*)0) = 0x1337; | 51 *((int*)0) = 0x1337; |
50 } | 52 } |
51 | 53 |
52 const wchar_t kWindows8OSKRegPath[] = | 54 const wchar_t kWindows8OSKRegPath[] = |
53 L"Software\\Classes\\CLSID\\{054AAE20-4BEA-4347-8A35-64A533254A9D}" | 55 L"Software\\Classes\\CLSID\\{054AAE20-4BEA-4347-8A35-64A533254A9D}" |
54 L"\\LocalServer32"; | 56 L"\\LocalServer32"; |
55 | 57 |
58 // Returns true if a physical keyboard is detected on Windows 8 and up. | |
59 // Uses the Setup APIs to enumerate the attached keyboards and returns true | |
60 // if the keyboard count is more than 1. While this will work in most cases | |
61 // it won't work if there are devices which expose keyboard interfaces which | |
62 // are attached to the machine. | |
63 bool IsKeyboardPresentOnSlate() { | |
64 // This function is only supported for Windows 8 and up. | |
65 if (base::win::GetVersion() < base::win::VERSION_WIN8) { | |
Lei Zhang
2014/10/20 21:53:15
Since this function is internal to win_util.cc, th
ananta
2014/10/20 22:00:13
Done.
| |
66 DCHECK(false); | |
67 return true; | |
68 } | |
69 | |
70 // This function should be only invoked for machines with touch screens. | |
71 if ((GetSystemMetrics(SM_DIGITIZER) & NID_INTEGRATED_TOUCH) | |
72 != NID_INTEGRATED_TOUCH) { | |
73 return true; | |
74 } | |
75 | |
76 const GUID KEYBOARD_CLASS_GUID = | |
77 { 0x4D36E96B, 0xE325, 0x11CE, | |
78 { 0xBF, 0xC1, 0x08, 0x00, 0x2B, 0xE1, 0x03, 0x18 } }; | |
79 | |
80 // Query for all the keyboard devices. | |
81 HDEVINFO device_info = | |
82 SetupDiGetClassDevs(&KEYBOARD_CLASS_GUID, NULL, NULL, DIGCF_PRESENT); | |
83 if (device_info == INVALID_HANDLE_VALUE) | |
84 return false; | |
85 | |
86 // Enumerate all keyboards and look for ACPI\PNP and HID\VID devices. If | |
87 // the count is more than 1 we assume that a keyboard is present. This is | |
88 // under the assumption that there will always be one keyboard device. | |
89 int keyboard_count = 0; | |
90 for (int i = 0;; ++i) { | |
Lei Zhang
2014/10/20 21:53:15
Does the compiler care about int vs DWORD?
ananta
2014/10/20 22:00:13
They are the same size. Changed for correctness to
| |
91 SP_DEVINFO_DATA device_info_data = { 0 }; | |
92 device_info_data.cbSize = sizeof (device_info_data); | |
Lei Zhang
2014/10/20 21:53:15
nit: sizeof(
ananta
2014/10/20 22:00:13
Done.
| |
93 if (!SetupDiEnumDeviceInfo(device_info, i, &device_info_data)) | |
94 break; | |
95 // Get the device ID. | |
96 wchar_t device_id[MAX_DEVICE_ID_LEN]; | |
97 CONFIGRET status = CM_Get_Device_ID(device_info_data.DevInst, | |
98 device_id, | |
99 MAX_DEVICE_ID_LEN, | |
100 0); | |
101 if (status == CR_SUCCESS) { | |
102 // To reduce the scope of the hack we only look for PNP and HID | |
103 // keyboards. | |
104 if (StartsWith(L"ACPI\\PNP", device_id, false) || | |
105 StartsWith(L"HID\\VID", device_id, false)) { | |
106 keyboard_count++; | |
107 } | |
108 } | |
109 } | |
110 // On a Windows machine, the API's always report 1 keyboard at least | |
111 // regardless of whether the machine has a keyboard attached or not. | |
112 // The heuristic we are using is to check the count and return true | |
113 // if the API's report more than one keyboard. Please note that this | |
114 // will break for non keyboard devices which expose a keyboard PDO. | |
115 return keyboard_count > 1; | |
116 } | |
117 | |
56 } // namespace | 118 } // namespace |
57 | 119 |
58 namespace base { | 120 namespace base { |
59 namespace win { | 121 namespace win { |
60 | 122 |
61 static bool g_crash_on_process_detach = false; | 123 static bool g_crash_on_process_detach = false; |
62 | 124 |
63 #define NONCLIENTMETRICS_SIZE_PRE_VISTA \ | 125 #define NONCLIENTMETRICS_SIZE_PRE_VISTA \ |
64 SIZEOF_STRUCT_WITH_SPECIFIED_LAST_MEMBER(NONCLIENTMETRICS, lfMessageFont) | 126 SIZEOF_STRUCT_WITH_SPECIFIED_LAST_MEMBER(NONCLIENTMETRICS, lfMessageFont) |
65 | 127 |
(...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
245 if (mobile_power_profile || slate_power_profile) | 307 if (mobile_power_profile || slate_power_profile) |
246 return (GetSystemMetrics(SM_CONVERTIBLESLATEMODE) == 0); | 308 return (GetSystemMetrics(SM_CONVERTIBLESLATEMODE) == 0); |
247 | 309 |
248 return false; | 310 return false; |
249 } | 311 } |
250 | 312 |
251 bool DisplayVirtualKeyboard() { | 313 bool DisplayVirtualKeyboard() { |
252 if (base::win::GetVersion() < base::win::VERSION_WIN8) | 314 if (base::win::GetVersion() < base::win::VERSION_WIN8) |
253 return false; | 315 return false; |
254 | 316 |
317 if (IsKeyboardPresentOnSlate()) | |
318 return false; | |
319 | |
255 static base::LazyInstance<string16>::Leaky osk_path = | 320 static base::LazyInstance<string16>::Leaky osk_path = |
256 LAZY_INSTANCE_INITIALIZER; | 321 LAZY_INSTANCE_INITIALIZER; |
257 | 322 |
258 if (osk_path.Get().empty()) { | 323 if (osk_path.Get().empty()) { |
259 // We need to launch TabTip.exe from the location specified under the | 324 // We need to launch TabTip.exe from the location specified under the |
260 // LocalServer32 key for the {{054AAE20-4BEA-4347-8A35-64A533254A9D}} | 325 // LocalServer32 key for the {{054AAE20-4BEA-4347-8A35-64A533254A9D}} |
261 // CLSID. | 326 // CLSID. |
262 // TabTip.exe is typically found at | 327 // TabTip.exe is typically found at |
263 // c:\program files\common files\microsoft shared\ink on English Windows. | 328 // c:\program files\common files\microsoft shared\ink on English Windows. |
264 // We don't want to launch TabTip.exe from | 329 // We don't want to launch TabTip.exe from |
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
410 #if defined(_MSC_FULL_VER) | 475 #if defined(_MSC_FULL_VER) |
411 #pragma message(__PPOUT__(_MSC_FULL_VER)) | 476 #pragma message(__PPOUT__(_MSC_FULL_VER)) |
412 #endif | 477 #endif |
413 | 478 |
414 #pragma message("Visual Studio 2012 x86 must be updated to at least Update 1") | 479 #pragma message("Visual Studio 2012 x86 must be updated to at least Update 1") |
415 #error Must install Update 1 to Visual Studio 2012. | 480 #error Must install Update 1 to Visual Studio 2012. |
416 #endif | 481 #endif |
417 | 482 |
418 #endif // _MSC_VER | 483 #endif // _MSC_VER |
419 | 484 |
OLD | NEW |