Rev 3741 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
3709 | clevermous | 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 |
||
3711 | clevermous | 10 | workers_globals |
3709 | clevermous | 11 | align 4 |
12 | ; Callbacks for HID layer. |
||
13 | mouse_driver: |
||
3711 | clevermous | 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 |
||
3709 | clevermous | 20 | } |
21 | |||
22 | ; Data that are specific for one mouse device. |
||
23 | struct mouse_device_data |
||
3711 | clevermous | 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 |
||
3741 | clevermous | 28 | hwheel dd ? |
3709 | clevermous | 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 |
||
4529 | hidnplayr | 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 |
||
3709 | clevermous | 42 | ; Just allocate memory; no initialization needed. |
3711 | clevermous | 43 | movi eax, sizeof.mouse_device_data |
44 | call Kmalloc |
||
45 | ret |
||
3709 | clevermous | 46 | endp |
47 | |||
48 | ; This procedure is called when HID layer detects disconnect of a previously |
||
49 | ; connected mouse. |
||
50 | ; in: edi -> mouse_device_data (pointer returned from mouse_driver_add_device) |
||
51 | proc mouse_driver_disconnect |
||
52 | ; Free the allocated memory. |
||
3711 | clevermous | 53 | mov eax, edi |
54 | call Kfree |
||
55 | ret |
||
3709 | clevermous | 56 | endp |
57 | |||
58 | ; This procedure is called when HID layer starts processing a new input packet |
||
59 | ; from a mouse. |
||
60 | ; in: edi -> mouse_device_data (pointer returned from mouse_driver_add_device) |
||
61 | proc mouse_driver_begin_packet |
||
62 | ; Zero all variables describing the current state. |
||
3711 | clevermous | 63 | mov [edi+mouse_device_data.buttons], 0 |
64 | mov [edi+mouse_device_data.dx], 0 |
||
65 | mov [edi+mouse_device_data.dy], 0 |
||
66 | mov [edi+mouse_device_data.wheel], 0 |
||
3741 | clevermous | 67 | mov [edi+mouse_device_data.hwheel], 0 |
3711 | clevermous | 68 | ret |
3709 | clevermous | 69 | endp |
70 | |||
71 | ; 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) |
||
73 | ; in: ecx = fields count (always nonzero), edx = pointer to fields values |
||
74 | ; in: esi -> report_field_group |
||
75 | ; out: CF set => array is ok, CF cleared => array should be ignored |
||
76 | proc mouse_driver_array_overflow? |
||
77 | ; no array fields, no overflows |
||
3711 | clevermous | 78 | stc |
79 | ret |
||
3709 | clevermous | 80 | endp |
81 | |||
82 | ; This procedure is called from HID layer for every field. |
||
83 | ; in: edi -> mouse_device_data (pointer returned from mouse_driver_add_device) |
||
84 | ; in: ecx = field usage, edx = value, esi -> report_field_group |
||
85 | proc mouse_driver_input_field |
||
86 | ; 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 |
||
88 | ; HID_DUMP_UNCLAIMED is enabled, just ignore otherwise. |
||
3711 | clevermous | 89 | cmp ecx, USAGE_GD_X |
90 | jz .x |
||
91 | cmp ecx, USAGE_GD_Y |
||
92 | jz .y |
||
93 | cmp ecx, USAGE_GD_WHEEL |
||
94 | jz .wheel |
||
3741 | clevermous | 95 | cmp ecx, 0xC0238 |
96 | jz .hwheel |
||
3711 | clevermous | 97 | sub ecx, USAGE_BUTTON_PAGE + 1 |
98 | jb .unclaimed |
||
99 | cmp ecx, 32 |
||
100 | jae .unclaimed |
||
3709 | clevermous | 101 | ; 2. This is a button. |
102 | ; If a button is pressed, set the corresponding bit in the state. |
||
103 | ; If a button is not pressed, do nothing. |
||
3711 | clevermous | 104 | test edx, edx |
105 | jz @f |
||
106 | bts [edi+mouse_device_data.buttons], ecx |
||
3709 | clevermous | 107 | @@: |
108 | if ~HID_DUMP_UNCLAIMED |
||
109 | .unclaimed: |
||
110 | end if |
||
3711 | clevermous | 111 | ret |
3709 | clevermous | 112 | if HID_DUMP_UNCLAIMED |
113 | .unclaimed: |
||
3711 | clevermous | 114 | add ecx, USAGE_BUTTON_PAGE + 1 |
115 | jmp default_driver_input_field |
||
3709 | clevermous | 116 | end if |
117 | .x: |
||
118 | ; 3. This is x moving. For relative fields, store the value in the state. |
||
119 | ; Pass absolute field to the default handler. |
||
3711 | clevermous | 120 | test byte [esi+report_field_group.flags], HID_FIELD_RELATIVE |
4529 | hidnplayr | 121 | jz .relative_x |
3711 | clevermous | 122 | mov [edi+mouse_device_data.dx], edx |
123 | ret |
||
3709 | clevermous | 124 | .y: |
125 | ; 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 |
||
127 | ; bottom to top, the kernel expects "programming" PS/2-style with Y axis |
||
128 | ; increasing from top to bottom. |
||
129 | ; Pass absolute fields to the default handler. |
||
3711 | clevermous | 130 | test byte [esi+report_field_group.flags], HID_FIELD_RELATIVE |
4529 | hidnplayr | 131 | jz .relative_y |
3711 | clevermous | 132 | neg edx |
133 | mov [edi+mouse_device_data.dy], edx |
||
134 | ret |
||
3709 | clevermous | 135 | .wheel: |
136 | ; 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. |
||
3711 | clevermous | 138 | test byte [esi+report_field_group.flags], HID_FIELD_RELATIVE |
139 | jz .unclaimed |
||
140 | neg edx |
||
141 | mov [edi+mouse_device_data.wheel], edx |
||
142 | ret |
||
3741 | clevermous | 143 | .hwheel: |
144 | test byte [esi+report_field_group.flags], HID_FIELD_RELATIVE |
||
145 | jz .unclaimed |
||
146 | mov [edi+mouse_device_data.hwheel], edx |
||
147 | ret |
||
4529 | hidnplayr | 148 | .relative_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 |
||
155 | or [edi+mouse_device_data.buttons], 0x80000000 |
||
156 | pop ebx |
||
157 | ret |
||
158 | .relative_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 |
||
165 | or [edi+mouse_device_data.buttons], 0x40000000 |
||
166 | pop ebx |
||
167 | ret |
||
3709 | clevermous | 168 | endp |
169 | |||
170 | ; This procedure is called when HID layer ends processing a new input packet |
||
171 | ; from a mouse. |
||
172 | ; in: edi -> mouse_device_data (pointer returned from mouse_driver_add_device) |
||
173 | proc mouse_driver_end_packet |
||
174 | ; Call the kernel, passing collected state. |
||
3711 | clevermous | 175 | stdcall SetMouseData, \ |
176 | [edi+mouse_device_data.buttons], \ |
||
177 | [edi+mouse_device_data.dx], \ |
||
178 | [edi+mouse_device_data.dy], \ |
||
179 | [edi+mouse_device_data.wheel], \ |
||
3741 | clevermous | 180 | [edi+mouse_device_data.hwheel] |
3711 | clevermous | 181 | ret |
3709 | clevermous | 182 | endp |