1 // Copyright 2019 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 "device/vr/windows_mixed_reality/wrappers/wmr_input_source_state.h"
6 
7 #include <windows.perception.spatial.h>
8 #include <windows.ui.input.spatial.h>
9 
10 #include <wrl.h>
11 
12 #include "base/logging.h"
13 #include "device/vr/windows_mixed_reality/wrappers/wmr_input_location.h"
14 #include "device/vr/windows_mixed_reality/wrappers/wmr_input_source.h"
15 #include "device/vr/windows_mixed_reality/wrappers/wmr_origins.h"
16 #include "device/vr/windows_mixed_reality/wrappers/wmr_pointer_pose.h"
17 
18 using ABI::Windows::UI::Input::Spatial::ISpatialInteractionControllerProperties;
19 using ABI::Windows::UI::Input::Spatial::ISpatialInteractionSource;
20 using ABI::Windows::UI::Input::Spatial::ISpatialInteractionSourceLocation;
21 using ABI::Windows::UI::Input::Spatial::ISpatialInteractionSourceProperties;
22 using ABI::Windows::UI::Input::Spatial::ISpatialInteractionSourceState;
23 using ABI::Windows::UI::Input::Spatial::ISpatialInteractionSourceState2;
24 using ABI::Windows::UI::Input::Spatial::ISpatialPointerPose;
25 using Microsoft::WRL::ComPtr;
26 
27 namespace device {
28 
WMRInputSourceStateImpl(ComPtr<ISpatialInteractionSourceState> source_state)29 WMRInputSourceStateImpl::WMRInputSourceStateImpl(
30     ComPtr<ISpatialInteractionSourceState> source_state)
31     : source_state_(source_state) {
32   DCHECK(source_state_);
33   HRESULT hr = source_state_.As(&source_state2_);
34   DCHECK(SUCCEEDED(hr));
35 
36   hr = source_state_->get_Properties(&properties_);
37   DCHECK(SUCCEEDED(hr));
38 
39   source_state2_->get_ControllerProperties(&controller_properties_);
40 }
41 
42 WMRInputSourceStateImpl::WMRInputSourceStateImpl(
43     const WMRInputSourceStateImpl& other) = default;
44 
45 WMRInputSourceStateImpl::~WMRInputSourceStateImpl() = default;
46 
47 // ISpatialInteractionSourceState
TryGetPointerPose(const WMRCoordinateSystem * origin) const48 std::unique_ptr<WMRPointerPose> WMRInputSourceStateImpl::TryGetPointerPose(
49     const WMRCoordinateSystem* origin) const {
50   ComPtr<ISpatialPointerPose> pointer_pose_wmr;
51   HRESULT hr =
52       source_state_->TryGetPointerPose(origin->GetRawPtr(), &pointer_pose_wmr);
53 
54   if (SUCCEEDED(hr) && pointer_pose_wmr) {
55     return std::make_unique<WMRPointerPoseImpl>(pointer_pose_wmr);
56   }
57 
58   return nullptr;
59 }
60 
GetSource() const61 std::unique_ptr<WMRInputSource> WMRInputSourceStateImpl::GetSource() const {
62   ComPtr<ISpatialInteractionSource> source;
63   HRESULT hr = source_state_->get_Source(&source);
64   DCHECK(SUCCEEDED(hr));
65   return std::make_unique<WMRInputSourceImpl>(source);
66 }
67 
IsGrasped() const68 bool WMRInputSourceStateImpl::IsGrasped() const {
69   boolean val;
70   HRESULT hr = source_state2_->get_IsGrasped(&val);
71   DCHECK(SUCCEEDED(hr));
72   return val;
73 }
74 
IsSelectPressed() const75 bool WMRInputSourceStateImpl::IsSelectPressed() const {
76   boolean val;
77   HRESULT hr = source_state2_->get_IsSelectPressed(&val);
78   DCHECK(SUCCEEDED(hr));
79   return val;
80 }
81 
SelectPressedValue() const82 double WMRInputSourceStateImpl::SelectPressedValue() const {
83   DOUBLE val;
84   HRESULT hr = source_state2_->get_SelectPressedValue(&val);
85   DCHECK(SUCCEEDED(hr));
86   return val;
87 }
88 
SupportsControllerProperties() const89 bool WMRInputSourceStateImpl::SupportsControllerProperties() const {
90   return controller_properties_ != nullptr;
91 }
92 
IsThumbstickPressed() const93 bool WMRInputSourceStateImpl::IsThumbstickPressed() const {
94   DCHECK(SupportsControllerProperties());
95   boolean val;
96   HRESULT hr = controller_properties_->get_IsThumbstickPressed(&val);
97   DCHECK(SUCCEEDED(hr));
98   return val;
99 }
100 
IsTouchpadPressed() const101 bool WMRInputSourceStateImpl::IsTouchpadPressed() const {
102   DCHECK(SupportsControllerProperties());
103   boolean val;
104   HRESULT hr = controller_properties_->get_IsTouchpadPressed(&val);
105   DCHECK(SUCCEEDED(hr));
106   return val;
107 }
108 
IsTouchpadTouched() const109 bool WMRInputSourceStateImpl::IsTouchpadTouched() const {
110   DCHECK(SupportsControllerProperties());
111   boolean val;
112   HRESULT hr = controller_properties_->get_IsTouchpadTouched(&val);
113   DCHECK(SUCCEEDED(hr));
114   return val;
115 }
116 
ThumbstickX() const117 double WMRInputSourceStateImpl::ThumbstickX() const {
118   DCHECK(SupportsControllerProperties());
119   DOUBLE val;
120   HRESULT hr = controller_properties_->get_ThumbstickX(&val);
121   DCHECK(SUCCEEDED(hr));
122   return val;
123 }
124 
ThumbstickY() const125 double WMRInputSourceStateImpl::ThumbstickY() const {
126   DCHECK(SupportsControllerProperties());
127   DOUBLE val;
128   HRESULT hr = controller_properties_->get_ThumbstickY(&val);
129   DCHECK(SUCCEEDED(hr));
130   return val;
131 }
132 
TouchpadX() const133 double WMRInputSourceStateImpl::TouchpadX() const {
134   DCHECK(SupportsControllerProperties());
135   DOUBLE val;
136   HRESULT hr = controller_properties_->get_TouchpadX(&val);
137   DCHECK(SUCCEEDED(hr));
138   return val;
139 }
140 
TouchpadY() const141 double WMRInputSourceStateImpl::TouchpadY() const {
142   DCHECK(SupportsControllerProperties());
143   DOUBLE val;
144   HRESULT hr = controller_properties_->get_TouchpadY(&val);
145   DCHECK(SUCCEEDED(hr));
146   return val;
147 }
148 
TryGetLocation(const WMRCoordinateSystem * origin) const149 std::unique_ptr<WMRInputLocation> WMRInputSourceStateImpl::TryGetLocation(
150     const WMRCoordinateSystem* origin) const {
151   ComPtr<ISpatialInteractionSourceLocation> location_wmr;
152   if (FAILED(properties_->TryGetLocation(origin->GetRawPtr(), &location_wmr)) ||
153       !location_wmr)
154     return nullptr;
155 
156   return std::make_unique<WMRInputLocationImpl>(location_wmr);
157 }
158 
159 }  // namespace device
160