Rev 4592 | 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 |
||
35 | ; Just allocate memory; no initialization needed. |
||
3711 | clevermous | 36 | movi eax, sizeof.mouse_device_data |
5051 | clevermous | 37 | invoke Kmalloc |
3711 | clevermous | 38 | ret |
3709 | clevermous | 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. |
||
3711 | clevermous | 46 | mov eax, edi |
5051 | clevermous | 47 | invoke Kfree |
3711 | clevermous | 48 | ret |
3709 | clevermous | 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. |
||
3711 | clevermous | 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 |
||
3741 | clevermous | 60 | mov [edi+mouse_device_data.hwheel], 0 |
3711 | clevermous | 61 | ret |
3709 | clevermous | 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 |
||
3711 | clevermous | 71 | stc |
72 | ret |
||
3709 | clevermous | 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. |
||
3711 | clevermous | 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 |
||
3741 | clevermous | 88 | cmp ecx, 0xC0238 |
89 | jz .hwheel |
||
3711 | clevermous | 90 | sub ecx, USAGE_BUTTON_PAGE + 1 |
91 | jb .unclaimed |
||
92 | cmp ecx, 32 |
||
93 | jae .unclaimed |
||
3709 | clevermous | 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. |
||
3711 | clevermous | 97 | test edx, edx |
98 | jz @f |
||
99 | bts [edi+mouse_device_data.buttons], ecx |
||
3709 | clevermous | 100 | @@: |
101 | if ~HID_DUMP_UNCLAIMED |
||
102 | .unclaimed: |
||
103 | end if |
||
3711 | clevermous | 104 | ret |
3709 | clevermous | 105 | if HID_DUMP_UNCLAIMED |
106 | .unclaimed: |
||
3711 | clevermous | 107 | add ecx, USAGE_BUTTON_PAGE + 1 |
108 | jmp default_driver_input_field |
||
3709 | clevermous | 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. |
||
3711 | clevermous | 113 | test byte [esi+report_field_group.flags], HID_FIELD_RELATIVE |
4530 | hidnplayr | 114 | jz .absolute_x |
3711 | clevermous | 115 | mov [edi+mouse_device_data.dx], edx |
116 | ret |
||
3709 | clevermous | 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. |
||
3711 | clevermous | 123 | test byte [esi+report_field_group.flags], HID_FIELD_RELATIVE |
4530 | hidnplayr | 124 | jz .absolute_y |
3711 | clevermous | 125 | neg edx |
126 | mov [edi+mouse_device_data.dy], edx |
||
127 | ret |
||
3709 | clevermous | 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. |
||
3711 | clevermous | 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 |
||
3741 | clevermous | 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 |
||
4530 | hidnplayr | 141 | .absolute_x: |
4592 | hidnplayr | 142 | mov [edi+mouse_device_data.dx], edx |
4529 | hidnplayr | 143 | or [edi+mouse_device_data.buttons], 0x80000000 |
144 | ret |
||
4530 | hidnplayr | 145 | .absolute_y: |
4592 | hidnplayr | 146 | mov [edi+mouse_device_data.dy], edx |
4529 | hidnplayr | 147 | or [edi+mouse_device_data.buttons], 0x40000000 |
148 | ret |
||
3709 | clevermous | 149 | endp |
150 | |||
151 | ; This procedure is called when HID layer ends processing a new input packet |
||
152 | ; from a mouse. |
||
153 | ; in: edi -> mouse_device_data (pointer returned from mouse_driver_add_device) |
||
154 | proc mouse_driver_end_packet |
||
155 | ; Call the kernel, passing collected state. |
||
5051 | clevermous | 156 | invoke SetMouseData, \ |
3711 | clevermous | 157 | [edi+mouse_device_data.buttons], \ |
158 | [edi+mouse_device_data.dx], \ |
||
159 | [edi+mouse_device_data.dy], \ |
||
160 | [edi+mouse_device_data.wheel], \ |
||
3741 | clevermous | 161 | [edi+mouse_device_data.hwheel] |
3711 | clevermous | 162 | ret |
3709 | clevermous | 163 | endp |