| OLD | NEW |
| (Empty) | |
| 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 |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #include "ui/base/x/valuators.h" |
| 6 |
| 7 #include <X11/extensions/XInput2.h> |
| 8 |
| 9 #include "base/memory/singleton.h" |
| 10 #include "ui/base/touch/touch_factory_x11.h" |
| 11 #include "ui/base/x/device_list_cache_x.h" |
| 12 #include "ui/base/x/x11_util.h" |
| 13 |
| 14 namespace { |
| 15 |
| 16 #define AXIS_LABEL_ABS_MT_TOUCH_MAJOR "Abs MT Touch Major" |
| 17 #define AXIS_LABEL_ABS_MT_TOUCH_MINOR "Abs MT Touch Minor" |
| 18 #define AXIS_LABEL_ABS_MT_ORIENTATION "Abs MT Orientation" |
| 19 #define AXIS_LABEL_ABS_MT_PRESSURE "Abs MT Pressure" |
| 20 #define AXIS_LABEL_ABS_MT_SLOT_ID "Abs MT Slot ID" |
| 21 #define AXIS_LABEL_ABS_MT_TRACKING_ID "Abs MT Tracking ID" |
| 22 #define AXIS_LABEL_TOUCH_TIMESTAMP "Touch Timestamp" |
| 23 |
| 24 // Given the Valuator, return the correspoding XIValuatorClassInfo using |
| 25 // the X device information through Atom name matching. |
| 26 XIValuatorClassInfo* FindValuator(Display* display, |
| 27 XIDeviceInfo* info, |
| 28 ui::ValuatorTracker::Valuator val) { |
| 29 // Lookup table for mapping Valuator to Atom string used in X. |
| 30 // A full set of Atom strings can be found at xserver-properties.h. |
| 31 static struct { |
| 32 ui::ValuatorTracker::Valuator val; |
| 33 Atom atom; |
| 34 } kValuatorAtom[] = { |
| 35 { ui::ValuatorTracker::VAL_TOUCH_MAJOR, |
| 36 XInternAtom(ui::GetXDisplay(), AXIS_LABEL_ABS_MT_TOUCH_MAJOR, false) }, |
| 37 { ui::ValuatorTracker::VAL_TOUCH_MINOR, |
| 38 XInternAtom(ui::GetXDisplay(), AXIS_LABEL_ABS_MT_TOUCH_MINOR, false) }, |
| 39 { ui::ValuatorTracker::VAL_ORIENTATION, |
| 40 XInternAtom(ui::GetXDisplay(), AXIS_LABEL_ABS_MT_ORIENTATION, false) }, |
| 41 { ui::ValuatorTracker::VAL_PRESSURE, |
| 42 XInternAtom(ui::GetXDisplay(), AXIS_LABEL_ABS_MT_PRESSURE, false) }, |
| 43 #if !defined(USE_XI2_MT) |
| 44 // For Slot ID, See this chromeos revision: http://git.chromium.org/gitweb/? |
| 45 // p=chromiumos/overlays/chromiumos-overlay.git; |
| 46 // a=commit;h=9164d0a75e48c4867e4ef4ab51f743ae231c059a |
| 47 { ui::ValuatorTracker::VAL_SLOT_ID, |
| 48 XInternAtom(ui::GetXDisplay(), AXIS_LABEL_ABS_MT_SLOT_ID, false) }, |
| 49 #endif |
| 50 { ui::ValuatorTracker::VAL_TRACKING_ID, |
| 51 XInternAtom(ui::GetXDisplay(), AXIS_LABEL_ABS_MT_TRACKING_ID, false) }, |
| 52 { ui::ValuatorTracker::VAL_TOUCH_RAW_TIMESTAMP, |
| 53 XInternAtom(ui::GetXDisplay(), AXIS_LABEL_TOUCH_TIMESTAMP, false) }, |
| 54 { ui::ValuatorTracker::VAL_LAST_ENTRY, None }, |
| 55 }; |
| 56 |
| 57 Atom atom = None; |
| 58 |
| 59 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kValuatorAtom); i++) { |
| 60 if (val == kValuatorAtom[i].val) { |
| 61 atom = kValuatorAtom[i].atom; |
| 62 break; |
| 63 } |
| 64 } |
| 65 |
| 66 if (atom == None) |
| 67 return NULL; |
| 68 |
| 69 for (int i = 0; i < info->num_classes; i++) { |
| 70 if (info->classes[i]->type != XIValuatorClass) |
| 71 continue; |
| 72 XIValuatorClassInfo* v = |
| 73 reinterpret_cast<XIValuatorClassInfo*>(info->classes[i]); |
| 74 if (v->label && atom == v->label) |
| 75 return v; |
| 76 } |
| 77 |
| 78 return NULL; |
| 79 } |
| 80 |
| 81 } // namespace |
| 82 |
| 83 namespace ui { |
| 84 |
| 85 ValuatorTracker::ValuatorTracker() { |
| 86 SetupValuator(); |
| 87 } |
| 88 |
| 89 ValuatorTracker::~ValuatorTracker() { |
| 90 } |
| 91 |
| 92 // static |
| 93 ValuatorTracker* ValuatorTracker::GetInstance() { |
| 94 return Singleton<ValuatorTracker>::get(); |
| 95 } |
| 96 |
| 97 bool ValuatorTracker::ExtractValuator(const XEvent& xev, |
| 98 Valuator val, |
| 99 double* value) { |
| 100 XIDeviceEvent* xiev = static_cast<XIDeviceEvent*>(xev.xcookie.data); |
| 101 if (xiev->sourceid >= kMaxDeviceNum || xiev->deviceid >= kMaxDeviceNum) |
| 102 return false; |
| 103 int val_index = valuator_lookup_[xiev->sourceid][val]; |
| 104 if (val_index >= 0) { |
| 105 if (XIMaskIsSet(xiev->valuators.mask, val_index)) { |
| 106 double* valuators = xiev->valuators.values; |
| 107 while (val_index--) { |
| 108 if (XIMaskIsSet(xiev->valuators.mask, val_index)) |
| 109 ++valuators; |
| 110 } |
| 111 *value = *valuators; |
| 112 last_seen_valuator_[xiev->deviceid][val] = *value; |
| 113 return true; |
| 114 } else { |
| 115 *value = last_seen_valuator_[xiev->deviceid][val]; |
| 116 } |
| 117 } |
| 118 |
| 119 #if defined(USE_XI2_MT) |
| 120 // With XInput2 MT, Tracking ID is provided in the detail field. |
| 121 if (val == VAL_TRACKING_ID) { |
| 122 *value = xiev->detail; |
| 123 return true; |
| 124 } |
| 125 #endif |
| 126 |
| 127 return false; |
| 128 } |
| 129 |
| 130 bool ValuatorTracker::NormalizeValuator(unsigned int deviceid, |
| 131 Valuator val, |
| 132 double* value) { |
| 133 double max_value; |
| 134 double min_value; |
| 135 if (GetValuatorRange(deviceid, val, &min_value, &max_value)) { |
| 136 *value = (*value - min_value) / (max_value - min_value); |
| 137 DCHECK(*value >= 0.0 && *value <= 1.0); |
| 138 return true; |
| 139 } |
| 140 return false; |
| 141 } |
| 142 |
| 143 bool ValuatorTracker::GetValuatorRange(unsigned int deviceid, |
| 144 Valuator val, |
| 145 double* min, |
| 146 double* max) { |
| 147 if (valuator_lookup_[deviceid][val] >= 0) { |
| 148 *min = valuator_min_[deviceid][val]; |
| 149 *max = valuator_max_[deviceid][val]; |
| 150 return true; |
| 151 } |
| 152 return false; |
| 153 } |
| 154 |
| 155 void ValuatorTracker::SetupValuator() { |
| 156 memset(valuator_lookup_, -1, sizeof(valuator_lookup_)); |
| 157 memset(valuator_min_, 0, sizeof(valuator_min_)); |
| 158 memset(valuator_max_, 0, sizeof(valuator_max_)); |
| 159 memset(last_seen_valuator_, 0, sizeof(last_seen_valuator_)); |
| 160 |
| 161 Display* display = GetXDisplay(); |
| 162 XIDeviceList info_list = |
| 163 DeviceListCacheX::GetInstance()->GetXI2DeviceList(display); |
| 164 TouchFactory* factory = TouchFactory::GetInstance(); |
| 165 |
| 166 for (int i = 0; i < info_list.count; i++) { |
| 167 XIDeviceInfo* info = info_list.devices + i; |
| 168 |
| 169 if (!factory->IsTouchDevice(info->deviceid)) |
| 170 continue; |
| 171 |
| 172 for (int j = 0; j < VAL_LAST_ENTRY; j++) { |
| 173 Valuator val = static_cast<Valuator>(j); |
| 174 XIValuatorClassInfo* valuator = FindValuator(display, info, val); |
| 175 if (valuator) { |
| 176 valuator_lookup_[info->deviceid][j] = valuator->number; |
| 177 valuator_min_[info->deviceid][j] = valuator->min; |
| 178 valuator_max_[info->deviceid][j] = valuator->max; |
| 179 } |
| 180 } |
| 181 } |
| 182 } |
| 183 |
| 184 } // namespace ui |
| OLD | NEW |