Roll src/third_party/WebKit f007c95:0171005 (svn 185074:185088)
[chromium-blink-merge.git] / tools / usb_gadget / mouse_gadget.py
blobcb4f7e8df675fa30fc4350908f5cc9bb34a39b5b
1 # Copyright 2014 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.
5 """Implementation of a USB HID mouse.
7 Two classes are provided by this module. The MouseFeature class implements
8 the core functionality of a HID mouse and can be included in any HID gadget.
9 The MouseGadget class implements an example mouse gadget.
10 """
12 import struct
14 import hid_constants
15 import hid_descriptors
16 import hid_gadget
17 import usb_constants
20 class MouseFeature(hid_gadget.HidFeature):
21 """HID feature implementation for a mouse.
23 REPORT_DESC provides an example HID report descriptor for a device including
24 this functionality.
25 """
27 REPORT_DESC = hid_descriptors.ReportDescriptor(
28 hid_descriptors.UsagePage(0x01), # Generic Desktop
29 hid_descriptors.Usage(0x02), # Mouse
30 hid_descriptors.Collection(
31 hid_constants.CollectionType.APPLICATION,
32 hid_descriptors.Usage(0x01), # Pointer
33 hid_descriptors.Collection(
34 hid_constants.CollectionType.PHYSICAL,
35 hid_descriptors.UsagePage(0x09), # Buttons
36 hid_descriptors.UsageMinimum(1),
37 hid_descriptors.UsageMaximum(3),
38 hid_descriptors.LogicalMinimum(0, force_length=1),
39 hid_descriptors.LogicalMaximum(1),
40 hid_descriptors.ReportCount(3),
41 hid_descriptors.ReportSize(1),
42 hid_descriptors.Input(hid_descriptors.Data,
43 hid_descriptors.Variable,
44 hid_descriptors.Absolute),
45 hid_descriptors.ReportCount(1),
46 hid_descriptors.ReportSize(5),
47 hid_descriptors.Input(hid_descriptors.Constant),
48 hid_descriptors.UsagePage(0x01), # Generic Desktop
49 hid_descriptors.Usage(0x30), # X
50 hid_descriptors.Usage(0x31), # Y
51 hid_descriptors.LogicalMinimum(0x81), # -127
52 hid_descriptors.LogicalMaximum(127),
53 hid_descriptors.ReportSize(8),
54 hid_descriptors.ReportCount(2),
55 hid_descriptors.Input(hid_descriptors.Data,
56 hid_descriptors.Variable,
57 hid_descriptors.Relative)
62 def __init__(self):
63 super(MouseFeature, self).__init__()
64 self._buttons = 0
66 def ButtonDown(self, button):
67 self._buttons |= button
68 if self.IsConnected():
69 self.SendReport(self.EncodeInputReport())
71 def ButtonUp(self, button):
72 self._buttons &= ~button
73 if self.IsConnected():
74 self.SendReport(self.EncodeInputReport())
76 def Move(self, x_displacement, y_displacement):
77 if self.IsConnected():
78 self.SendReport(self.EncodeInputReport(x_displacement, y_displacement))
80 def EncodeInputReport(self, x_displacement=0, y_displacement=0):
81 return struct.pack('Bbb', self._buttons, x_displacement, y_displacement)
83 def GetInputReport(self):
84 """Construct an input report.
86 See Device Class Definition for Human Interface Devices (HID) Version 1.11
87 Appendix B.2.
89 Returns:
90 A packed input report.
91 """
92 return self.EncodeInputReport()
95 class MouseGadget(hid_gadget.HidGadget):
96 """USB gadget implementation of a HID mouse."""
98 def __init__(self):
99 self._feature = MouseFeature()
100 super(MouseGadget, self).__init__(
101 report_desc=MouseFeature.REPORT_DESC,
102 features={0: self._feature},
103 packet_size=8,
104 interval_ms=1,
105 out_endpoint=False,
106 vendor_id=usb_constants.VendorID.GOOGLE,
107 product_id=usb_constants.ProductID.GOOGLE_MOUSE_GADGET,
108 device_version=0x0100)
109 self.AddStringDescriptor(1, 'Google Inc.')
110 self.AddStringDescriptor(2, 'Mouse Gadget')
112 def ButtonDown(self, button):
113 self._feature.ButtonDown(button)
115 def ButtonUp(self, button):
116 self._feature.ButtonUp(button)
118 def Move(self, x_displacement, y_displacement):
119 self._feature.Move(x_displacement, y_displacement)
122 def RegisterHandlers():
123 """Registers web request handlers with the application server."""
125 from tornado import web
127 class WebConfigureHandler(web.RequestHandler):
129 def post(self):
130 gadget = MouseGadget()
131 server.SwitchGadget(gadget)
133 class WebClickHandler(web.RequestHandler):
135 def post(self):
136 BUTTONS = {
137 '1': hid_constants.Mouse.BUTTON_1,
138 '2': hid_constants.Mouse.BUTTON_2,
139 '3': hid_constants.Mouse.BUTTON_3,
142 button = BUTTONS[self.get_argument('button')]
143 server.gadget.ButtonDown(button)
144 server.gadget.ButtonUp(button)
146 class WebMoveHandler(web.RequestHandler):
148 def post(self):
149 x = int(self.get_argument('x'))
150 y = int(self.get_argument('y'))
151 server.gadget.Move(x, y)
153 import server
154 server.app.add_handlers('.*$', [
155 (r'/mouse/configure', WebConfigureHandler),
156 (r'/mouse/move', WebMoveHandler),
157 (r'/mouse/click', WebClickHandler),