blob: b137dd769ee83530a4b7fd4d9c06db7114300019 [file] [log] [blame]
Alex Vakulenkoe4eec202017-01-27 14:41:04 -08001#include "VirtualTouchpad.h"
2
3#include <cutils/log.h>
4#include <inttypes.h>
5#include <linux/input.h>
6
7namespace android {
8namespace dvr {
9
10namespace {
11
12// Virtual evdev device properties.
13static const char* const kDeviceName = "vr window manager virtual touchpad";
14static constexpr int16_t kDeviceBusType = BUS_VIRTUAL;
15static constexpr int16_t kDeviceVendor = 0x18D1; // Google USB vendor ID.
16static constexpr int16_t kDeviceProduct = 0x5652; // 'VR'
17static constexpr int16_t kDeviceVersion = 0x0001;
18static constexpr int32_t kWidth = 0x10000;
19static constexpr int32_t kHeight = 0x10000;
20static constexpr int32_t kSlots = 2;
21
22} // anonymous namespace
23
24int VirtualTouchpad::Initialize() {
25 if (!injector_) {
26 owned_injector_.reset(new EvdevInjector());
27 injector_ = owned_injector_.get();
28 }
29 injector_->ConfigureBegin(kDeviceName, kDeviceBusType, kDeviceVendor,
30 kDeviceProduct, kDeviceVersion);
31 injector_->ConfigureInputProperty(INPUT_PROP_DIRECT);
32 injector_->ConfigureMultiTouchXY(0, 0, kWidth - 1, kHeight - 1);
33 injector_->ConfigureAbsSlots(kSlots);
34 injector_->ConfigureKey(BTN_TOUCH);
35 injector_->ConfigureEnd();
36 return injector_->GetError();
37}
38
39int VirtualTouchpad::Touch(float x, float y, float pressure) {
40 int error = 0;
41 int32_t device_x = x * kWidth;
42 int32_t device_y = y * kHeight;
43 touches_ = ((touches_ & 1) << 1) | (pressure > 0);
44 ALOGV("(%f,%f) %f -> (%" PRId32 ",%" PRId32 ") %d",
45 x, y, pressure, device_x, device_y, touches_);
46
47 injector_->ResetError();
48 switch (touches_) {
49 case 0b00: // Hover continues.
50 if (device_x != last_device_x_ || device_y != last_device_y_) {
51 injector_->SendMultiTouchXY(0, 0, device_x, device_y);
52 injector_->SendSynReport();
53 }
54 break;
55 case 0b01: // Touch begins.
56 // Press.
57 injector_->SendMultiTouchXY(0, 0, device_x, device_y);
58 injector_->SendKey(BTN_TOUCH, EvdevInjector::KEY_PRESS);
59 injector_->SendSynReport();
60 break;
61 case 0b10: // Touch ends.
62 injector_->SendKey(BTN_TOUCH, EvdevInjector::KEY_RELEASE);
63 injector_->SendMultiTouchLift(0);
64 injector_->SendSynReport();
65 break;
66 case 0b11: // Touch continues.
67 if (device_x != last_device_x_ || device_y != last_device_y_) {
68 injector_->SendMultiTouchXY(0, 0, device_x, device_y);
69 injector_->SendSynReport();
70 }
71 break;
72 }
73 last_device_x_ = device_x;
74 last_device_y_ = device_y;
75
76 return injector_->GetError();
77}
78
79} // namespace dvr
80} // namespace android