forked from KolibriOS/kolibrios
USBHID: translate USB media keys to corresponding PS/2 codes.
git-svn-id: svn://kolibrios.org@5148 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
parent
ab98cf7eab
commit
75d63bdb63
180
drivers/usb/usbhid/multimedia.inc
Normal file
180
drivers/usb/usbhid/multimedia.inc
Normal file
@ -0,0 +1,180 @@
|
|||||||
|
; HID multimedia keyboard driver, part of USBHID driver.
|
||||||
|
|
||||||
|
; Global constants.
|
||||||
|
; They are assembled in a macro to separate code and data;
|
||||||
|
; the code is located at the point of "include 'multimedia.inc'",
|
||||||
|
; the data are collected when workers_globals is instantiated.
|
||||||
|
macro workers_globals
|
||||||
|
{
|
||||||
|
; include global constants from previous workers
|
||||||
|
workers_globals
|
||||||
|
align 4
|
||||||
|
; Callbacks for HID layer.
|
||||||
|
multimedia_driver:
|
||||||
|
dd multimedia_driver_add_device
|
||||||
|
dd multimedia_driver_disconnect
|
||||||
|
dd multimedia_driver_begin_packet
|
||||||
|
dd multimedia_driver_array_overflow?
|
||||||
|
dd multimedia_driver_input_field
|
||||||
|
dd multimedia_driver_end_packet
|
||||||
|
}
|
||||||
|
|
||||||
|
; Data that are specific for one keyboard device.
|
||||||
|
struct multimedia_device_data
|
||||||
|
usbdev dd ? ; pointer to device_data of USB and HID layers
|
||||||
|
last_pressed dd ?
|
||||||
|
ends
|
||||||
|
|
||||||
|
; This procedure is called when HID layer detects a new keyboard.
|
||||||
|
; in: ebx -> usb_device_data, edi -> collection
|
||||||
|
; out: eax = device-specific data or NULL on error
|
||||||
|
proc multimedia_driver_add_device
|
||||||
|
; 1. Allocate memory for keyboard_device_data. If failed, return NULL.
|
||||||
|
movi eax, sizeof.multimedia_device_data
|
||||||
|
invoke Kmalloc
|
||||||
|
test eax, eax
|
||||||
|
jz .nothing
|
||||||
|
; 2. Initialize keyboard_device_data: store pointer to USB layer data,
|
||||||
|
; zero some fields, initialize bit positions to -1.
|
||||||
|
mov [eax+multimedia_device_data.usbdev], ebx
|
||||||
|
mov [eax+multimedia_device_data.last_pressed], 0
|
||||||
|
.nothing:
|
||||||
|
ret
|
||||||
|
endp
|
||||||
|
|
||||||
|
; This procedure is called when HID layer detects disconnect of a previously
|
||||||
|
; connected keyboard.
|
||||||
|
; in: edi -> multimedia_device_data (pointer returned from multimedia_driver_add_device)
|
||||||
|
proc multimedia_driver_disconnect
|
||||||
|
; We should free data in CloseKeyboard, not here.
|
||||||
|
ret
|
||||||
|
endp
|
||||||
|
|
||||||
|
; This procedure is called when HID layer starts processing a new input packet
|
||||||
|
; from a keyboard.
|
||||||
|
; in: edi -> keyboard_device_data (pointer returned from keyboard_driver_add_device)
|
||||||
|
proc multimedia_driver_begin_packet
|
||||||
|
; Nothing to do.
|
||||||
|
ret
|
||||||
|
endp
|
||||||
|
|
||||||
|
; This procedure is called when HID layer processes every non-empty array field group.
|
||||||
|
; in: edi -> keyboard_device_data (pointer returned from keyboard_driver_add_device)
|
||||||
|
; in: ecx = fields count (always nonzero), edx = pointer to fields values
|
||||||
|
; in: esi -> report_field_group
|
||||||
|
; out: CF set => group is ok, CF cleared => group should be ignored
|
||||||
|
proc multimedia_driver_array_overflow?
|
||||||
|
; The keyboard signals array overflow by filling the entire array with
|
||||||
|
; USAGE_KBD_ROLLOVER codes.
|
||||||
|
mov eax, [edx] ; eax = first field in the array
|
||||||
|
sub eax, USAGE_KBD_ROLLOVER ; eax = 0 if overflow, nonzero otherwise
|
||||||
|
neg eax ; CF cleared if eax was zero, CF set if eax was nonzero
|
||||||
|
ret
|
||||||
|
endp
|
||||||
|
|
||||||
|
; This procedure is called from HID layer for every field.
|
||||||
|
; in: edi -> keyboard_device_data (pointer returned from keyboard_driver_add_device)
|
||||||
|
; in: ecx = field usage, edx = value, esi -> report_field_group
|
||||||
|
proc multimedia_driver_input_field
|
||||||
|
if HID_DUMP_UNCLAIMED
|
||||||
|
.unclaimed = default_driver_input_field
|
||||||
|
end if
|
||||||
|
|
||||||
|
test edx, edx
|
||||||
|
jnz @f
|
||||||
|
cmp [edi+multimedia_device_data.last_pressed], ecx
|
||||||
|
jne .nothing
|
||||||
|
@@:
|
||||||
|
mov eax, 0x19
|
||||||
|
cmp ecx, USAGE_CONSUMER + 0xB5 ; Next track
|
||||||
|
je .multimedia_key
|
||||||
|
mov al, 0x10
|
||||||
|
cmp ecx, USAGE_CONSUMER + 0xB6 ; Previous track
|
||||||
|
je .multimedia_key
|
||||||
|
mov al, 0x24
|
||||||
|
cmp ecx, USAGE_CONSUMER + 0xB7 ; Stop
|
||||||
|
je .multimedia_key
|
||||||
|
mov al, 0x22
|
||||||
|
cmp ecx, USAGE_CONSUMER + 0xCD ; Play/pause
|
||||||
|
je .multimedia_key
|
||||||
|
mov al, 0x20
|
||||||
|
cmp ecx, USAGE_CONSUMER + 0xE2 ; Mute
|
||||||
|
je .multimedia_key
|
||||||
|
mov al, 0x30
|
||||||
|
cmp ecx, USAGE_CONSUMER + 0xE9 ; Volume up
|
||||||
|
je .multimedia_key
|
||||||
|
mov al, 0x2E
|
||||||
|
cmp ecx, USAGE_CONSUMER + 0xEA ; Volume down
|
||||||
|
je .multimedia_key
|
||||||
|
mov al, 0x6D
|
||||||
|
cmp ecx, USAGE_CONSUMER + 0x183 ; Media select
|
||||||
|
je .multimedia_key
|
||||||
|
mov al, 0x6C
|
||||||
|
cmp ecx, USAGE_CONSUMER + 0x18A ; E-Mail
|
||||||
|
je .multimedia_key
|
||||||
|
mov al, 0x21
|
||||||
|
cmp ecx, USAGE_CONSUMER + 0x192 ; Calculator
|
||||||
|
je .multimedia_key
|
||||||
|
mov al, 0x6B
|
||||||
|
cmp ecx, USAGE_CONSUMER + 0x194 ; My computer
|
||||||
|
je .multimedia_key
|
||||||
|
mov al, 0x65
|
||||||
|
cmp ecx, USAGE_CONSUMER + 0x221 ; WWW Search
|
||||||
|
je .multimedia_key
|
||||||
|
mov al, 0x32
|
||||||
|
cmp ecx, USAGE_CONSUMER + 0x223 ; WWW Home
|
||||||
|
je .multimedia_key
|
||||||
|
mov al, 0x6a
|
||||||
|
cmp ecx, USAGE_CONSUMER + 0x224 ; WWW Back
|
||||||
|
je .multimedia_key
|
||||||
|
mov al, 0x69
|
||||||
|
cmp ecx, USAGE_CONSUMER + 0x225 ; WWW forward
|
||||||
|
je .multimedia_key
|
||||||
|
mov al, 0x68
|
||||||
|
cmp ecx, USAGE_CONSUMER + 0x226 ; WWW Stop
|
||||||
|
je .multimedia_key
|
||||||
|
mov al, 0x67
|
||||||
|
cmp ecx, USAGE_CONSUMER + 0x227 ; WWW refresh
|
||||||
|
je .multimedia_key
|
||||||
|
mov al, 0x66
|
||||||
|
cmp ecx, USAGE_CONSUMER + 0x22A ; WWW favorites
|
||||||
|
je .multimedia_key
|
||||||
|
jmp .unclaimed
|
||||||
|
|
||||||
|
|
||||||
|
.multimedia_key:
|
||||||
|
; 1d. Further actions are slightly different for key press and key release.
|
||||||
|
; Decide what to do.
|
||||||
|
test edx, edx
|
||||||
|
jz .multimedia_key_released
|
||||||
|
.multimedia_key_pressed:
|
||||||
|
; The key is pressed.
|
||||||
|
push ecx
|
||||||
|
mov ecx, 0xE0
|
||||||
|
invoke SetKeyboardData
|
||||||
|
pop ecx
|
||||||
|
invoke SetKeyboardData
|
||||||
|
ret
|
||||||
|
|
||||||
|
.multimedia_key_released:
|
||||||
|
mov [edi+multimedia_device_data.last_pressed], 0
|
||||||
|
; The key is released.
|
||||||
|
or cl, 0x80
|
||||||
|
push ecx
|
||||||
|
mov ecx, 0xE0
|
||||||
|
invoke SetKeyboardData
|
||||||
|
pop ecx
|
||||||
|
invoke SetKeyboardData
|
||||||
|
ret
|
||||||
|
.nothing:
|
||||||
|
ret
|
||||||
|
|
||||||
|
endp
|
||||||
|
|
||||||
|
; This procedure is called when HID layer ends processing a new input packet
|
||||||
|
; from a keyboard.
|
||||||
|
; in: edi -> keyboard_device_data (pointer returned from keyboard_driver_add_device)
|
||||||
|
proc multimedia_driver_end_packet
|
||||||
|
; Nothing to do.
|
||||||
|
ret
|
||||||
|
endp
|
@ -23,6 +23,8 @@ USAGE_GD_SLIDER = 10036h
|
|||||||
USAGE_GD_DIAL = 10037h
|
USAGE_GD_DIAL = 10037h
|
||||||
USAGE_GD_WHEEL = 10038h
|
USAGE_GD_WHEEL = 10038h
|
||||||
|
|
||||||
|
USAGE_GD_CONS_CTRL = 0C0001h ; Consumer control (media keys)
|
||||||
|
|
||||||
; Keyboard/Keypad usage page
|
; Keyboard/Keypad usage page
|
||||||
USAGE_KBD_NOEVENT = 70000h
|
USAGE_KBD_NOEVENT = 70000h
|
||||||
USAGE_KBD_ROLLOVER = 70001h
|
USAGE_KBD_ROLLOVER = 70001h
|
||||||
@ -46,6 +48,9 @@ USAGE_LED_SCROLLLOCK = 80003h
|
|||||||
; First button is USAGE_BUTTON_PAGE+1, second - USAGE_BUTTON_PAGE+2 etc.
|
; First button is USAGE_BUTTON_PAGE+1, second - USAGE_BUTTON_PAGE+2 etc.
|
||||||
USAGE_BUTTON_PAGE = 90000h
|
USAGE_BUTTON_PAGE = 90000h
|
||||||
|
|
||||||
|
; Consumer control usage page
|
||||||
|
USAGE_CONSUMER = 0C0000h
|
||||||
|
|
||||||
; Flags for input/output/feature fields
|
; Flags for input/output/feature fields
|
||||||
HID_FIELD_CONSTANT = 1 ; if not, then Data field
|
HID_FIELD_CONSTANT = 1 ; if not, then Data field
|
||||||
HID_FIELD_VARIABLE = 2 ; if not, then Array field
|
HID_FIELD_VARIABLE = 2 ; if not, then Array field
|
||||||
@ -1010,6 +1015,9 @@ end if
|
|||||||
jz .has_driver
|
jz .has_driver
|
||||||
cmp [edi+collection.usage], USAGE_GD_KEYPAD
|
cmp [edi+collection.usage], USAGE_GD_KEYPAD
|
||||||
jz .has_driver
|
jz .has_driver
|
||||||
|
mov esi, multimedia_driver
|
||||||
|
cmp [edi+collection.usage], USAGE_GD_CONS_CTRL
|
||||||
|
jz .has_driver
|
||||||
if HID_DUMP_UNCLAIMED
|
if HID_DUMP_UNCLAIMED
|
||||||
mov esi, default_driver
|
mov esi, default_driver
|
||||||
else
|
else
|
||||||
|
@ -523,6 +523,7 @@ include 'sort.inc'
|
|||||||
include 'unclaimed.inc'
|
include 'unclaimed.inc'
|
||||||
include 'mouse.inc'
|
include 'mouse.inc'
|
||||||
include 'keyboard.inc'
|
include 'keyboard.inc'
|
||||||
|
include 'multimedia.inc'
|
||||||
|
|
||||||
; strings
|
; strings
|
||||||
my_driver db 'usbhid',0
|
my_driver db 'usbhid',0
|
||||||
|
Loading…
Reference in New Issue
Block a user