File: pointer_device_win.cc

package info (click to toggle)
chromium 138.0.7204.183-1
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 6,071,908 kB
  • sloc: cpp: 34,937,088; ansic: 7,176,967; javascript: 4,110,704; python: 1,419,953; asm: 946,768; xml: 739,971; pascal: 187,324; sh: 89,623; perl: 88,663; objc: 79,944; sql: 50,304; cs: 41,786; fortran: 24,137; makefile: 21,806; php: 13,980; tcl: 13,166; yacc: 8,925; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (138 lines) | stat: -rw-r--r-- 4,725 bytes parent folder | download | duplicates (8)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
// Copyright 2012 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "ui/base/pointer/pointer_device.h"

#include <algorithm>

#include "base/check_op.h"
#include "base/notreached.h"
#include "base/win/win_util.h"
#include "ui/base/win/hidden_window.h"

namespace ui {

namespace {

bool IsTouchDevicePresent() {
  int value = GetSystemMetrics(SM_DIGITIZER);
  return (value & NID_READY) &&
         ((value & NID_INTEGRATED_TOUCH) || (value & NID_EXTERNAL_TOUCH));
}

PointerDigitizerType ToPointerDigitizerType(
    POINTER_DEVICE_TYPE pointer_device_type) {
  switch (pointer_device_type) {
    case POINTER_DEVICE_TYPE_INTEGRATED_PEN:
      return PointerDigitizerType::kDirectPen;
    case POINTER_DEVICE_TYPE_EXTERNAL_PEN:
      return PointerDigitizerType::kIndirectPen;
    case POINTER_DEVICE_TYPE_TOUCH:
      return PointerDigitizerType::kTouch;
    case POINTER_DEVICE_TYPE_TOUCH_PAD:
      return PointerDigitizerType::kTouchPad;
    default:
      return PointerDigitizerType::kUnknown;
  }
}

PointerDevice ToPointerDevice(const POINTER_DEVICE_INFO& device) {
  return {.key = device.device,
          .digitizer = ToPointerDigitizerType(device.pointerDeviceType),
          .max_active_contacts = device.maxActiveContacts};
}

}  // namespace

// The following method logic is as follow :
// - On versions prior to Windows 8 it will always return POINTER_TYPE_FINE
// and/or POINTER_TYPE_COARSE (if the device has a touch screen).
// - If the device is a detachable/convertible device and the keyboard/trackpad
// is detached/flipped it will always return POINTER_TYPE_COARSE.
// It does not cover the case where an external mouse/keyboard is connected
// while the device is used as a tablet. This is because Windows doesn't provide
// us a reliable way to detect keyboard/mouse presence with
// GetSystemMetrics(SM_MOUSEPRESENT).
// - If the device doesn't have a touch screen it will return POINTER_TYPE_FINE.
// In the rare cases (this is Microsoft documentation) where
// GetSystemMetrics(SM_MOUSEPRESENT) returns 0 we will return POINTER_TYPE_NONE.
// - If the device has a touch screen the available pointer devices are
// POINTER_TYPE_FINE and POINTER_TYPE_COARSE.
int GetAvailablePointerTypes() {
  // IsTabletDevice guarantees us that :
  // - The device has a touch screen.
  // - It is used as a tablet which means that it has no keyboard connected.
  // On Windows 10 it means that it is verifying with ConvertibleSlateMode.
  if (base::win::IsDeviceUsedAsATablet(nullptr))
    return POINTER_TYPE_COARSE;

  bool is_touch_device_present = IsTouchDevicePresent();

  if (GetSystemMetrics(SM_MOUSEPRESENT) == 0 && !is_touch_device_present)
    return POINTER_TYPE_NONE;

  int available_pointer_types = POINTER_TYPE_FINE;
  if (is_touch_device_present)
    available_pointer_types |= POINTER_TYPE_COARSE;

  return available_pointer_types;
}

// This method follows the same logic as above but with hover types.
int GetAvailableHoverTypes() {
  if (base::win::IsDeviceUsedAsATablet(nullptr))
    return HOVER_TYPE_NONE;

  if (GetSystemMetrics(SM_MOUSEPRESENT) != 0)
    return HOVER_TYPE_HOVER;

  return HOVER_TYPE_NONE;
}

TouchScreensAvailability GetTouchScreensAvailability() {
  if (!IsTouchDevicePresent())
    return TouchScreensAvailability::NONE;

  return TouchScreensAvailability::ENABLED;
}

int MaxTouchPoints() {
  return IsTouchDevicePresent() ? GetSystemMetrics(SM_MAXIMUMTOUCHES) : 0;
}

PointerType GetPrimaryPointerType(int available_pointer_types) {
  if (available_pointer_types & POINTER_TYPE_FINE)
    return POINTER_TYPE_FINE;
  if (available_pointer_types & POINTER_TYPE_COARSE)
    return POINTER_TYPE_COARSE;
  DCHECK_EQ(available_pointer_types, POINTER_TYPE_NONE);
  return POINTER_TYPE_NONE;
}

HoverType GetPrimaryHoverType(int available_hover_types) {
  if (available_hover_types & HOVER_TYPE_HOVER)
    return HOVER_TYPE_HOVER;
  DCHECK_EQ(available_hover_types, HOVER_TYPE_NONE);
  return HOVER_TYPE_NONE;
}

std::optional<PointerDevice> GetPointerDevice(PointerDevice::Key key) {
  POINTER_DEVICE_INFO device;
  return base::win::GetPointerDevice(key, device)
             ? std::make_optional(ToPointerDevice(device))
             : std::nullopt;
}

std::vector<PointerDevice> GetPointerDevices() {
  std::vector<PointerDevice> result;
  if (std::optional<std::vector<POINTER_DEVICE_INFO>> pointer_devices =
          base::win::GetPointerDevices()) {
    result.reserve(pointer_devices->size());
    std::transform(pointer_devices->cbegin(), pointer_devices->cend(),
                   std::back_inserter(result), &ToPointerDevice);
  }
  return result;
}

}  // namespace ui