Chromium Code Reviews| Index: base/win/win_util.cc |
| diff --git a/base/win/win_util.cc b/base/win/win_util.cc |
| index 69e14e4f6aac04ca330890a177975e15dafc4039..ad18e702f3912c31cf89359da6253f163fe66a64 100644 |
| --- a/base/win/win_util.cc |
| +++ b/base/win/win_util.cc |
| @@ -5,6 +5,7 @@ |
| #include "base/win/win_util.h" |
| #include <aclapi.h> |
| +#include <cfgmgr32.h> |
| #include <lm.h> |
| #include <powrprof.h> |
| #include <shellapi.h> |
| @@ -14,6 +15,7 @@ |
| #include <propkey.h> |
| #include <propvarutil.h> |
| #include <sddl.h> |
| +#include <setupapi.h> |
| #include <signal.h> |
| #include <stdlib.h> |
| @@ -53,6 +55,65 @@ const wchar_t kWindows8OSKRegPath[] = |
| L"Software\\Classes\\CLSID\\{054AAE20-4BEA-4347-8A35-64A533254A9D}" |
| L"\\LocalServer32"; |
| +// Returns true if a physical keyboard is detected on Windows 8 and up. |
| +// Uses the Setup APIs to enumerate the attached keyboards and returns true |
| +// if the keyboard count is more than 1. While this will work in most cases |
| +// it won't work if there are devices which expose keyboard interfaces which |
| +// are attached to the machine. |
| +bool IsKeyboardPresent() { |
|
cpu_(ooo_6.6-7.5)
2014/10/16 18:11:33
please rename this to IsKeyboardPresentOnSlate()
ananta
2014/10/16 19:35:58
Done.
|
| + // This function is only supported for Windows 8 and up. |
| + if (base::win::GetVersion() < base::win::VERSION_WIN8) { |
| + DCHECK(false); |
| + return true; |
| + } |
| + |
| + // This function should be only invoked for machines with touch screens. |
| + if ((GetSystemMetrics(SM_DIGITIZER) & NID_INTEGRATED_TOUCH) |
| + != NID_INTEGRATED_TOUCH) { |
| + DCHECK(false); |
| + return true; |
| + } |
| + |
| + const GUID KEYBOARD_CLASS_GUID = |
| + { 0x4D36E96B, 0xE325, 0x11CE, |
| + { 0xBF, 0xC1, 0x08, 0x00, 0x2B, 0xE1, 0x03, 0x18 } }; |
| + |
| + // Query for all the keyboard devices. |
| + HDEVINFO device_info = |
| + SetupDiGetClassDevs(&KEYBOARD_CLASS_GUID, NULL, NULL, DIGCF_PRESENT); |
| + if (device_info == INVALID_HANDLE_VALUE) |
| + return false; |
| + |
| + // Enumerate all keyboards and look for ACPI\PNP and HID\VID devices. If |
| + // the count is more than 1 we assume that a keyboard is present. This is |
| + // under the assumption that there will always be one keyboard device. |
| + bool has_keyboard = false; |
|
scottmg
2014/10/16 18:30:46
this is unused
ananta
2014/10/16 19:35:58
Done.
|
| + int32 keyboard_count = 0; |
|
scottmg
2014/10/16 18:30:46
just int
ananta
2014/10/16 19:35:58
Done.
|
| + for (int i = 0;; ++i) { |
| + SP_DEVINFO_DATA device_info_data = { 0 }; |
| + device_info_data.cbSize = sizeof (device_info_data); |
| + if (!SetupDiEnumDeviceInfo(device_info, i, &device_info_data)) |
| + break; |
|
scottmg
2014/10/16 18:30:46
maybe continue?
ananta
2014/10/16 19:35:58
The loop above continues indefinitely. That would
|
| + // Get the device ID |
|
cpu_(ooo_6.6-7.5)
2014/10/16 18:11:33
period at the end of comments.
ananta
2014/10/16 19:35:58
Done.
|
| + WCHAR device_id[MAX_DEVICE_ID_LEN]; |
|
cpu_(ooo_6.6-7.5)
2014/10/16 18:11:33
WCHAR --> wchar_t
ananta
2014/10/16 19:35:58
Done.
|
| + CONFIGRET status = CM_Get_Device_ID(device_info_data.DevInst, |
| + device_id, |
| + MAX_DEVICE_ID_LEN, |
| + 0); |
| + if (status == CR_SUCCESS) { |
| + // To reduce the scope of the hack we only look for PNP and HID |
| + // keyboards. |
| + if (!base::strncmp16(L"ACPI\\PNP", device_id, wcslen(L"ACPI\\PNP")) || |
| + !base::strncmp16(L"HID\\VID", device_id, wcslen(L"HID\\VID"))) { |
|
cpu_(ooo_6.6-7.5)
2014/10/16 18:11:33
use StartsWith( and set it to be case insensitive?
ananta
2014/10/16 19:35:58
Done.
|
| + keyboard_count++; |
| + } |
| + } else { |
| + break; |
|
scottmg
2014/10/16 18:30:46
maybe no else to check any others?
ananta
2014/10/16 19:35:58
Good point. Done.
|
| + } |
| + } |
|
cpu_(ooo_6.6-7.5)
2014/10/16 18:11:33
comment explaining why > 1.
ananta
2014/10/16 19:35:58
Done.
|
| + return keyboard_count > 1; |
| +} |
| + |
| } // namespace |
| namespace base { |
| @@ -252,6 +313,9 @@ bool DisplayVirtualKeyboard() { |
| if (base::win::GetVersion() < base::win::VERSION_WIN8) |
| return false; |
| + if (IsKeyboardPresent()) |
| + return false; |
| + |
| static base::LazyInstance<string16>::Leaky osk_path = |
| LAZY_INSTANCE_INITIALIZER; |