Rev 5148 | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 5148 | Rev 5294 | ||
---|---|---|---|
1 | ; HID multimedia keyboard driver, part of USBHID driver. |
1 | ; HID multimedia keyboard 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 'multimedia.inc'", |
5 | ; the code is located at the point of "include 'multimedia.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 | multimedia_driver: |
13 | multimedia_driver: |
14 | dd multimedia_driver_add_device |
14 | dd multimedia_driver_add_device |
15 | dd multimedia_driver_disconnect |
15 | dd multimedia_driver_disconnect |
16 | dd multimedia_driver_begin_packet |
16 | dd multimedia_driver_begin_packet |
17 | dd multimedia_driver_array_overflow? |
17 | dd multimedia_driver_array_overflow? |
18 | dd multimedia_driver_input_field |
18 | dd multimedia_driver_input_field |
19 | dd multimedia_driver_end_packet |
19 | dd multimedia_driver_end_packet |
20 | } |
20 | } |
21 | 21 | ||
22 | ; Data that are specific for one keyboard device. |
22 | ; Data that are specific for one keyboard device. |
23 | struct multimedia_device_data |
23 | struct multimedia_device_data |
24 | usbdev dd ? ; pointer to device_data of USB and HID layers |
24 | usbdev dd ? ; pointer to device_data of USB and HID layers |
25 | last_pressed dd ? |
25 | last_pressed dd ? |
26 | ends |
26 | ends |
27 | 27 | ||
28 | ; This procedure is called when HID layer detects a new keyboard. |
28 | ; This procedure is called when HID layer detects a new keyboard. |
29 | ; in: ebx -> usb_device_data, edi -> collection |
29 | ; in: ebx -> usb_device_data, edi -> collection |
30 | ; out: eax = device-specific data or NULL on error |
30 | ; out: eax = device-specific data or NULL on error |
31 | proc multimedia_driver_add_device |
31 | proc multimedia_driver_add_device |
32 | ; 1. Allocate memory for keyboard_device_data. If failed, return NULL. |
32 | ; 1. Allocate memory for keyboard_device_data. If failed, return NULL. |
33 | movi eax, sizeof.multimedia_device_data |
33 | movi eax, sizeof.multimedia_device_data |
34 | invoke Kmalloc |
34 | invoke Kmalloc |
35 | test eax, eax |
35 | test eax, eax |
36 | jz .nothing |
36 | jz .nothing |
37 | ; 2. Initialize keyboard_device_data: store pointer to USB layer data, |
37 | ; 2. Initialize keyboard_device_data: store pointer to USB layer data, |
38 | ; zero some fields, initialize bit positions to -1. |
38 | ; zero some fields, initialize bit positions to -1. |
39 | mov [eax+multimedia_device_data.usbdev], ebx |
39 | mov [eax+multimedia_device_data.usbdev], ebx |
40 | mov [eax+multimedia_device_data.last_pressed], 0 |
40 | mov [eax+multimedia_device_data.last_pressed], 0 |
41 | .nothing: |
41 | .nothing: |
42 | ret |
42 | ret |
43 | endp |
43 | endp |
44 | 44 | ||
45 | ; This procedure is called when HID layer detects disconnect of a previously |
45 | ; This procedure is called when HID layer detects disconnect of a previously |
46 | ; connected keyboard. |
46 | ; connected keyboard. |
47 | ; in: edi -> multimedia_device_data (pointer returned from multimedia_driver_add_device) |
47 | ; in: edi -> multimedia_device_data (pointer returned from multimedia_driver_add_device) |
48 | proc multimedia_driver_disconnect |
48 | proc multimedia_driver_disconnect |
49 | ; We should free data in CloseKeyboard, not here. |
49 | ; We should free data in CloseKeyboard, not here. |
50 | ret |
50 | ret |
51 | endp |
51 | endp |
52 | 52 | ||
53 | ; This procedure is called when HID layer starts processing a new input packet |
53 | ; This procedure is called when HID layer starts processing a new input packet |
54 | ; from a keyboard. |
54 | ; from a keyboard. |
55 | ; in: edi -> keyboard_device_data (pointer returned from keyboard_driver_add_device) |
55 | ; in: edi -> keyboard_device_data (pointer returned from keyboard_driver_add_device) |
56 | proc multimedia_driver_begin_packet |
56 | proc multimedia_driver_begin_packet |
57 | ; Nothing to do. |
57 | ; Nothing to do. |
58 | ret |
58 | ret |
59 | endp |
59 | endp |
60 | 60 | ||
61 | ; This procedure is called when HID layer processes every non-empty array field group. |
61 | ; This procedure is called when HID layer processes every non-empty array field group. |
62 | ; in: edi -> keyboard_device_data (pointer returned from keyboard_driver_add_device) |
62 | ; in: edi -> keyboard_device_data (pointer returned from keyboard_driver_add_device) |
63 | ; in: ecx = fields count (always nonzero), edx = pointer to fields values |
63 | ; in: ecx = fields count (always nonzero), edx = pointer to fields values |
64 | ; in: esi -> report_field_group |
64 | ; in: esi -> report_field_group |
65 | ; out: CF set => group is ok, CF cleared => group should be ignored |
65 | ; out: CF set => group is ok, CF cleared => group should be ignored |
66 | proc multimedia_driver_array_overflow? |
66 | proc multimedia_driver_array_overflow? |
67 | ; The keyboard signals array overflow by filling the entire array with |
67 | ; The keyboard signals array overflow by filling the entire array with |
68 | ; USAGE_KBD_ROLLOVER codes. |
68 | ; USAGE_KBD_ROLLOVER codes. |
69 | mov eax, [edx] ; eax = first field in the array |
69 | mov eax, [edx] ; eax = first field in the array |
70 | sub eax, USAGE_KBD_ROLLOVER ; eax = 0 if overflow, nonzero otherwise |
70 | sub eax, USAGE_KBD_ROLLOVER ; eax = 0 if overflow, nonzero otherwise |
71 | neg eax ; CF cleared if eax was zero, CF set if eax was nonzero |
71 | neg eax ; CF cleared if eax was zero, CF set if eax was nonzero |
72 | ret |
72 | ret |
73 | endp |
73 | endp |
74 | 74 | ||
75 | ; This procedure is called from HID layer for every field. |
75 | ; This procedure is called from HID layer for every field. |
76 | ; in: edi -> keyboard_device_data (pointer returned from keyboard_driver_add_device) |
76 | ; in: edi -> keyboard_device_data (pointer returned from keyboard_driver_add_device) |
77 | ; in: ecx = field usage, edx = value, esi -> report_field_group |
77 | ; in: ecx = field usage, edx = value, esi -> report_field_group |
78 | proc multimedia_driver_input_field |
78 | proc multimedia_driver_input_field |
79 | if HID_DUMP_UNCLAIMED |
79 | if HID_DUMP_UNCLAIMED |
80 | .unclaimed = default_driver_input_field |
80 | .unclaimed = default_driver_input_field |
81 | end if |
81 | end if |
82 | 82 | ||
83 | test edx, edx |
83 | test edx, edx |
84 | jnz @f |
84 | jnz @f |
85 | cmp [edi+multimedia_device_data.last_pressed], ecx |
85 | cmp [edi+multimedia_device_data.last_pressed], ecx |
86 | jne .nothing |
86 | jne .nothing |
87 | @@: |
87 | @@: |
88 | mov eax, 0x19 |
88 | mov eax, 0x19 |
89 | cmp ecx, USAGE_CONSUMER + 0xB5 ; Next track |
89 | cmp ecx, USAGE_CONSUMER + 0xB5 ; Next track |
90 | je .multimedia_key |
90 | je .multimedia_key |
91 | mov al, 0x10 |
91 | mov al, 0x10 |
92 | cmp ecx, USAGE_CONSUMER + 0xB6 ; Previous track |
92 | cmp ecx, USAGE_CONSUMER + 0xB6 ; Previous track |
93 | je .multimedia_key |
93 | je .multimedia_key |
94 | mov al, 0x24 |
94 | mov al, 0x24 |
95 | cmp ecx, USAGE_CONSUMER + 0xB7 ; Stop |
95 | cmp ecx, USAGE_CONSUMER + 0xB7 ; Stop |
96 | je .multimedia_key |
96 | je .multimedia_key |
97 | mov al, 0x22 |
97 | mov al, 0x22 |
98 | cmp ecx, USAGE_CONSUMER + 0xCD ; Play/pause |
98 | cmp ecx, USAGE_CONSUMER + 0xCD ; Play/pause |
99 | je .multimedia_key |
99 | je .multimedia_key |
100 | mov al, 0x20 |
100 | mov al, 0x20 |
101 | cmp ecx, USAGE_CONSUMER + 0xE2 ; Mute |
101 | cmp ecx, USAGE_CONSUMER + 0xE2 ; Mute |
102 | je .multimedia_key |
102 | je .multimedia_key |
103 | mov al, 0x30 |
103 | mov al, 0x30 |
104 | cmp ecx, USAGE_CONSUMER + 0xE9 ; Volume up |
104 | cmp ecx, USAGE_CONSUMER + 0xE9 ; Volume up |
105 | je .multimedia_key |
105 | je .multimedia_key |
106 | mov al, 0x2E |
106 | mov al, 0x2E |
107 | cmp ecx, USAGE_CONSUMER + 0xEA ; Volume down |
107 | cmp ecx, USAGE_CONSUMER + 0xEA ; Volume down |
108 | je .multimedia_key |
108 | je .multimedia_key |
109 | mov al, 0x6D |
109 | mov al, 0x6D |
110 | cmp ecx, USAGE_CONSUMER + 0x183 ; Media select |
110 | cmp ecx, USAGE_CONSUMER + 0x183 ; Media select |
111 | je .multimedia_key |
111 | je .multimedia_key |
112 | mov al, 0x6C |
112 | mov al, 0x6C |
113 | cmp ecx, USAGE_CONSUMER + 0x18A ; E-Mail |
113 | cmp ecx, USAGE_CONSUMER + 0x18A ; E-Mail |
114 | je .multimedia_key |
114 | je .multimedia_key |
115 | mov al, 0x21 |
115 | mov al, 0x21 |
116 | cmp ecx, USAGE_CONSUMER + 0x192 ; Calculator |
116 | cmp ecx, USAGE_CONSUMER + 0x192 ; Calculator |
117 | je .multimedia_key |
117 | je .multimedia_key |
118 | mov al, 0x6B |
118 | mov al, 0x6B |
119 | cmp ecx, USAGE_CONSUMER + 0x194 ; My computer |
119 | cmp ecx, USAGE_CONSUMER + 0x194 ; My computer |
120 | je .multimedia_key |
120 | je .multimedia_key |
121 | mov al, 0x65 |
121 | mov al, 0x65 |
122 | cmp ecx, USAGE_CONSUMER + 0x221 ; WWW Search |
122 | cmp ecx, USAGE_CONSUMER + 0x221 ; WWW Search |
123 | je .multimedia_key |
123 | je .multimedia_key |
124 | mov al, 0x32 |
124 | mov al, 0x32 |
125 | cmp ecx, USAGE_CONSUMER + 0x223 ; WWW Home |
125 | cmp ecx, USAGE_CONSUMER + 0x223 ; WWW Home |
126 | je .multimedia_key |
126 | je .multimedia_key |
127 | mov al, 0x6a |
127 | mov al, 0x6a |
128 | cmp ecx, USAGE_CONSUMER + 0x224 ; WWW Back |
128 | cmp ecx, USAGE_CONSUMER + 0x224 ; WWW Back |
129 | je .multimedia_key |
129 | je .multimedia_key |
130 | mov al, 0x69 |
130 | mov al, 0x69 |
131 | cmp ecx, USAGE_CONSUMER + 0x225 ; WWW forward |
131 | cmp ecx, USAGE_CONSUMER + 0x225 ; WWW forward |
132 | je .multimedia_key |
132 | je .multimedia_key |
133 | mov al, 0x68 |
133 | mov al, 0x68 |
134 | cmp ecx, USAGE_CONSUMER + 0x226 ; WWW Stop |
134 | cmp ecx, USAGE_CONSUMER + 0x226 ; WWW Stop |
135 | je .multimedia_key |
135 | je .multimedia_key |
136 | mov al, 0x67 |
136 | mov al, 0x67 |
137 | cmp ecx, USAGE_CONSUMER + 0x227 ; WWW refresh |
137 | cmp ecx, USAGE_CONSUMER + 0x227 ; WWW refresh |
138 | je .multimedia_key |
138 | je .multimedia_key |
139 | mov al, 0x66 |
139 | mov al, 0x66 |
140 | cmp ecx, USAGE_CONSUMER + 0x22A ; WWW favorites |
140 | cmp ecx, USAGE_CONSUMER + 0x22A ; WWW favorites |
141 | je .multimedia_key |
141 | je .multimedia_key |
142 | jmp .unclaimed |
142 | jmp .unclaimed |
143 | 143 | ||
144 | 144 | ||
145 | .multimedia_key: |
145 | .multimedia_key: |
146 | ; 1d. Further actions are slightly different for key press and key release. |
146 | ; 1d. Further actions are slightly different for key press and key release. |
147 | ; Decide what to do. |
147 | ; Decide what to do. |
148 | test edx, edx |
148 | test edx, edx |
149 | jz .multimedia_key_released |
149 | jz .multimedia_key_released |
150 | .multimedia_key_pressed: |
150 | .multimedia_key_pressed: |
- | 151 | mov [edi+multimedia_device_data.last_pressed], eax |
|
151 | ; The key is pressed. |
152 | ; The key is pressed. |
152 | push ecx |
153 | push eax |
153 | mov ecx, 0xE0 |
154 | mov ecx, 0xE0 |
154 | invoke SetKeyboardData |
155 | invoke SetKeyboardData |
155 | pop ecx |
156 | pop ecx |
156 | invoke SetKeyboardData |
157 | invoke SetKeyboardData |
157 | ret |
158 | ret |
158 | 159 | ||
159 | .multimedia_key_released: |
160 | .multimedia_key_released: |
160 | mov [edi+multimedia_device_data.last_pressed], 0 |
161 | mov [edi+multimedia_device_data.last_pressed], 0 |
161 | ; The key is released. |
162 | ; The key is released. |
162 | or cl, 0x80 |
163 | or cl, 0x80 |
163 | push ecx |
164 | push eax |
164 | mov ecx, 0xE0 |
165 | mov ecx, 0xE0 |
165 | invoke SetKeyboardData |
166 | invoke SetKeyboardData |
166 | pop ecx |
167 | pop ecx |
167 | invoke SetKeyboardData |
168 | invoke SetKeyboardData |
168 | ret |
169 | ret |
169 | .nothing: |
170 | .nothing: |
170 | ret |
171 | ret |
171 | 172 | ||
172 | endp |
173 | endp |
173 | 174 | ||
174 | ; This procedure is called when HID layer ends processing a new input packet |
175 | ; This procedure is called when HID layer ends processing a new input packet |
175 | ; from a keyboard. |
176 | ; from a keyboard. |
176 | ; in: edi -> keyboard_device_data (pointer returned from keyboard_driver_add_device) |
177 | ; in: edi -> keyboard_device_data (pointer returned from keyboard_driver_add_device) |
177 | proc multimedia_driver_end_packet |
178 | proc multimedia_driver_end_packet |
178 | ; Nothing to do. |
179 | ; Nothing to do. |
179 | ret |
180 | ret |
180 | endp |
181 | endp |