Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / tools / usb_gadget / mouse_gadget.py
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.
4
5 """Implementation of a USB HID mouse.
6
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 """
11
12 import struct
13
14 import hid_constants
15 import hid_descriptors
16 import hid_gadget
17 import usb_constants
18
19
20 class MouseFeature(hid_gadget.HidFeature):
21   """HID feature implementation for a mouse.
22
23   REPORT_DESC provides an example HID report descriptor for a device including
24   this functionality.
25   """
26
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)
58           )
59       )
60   )
61
62   def __init__(self):
63     super(MouseFeature, self).__init__()
64     self._buttons = 0
65
66   def ButtonDown(self, button):
67     self._buttons |= button
68     if self.IsConnected():
69       self.SendReport(self.EncodeInputReport())
70
71   def ButtonUp(self, button):
72     self._buttons &= ~button
73     if self.IsConnected():
74       self.SendReport(self.EncodeInputReport())
75
76   def Move(self, x_displacement, y_displacement):
77     if self.IsConnected():
78       self.SendReport(self.EncodeInputReport(x_displacement, y_displacement))
79
80   def EncodeInputReport(self, x_displacement=0, y_displacement=0):
81     return struct.pack('Bbb', self._buttons, x_displacement, y_displacement)
82
83   def GetInputReport(self):
84     """Construct an input report.
85
86     See Device Class Definition for Human Interface Devices (HID) Version 1.11
87     Appendix B.2.
88
89     Returns:
90       A packed input report.
91     """
92     return self.EncodeInputReport()
93
94
95 class MouseGadget(hid_gadget.HidGadget):
96   """USB gadget implementation of a HID mouse."""
97
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')
111
112   def ButtonDown(self, button):
113     self._feature.ButtonDown(button)
114
115   def ButtonUp(self, button):
116     self._feature.ButtonUp(button)
117
118   def Move(self, x_displacement, y_displacement):
119     self._feature.Move(x_displacement, y_displacement)
120
121
122 def RegisterHandlers():
123   """Registers web request handlers with the application server."""
124
125   from tornado import web
126
127   class WebConfigureHandler(web.RequestHandler):
128
129     def post(self):
130       gadget = MouseGadget()
131       server.SwitchGadget(gadget)
132
133   class WebClickHandler(web.RequestHandler):
134
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,
140       }
141
142       button = BUTTONS[self.get_argument('button')]
143       server.gadget.ButtonDown(button)
144       server.gadget.ButtonUp(button)
145
146   class WebMoveHandler(web.RequestHandler):
147
148     def post(self):
149       x = int(self.get_argument('x'))
150       y = int(self.get_argument('y'))
151       server.gadget.Move(x, y)
152
153   import server
154   server.app.add_handlers('.*$', [
155       (r'/mouse/configure', WebConfigureHandler),
156       (r'/mouse/move', WebMoveHandler),
157       (r'/mouse/click', WebClickHandler),
158   ])