Subversion Repositories Kolibri OS

Rev

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