Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
4287 | Serge | 1 | ; HID mouse driver, part of USBHID driver. |
2 | |||
3 | ; Global constants. |
||
4 | ; They are assembled in a macro to separate code and data; |
||
5 | ; the code is located at the point of "include 'mouse.inc'", |
||
6 | ; the data are collected when workers_globals is instantiated. |
||
7 | macro workers_globals |
||
8 | { |
||
9 | ; include global constants from previous workers |
||
10 | workers_globals |
||
11 | align 4 |
||
12 | ; Callbacks for HID layer. |
||
13 | mouse_driver: |
||
14 | dd mouse_driver_add_device |
||
15 | dd mouse_driver_disconnect |
||
16 | dd mouse_driver_begin_packet |
||
17 | dd mouse_driver_array_overflow? |
||
18 | dd mouse_driver_input_field |
||
19 | dd mouse_driver_end_packet |
||
20 | } |
||
21 | |||
22 | ; Data that are specific for one mouse device. |
||
23 | struct mouse_device_data |
||
24 | buttons dd ? ; buttons that are currently pressed |
||
25 | dx dd ? ; current x moving |
||
26 | dy dd ? ; current y moving |
||
27 | wheel dd ? ; current wheel moving |
||
28 | hwheel dd ? |
||
29 | ends |
||
30 | |||
31 | ; This procedure is called when HID layer detects a new mouse. |
||
32 | ; in: ebx -> device_data from USB layer, edi -> collection |
||
33 | ; out: eax = device-specific data or NULL on error |
||
34 | proc mouse_driver_add_device |
||
35 | ; Just allocate memory; no initialization needed. |
||
36 | movi eax, sizeof.mouse_device_data |
||
37 | call Kmalloc |
||
38 | ret |
||
39 | endp |
||
40 | |||
41 | ; This procedure is called when HID layer detects disconnect of a previously |
||
42 | ; connected mouse. |
||
43 | ; in: edi -> mouse_device_data (pointer returned from mouse_driver_add_device) |
||
44 | proc mouse_driver_disconnect |
||
45 | ; Free the allocated memory. |
||
46 | mov eax, edi |
||
47 | call Kfree |
||
48 | ret |
||
49 | endp |
||
50 | |||
51 | ; This procedure is called when HID layer starts processing a new input packet |
||
52 | ; from a mouse. |
||
53 | ; in: edi -> mouse_device_data (pointer returned from mouse_driver_add_device) |
||
54 | proc mouse_driver_begin_packet |
||
55 | ; Zero all variables describing the current state. |
||
56 | mov [edi+mouse_device_data.buttons], 0 |
||
57 | mov [edi+mouse_device_data.dx], 0 |
||
58 | mov [edi+mouse_device_data.dy], 0 |
||
59 | mov [edi+mouse_device_data.wheel], 0 |
||
60 | mov [edi+mouse_device_data.hwheel], 0 |
||
61 | ret |
||
62 | endp |
||
63 | |||
64 | ; This procedure is called when HID layer processes every non-empty array field group. |
||
65 | ; in: edi -> mouse_device_data (pointer returned from mouse_driver_add_device) |
||
66 | ; in: ecx = fields count (always nonzero), edx = pointer to fields values |
||
67 | ; in: esi -> report_field_group |
||
68 | ; out: CF set => array is ok, CF cleared => array should be ignored |
||
69 | proc mouse_driver_array_overflow? |
||
70 | ; no array fields, no overflows |
||
71 | stc |
||
72 | ret |
||
73 | endp |
||
74 | |||
75 | ; This procedure is called from HID layer for every field. |
||
76 | ; in: edi -> mouse_device_data (pointer returned from mouse_driver_add_device) |
||
77 | ; in: ecx = field usage, edx = value, esi -> report_field_group |
||
78 | proc mouse_driver_input_field |
||
79 | ; 1. Determine the handler. We process x/y moving, wheel and up to 32 buttons. |
||
80 | ; Pass other fields to the default handler - default_driver_input_field if |
||
81 | ; HID_DUMP_UNCLAIMED is enabled, just ignore otherwise. |
||
82 | cmp ecx, USAGE_GD_X |
||
83 | jz .x |
||
84 | cmp ecx, USAGE_GD_Y |
||
85 | jz .y |
||
86 | cmp ecx, USAGE_GD_WHEEL |
||
87 | jz .wheel |
||
88 | cmp ecx, 0xC0238 |
||
89 | jz .hwheel |
||
90 | sub ecx, USAGE_BUTTON_PAGE + 1 |
||
91 | jb .unclaimed |
||
92 | cmp ecx, 32 |
||
93 | jae .unclaimed |
||
94 | ; 2. This is a button. |
||
95 | ; If a button is pressed, set the corresponding bit in the state. |
||
96 | ; If a button is not pressed, do nothing. |
||
97 | test edx, edx |
||
98 | jz @f |
||
99 | bts [edi+mouse_device_data.buttons], ecx |
||
100 | @@: |
||
101 | if ~HID_DUMP_UNCLAIMED |
||
102 | .unclaimed: |
||
103 | end if |
||
104 | ret |
||
105 | if HID_DUMP_UNCLAIMED |
||
106 | .unclaimed: |
||
107 | add ecx, USAGE_BUTTON_PAGE + 1 |
||
108 | jmp default_driver_input_field |
||
109 | end if |
||
110 | .x: |
||
111 | ; 3. This is x moving. For relative fields, store the value in the state. |
||
112 | ; Pass absolute field to the default handler. |
||
113 | test byte [esi+report_field_group.flags], HID_FIELD_RELATIVE |
||
114 | jz .unclaimed |
||
115 | mov [edi+mouse_device_data.dx], edx |
||
116 | ret |
||
117 | .y: |
||
118 | ; 4. This is y moving. For relative fields, store the value in the state, |
||
119 | ; changing the sign: HID uses "mathematics" scheme with Y axis increasing from |
||
120 | ; bottom to top, the kernel expects "programming" PS/2-style with Y axis |
||
121 | ; increasing from top to bottom. |
||
122 | ; Pass absolute fields to the default handler. |
||
123 | test byte [esi+report_field_group.flags], HID_FIELD_RELATIVE |
||
124 | jz .unclaimed |
||
125 | neg edx |
||
126 | mov [edi+mouse_device_data.dy], edx |
||
127 | ret |
||
128 | .wheel: |
||
129 | ; 5. This is wheel event. For relative fields, store the value in the state, |
||
130 | ; changing the sign. Pass absolute fields to the default handler. |
||
131 | test byte [esi+report_field_group.flags], HID_FIELD_RELATIVE |
||
132 | jz .unclaimed |
||
133 | neg edx |
||
134 | mov [edi+mouse_device_data.wheel], edx |
||
135 | ret |
||
136 | .hwheel: |
||
137 | test byte [esi+report_field_group.flags], HID_FIELD_RELATIVE |
||
138 | jz .unclaimed |
||
139 | mov [edi+mouse_device_data.hwheel], edx |
||
140 | ret |
||
141 | endp |
||
142 | |||
143 | ; This procedure is called when HID layer ends processing a new input packet |
||
144 | ; from a mouse. |
||
145 | ; in: edi -> mouse_device_data (pointer returned from mouse_driver_add_device) |
||
146 | proc mouse_driver_end_packet |
||
147 | ; Call the kernel, passing collected state. |
||
148 | stdcall SetMouseData, \ |
||
149 | [edi+mouse_device_data.buttons], \ |
||
150 | [edi+mouse_device_data.dx], \ |
||
151 | [edi+mouse_device_data.dy], \ |
||
152 | [edi+mouse_device_data.wheel], \ |
||
153 | [edi+mouse_device_data.hwheel] |
||
154 | ret |
||
155 | endp |