Rev 3709 | 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 |
||
3709 | clevermous | 28 | ends |
29 | |||
30 | ; This procedure is called when HID layer detects a new mouse. |
||
31 | ; in: ebx -> device_data from USB layer, edi -> collection |
||
32 | ; out: eax = device-specific data or NULL on error |
||
33 | proc mouse_driver_add_device |
||
34 | ; Just allocate memory; no initialization needed. |
||
3711 | clevermous | 35 | movi eax, sizeof.mouse_device_data |
36 | call Kmalloc |
||
37 | ret |
||
3709 | clevermous | 38 | endp |
39 | |||
40 | ; This procedure is called when HID layer detects disconnect of a previously |
||
41 | ; connected mouse. |
||
42 | ; in: edi -> mouse_device_data (pointer returned from mouse_driver_add_device) |
||
43 | proc mouse_driver_disconnect |
||
44 | ; Free the allocated memory. |
||
3711 | clevermous | 45 | mov eax, edi |
46 | call Kfree |
||
47 | ret |
||
3709 | clevermous | 48 | endp |
49 | |||
50 | ; This procedure is called when HID layer starts processing a new input packet |
||
51 | ; from a mouse. |
||
52 | ; in: edi -> mouse_device_data (pointer returned from mouse_driver_add_device) |
||
53 | proc mouse_driver_begin_packet |
||
54 | ; Zero all variables describing the current state. |
||
3711 | clevermous | 55 | mov [edi+mouse_device_data.buttons], 0 |
56 | mov [edi+mouse_device_data.dx], 0 |
||
57 | mov [edi+mouse_device_data.dy], 0 |
||
58 | mov [edi+mouse_device_data.wheel], 0 |
||
59 | ret |
||
3709 | clevermous | 60 | endp |
61 | |||
62 | ; This procedure is called when HID layer processes every non-empty array field group. |
||
63 | ; in: edi -> mouse_device_data (pointer returned from mouse_driver_add_device) |
||
64 | ; in: ecx = fields count (always nonzero), edx = pointer to fields values |
||
65 | ; in: esi -> report_field_group |
||
66 | ; out: CF set => array is ok, CF cleared => array should be ignored |
||
67 | proc mouse_driver_array_overflow? |
||
68 | ; no array fields, no overflows |
||
3711 | clevermous | 69 | stc |
70 | ret |
||
3709 | clevermous | 71 | endp |
72 | |||
73 | ; This procedure is called from HID layer for every field. |
||
74 | ; in: edi -> mouse_device_data (pointer returned from mouse_driver_add_device) |
||
75 | ; in: ecx = field usage, edx = value, esi -> report_field_group |
||
76 | proc mouse_driver_input_field |
||
77 | ; 1. Determine the handler. We process x/y moving, wheel and up to 32 buttons. |
||
78 | ; Pass other fields to the default handler - default_driver_input_field if |
||
79 | ; HID_DUMP_UNCLAIMED is enabled, just ignore otherwise. |
||
3711 | clevermous | 80 | cmp ecx, USAGE_GD_X |
81 | jz .x |
||
82 | cmp ecx, USAGE_GD_Y |
||
83 | jz .y |
||
84 | cmp ecx, USAGE_GD_WHEEL |
||
85 | jz .wheel |
||
86 | sub ecx, USAGE_BUTTON_PAGE + 1 |
||
87 | jb .unclaimed |
||
88 | cmp ecx, 32 |
||
89 | jae .unclaimed |
||
3709 | clevermous | 90 | ; 2. This is a button. |
91 | ; If a button is pressed, set the corresponding bit in the state. |
||
92 | ; If a button is not pressed, do nothing. |
||
3711 | clevermous | 93 | test edx, edx |
94 | jz @f |
||
95 | bts [edi+mouse_device_data.buttons], ecx |
||
3709 | clevermous | 96 | @@: |
97 | if ~HID_DUMP_UNCLAIMED |
||
98 | .unclaimed: |
||
99 | end if |
||
3711 | clevermous | 100 | ret |
3709 | clevermous | 101 | if HID_DUMP_UNCLAIMED |
102 | .unclaimed: |
||
3711 | clevermous | 103 | add ecx, USAGE_BUTTON_PAGE + 1 |
104 | jmp default_driver_input_field |
||
3709 | clevermous | 105 | end if |
106 | .x: |
||
107 | ; 3. This is x moving. For relative fields, store the value in the state. |
||
108 | ; Pass absolute field to the default handler. |
||
3711 | clevermous | 109 | test byte [esi+report_field_group.flags], HID_FIELD_RELATIVE |
110 | jz .unclaimed |
||
111 | mov [edi+mouse_device_data.dx], edx |
||
112 | ret |
||
3709 | clevermous | 113 | .y: |
114 | ; 4. This is y moving. For relative fields, store the value in the state, |
||
115 | ; changing the sign: HID uses "mathematics" scheme with Y axis increasing from |
||
116 | ; bottom to top, the kernel expects "programming" PS/2-style with Y axis |
||
117 | ; increasing from top to bottom. |
||
118 | ; Pass absolute fields to the default handler. |
||
3711 | clevermous | 119 | test byte [esi+report_field_group.flags], HID_FIELD_RELATIVE |
120 | jz .unclaimed |
||
121 | neg edx |
||
122 | mov [edi+mouse_device_data.dy], edx |
||
123 | ret |
||
3709 | clevermous | 124 | .wheel: |
125 | ; 5. This is wheel event. For relative fields, store the value in the state, |
||
126 | ; changing the sign. Pass absolute fields to the default handler. |
||
3711 | clevermous | 127 | test byte [esi+report_field_group.flags], HID_FIELD_RELATIVE |
128 | jz .unclaimed |
||
129 | neg edx |
||
130 | mov [edi+mouse_device_data.wheel], edx |
||
131 | ret |
||
3709 | clevermous | 132 | endp |
133 | |||
134 | ; This procedure is called when HID layer ends processing a new input packet |
||
135 | ; from a mouse. |
||
136 | ; in: edi -> mouse_device_data (pointer returned from mouse_driver_add_device) |
||
137 | proc mouse_driver_end_packet |
||
138 | ; Call the kernel, passing collected state. |
||
3711 | clevermous | 139 | stdcall SetMouseData, \ |
140 | [edi+mouse_device_data.buttons], \ |
||
141 | [edi+mouse_device_data.dx], \ |
||
142 | [edi+mouse_device_data.dy], \ |
||
143 | [edi+mouse_device_data.wheel], \ |
||
144 | |||
145 | ret |
||
3709 | clevermous | 146 | endp |