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