forked from KolibriOS/kolibrios
libini: ini_get_shortcut added
git-svn-id: svn://kolibrios.org@1327 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
parent
9d75a9ca5e
commit
28318762d1
@ -64,7 +64,7 @@ public @EXPORT as 'EXPORTS'
|
||||
include '../../../../proc32.inc'
|
||||
include '../../../../macros.inc'
|
||||
include '../libio/libio.inc'
|
||||
purge section ; mov,add,sub
|
||||
purge section,mov,add,sub
|
||||
|
||||
include 'libini_p.inc'
|
||||
|
||||
@ -657,6 +657,211 @@ endl
|
||||
ret
|
||||
endp
|
||||
|
||||
;;================================================================================================;;
|
||||
proc ini.get_shortcut _f_name, _sec_name, _key_name, _def_val, _modifiers ;///////////////////////;;
|
||||
;;------------------------------------------------------------------------------------------------;;
|
||||
;? Read shortcut key ;;
|
||||
;;------------------------------------------------------------------------------------------------;;
|
||||
;> _f_name = ini filename <asciiz> ;;
|
||||
;> _sec_name = section name <asciiz> ;;
|
||||
;> _key_name = key name <asciiz> ;;
|
||||
;> _def_val = default value to return if no key, section or file found <dword> ;;
|
||||
;> _modifiers = pointer to dword variable which receives modifiers state as in 66.4 <dword*> ;;
|
||||
;;------------------------------------------------------------------------------------------------;;
|
||||
;< eax = [_def_val] (error) / shortcut key value as scancode <int> ;;
|
||||
;< [[_modifiers]] = unchanged (error) / modifiers state for this shortcut <int> ;;
|
||||
;;================================================================================================;;
|
||||
locals
|
||||
buf rb 64
|
||||
endl
|
||||
|
||||
push ebx esi edi
|
||||
|
||||
lea esi, [buf]
|
||||
stdcall ini.get_str, [_f_name], [_sec_name], [_key_name], esi, 64, 0
|
||||
cmp byte[esi],0
|
||||
je .exit_error
|
||||
|
||||
xor ebx, ebx ; ebx holds the value of modifiers
|
||||
.loop:
|
||||
; test for end
|
||||
xor eax, eax
|
||||
cmp byte [esi], al
|
||||
jz .exit_ok ; exit with scancode zero
|
||||
; skip all '+'s
|
||||
cmp byte [esi], '+'
|
||||
jnz @f
|
||||
inc esi
|
||||
jmp .loop
|
||||
@@:
|
||||
; test for names
|
||||
mov edi, .names_table
|
||||
xor edx, edx
|
||||
.names_loop:
|
||||
movzx ecx, byte [edi]
|
||||
inc edi
|
||||
push esi
|
||||
@@:
|
||||
lodsb
|
||||
or al, 20h
|
||||
scasb
|
||||
loopz @b
|
||||
jz .name_found
|
||||
pop esi
|
||||
lea edi, [edi+ecx+4]
|
||||
inc edx
|
||||
cmp byte [edi], 0
|
||||
jnz .names_loop
|
||||
; special test: functional keys F<number>
|
||||
cmp byte [esi], 'f'
|
||||
jz @f
|
||||
cmp byte [esi], 'F'
|
||||
jnz .no_fx
|
||||
@@:
|
||||
mov edi, esi
|
||||
inc esi
|
||||
call libini._.str_to_int
|
||||
test eax, eax
|
||||
jz .fx
|
||||
mov esi, edi
|
||||
.no_fx:
|
||||
; name not found, that must be usual key
|
||||
movzx eax, byte [esi]
|
||||
stdcall libini._.ascii_to_scan, eax
|
||||
test eax, eax
|
||||
jz .exit_error
|
||||
; all is ok
|
||||
.exit_ok:
|
||||
mov ecx, [_modifiers]
|
||||
test ecx, ecx
|
||||
jz @f
|
||||
mov [ecx], ebx
|
||||
|
||||
@@:
|
||||
|
||||
pop edi esi ebx
|
||||
ret
|
||||
|
||||
.exit_error:
|
||||
mov eax, [_def_val]
|
||||
pop edi esi ebx
|
||||
ret
|
||||
; handler for Fx
|
||||
; eax = number
|
||||
.fx:
|
||||
cmp eax, 10
|
||||
ja @f
|
||||
add eax, 3Bh-1
|
||||
jmp .exit_ok
|
||||
@@:
|
||||
add eax, 57h-11
|
||||
jmp .exit_ok
|
||||
; handlers for names
|
||||
.name_found:
|
||||
pop eax ; ignore saved esi
|
||||
call dword [edi]
|
||||
cmp edx, .num_modifiers
|
||||
jae .exit_ok
|
||||
jmp .loop
|
||||
; modifiers
|
||||
; syntax of value for each modifier:
|
||||
; 0 = none, 1 = exactly one of L+R, 2 = both L+R, 3 = L, 4 = R
|
||||
; Logic for switching: LShift+RShift=LShift+Shift=Shift+Shift, LShift+LShift=LShift
|
||||
; generic modifier: 0->1->2->2, 3->2, 4->2
|
||||
; left modifier: 0->3->3, 1->2->2, 4->2
|
||||
; right modifier: 0->4->4, 1->2->2, 3->2
|
||||
; Shift corresponds to first hex digit, Ctrl - second, Alt - third
|
||||
macro shortcut_handle_modifiers name,reg,shift
|
||||
{
|
||||
local .set2,.set3,.set4
|
||||
.#name#_handler: ; generic modifier
|
||||
test reg, 0xF
|
||||
jnz .set2
|
||||
if shift
|
||||
or reg, 1 shl shift
|
||||
else
|
||||
inc reg
|
||||
end if
|
||||
retn
|
||||
.set2:
|
||||
and reg, not (0xF shl shift)
|
||||
or reg, 2 shl shift
|
||||
retn
|
||||
.l#name#_handler:
|
||||
mov al, reg
|
||||
and al, 0xF shl shift
|
||||
jz .set3
|
||||
cmp al, 3 shl shift
|
||||
jnz .set2
|
||||
retn
|
||||
.set3:
|
||||
add reg, 3 shl shift
|
||||
retn
|
||||
.r#name#_handler:
|
||||
mov al, reg
|
||||
and al, 0xF shl shift
|
||||
jz .set4
|
||||
cmp al, 4 shl shift
|
||||
jnz .set2
|
||||
retn
|
||||
.set4:
|
||||
add reg, 4 shl shift
|
||||
retn
|
||||
}
|
||||
shortcut_handle_modifiers shift,bl,0
|
||||
shortcut_handle_modifiers ctrl,bl,4
|
||||
shortcut_handle_modifiers alt,bh,0
|
||||
; names of keys
|
||||
.name_handler:
|
||||
movzx eax, byte [.names_scancodes+edx-.num_modifiers]
|
||||
retn
|
||||
endp
|
||||
|
||||
; note: comparison ignores case, so this table keeps lowercase names
|
||||
; macro does this
|
||||
macro shortcut_name_with_handler name,handler
|
||||
{
|
||||
local .start, .end
|
||||
db .end - .start
|
||||
.start:
|
||||
db name
|
||||
.end:
|
||||
repeat .end - .start
|
||||
load .a byte from .start + % - 1
|
||||
store byte .a or 0x20 at .start + % - 1
|
||||
end repeat
|
||||
dd handler
|
||||
}
|
||||
macro shortcut_name [name]
|
||||
{
|
||||
shortcut_name_with_handler name, .name_handler
|
||||
}
|
||||
; all names here must be in english
|
||||
; ... or modify lowercasing in macro and in comparison
|
||||
.names_table:
|
||||
; generic modifiers
|
||||
shortcut_name_with_handler 'Ctrl', .ctrl_handler
|
||||
shortcut_name_with_handler 'Alt', .alt_handler
|
||||
shortcut_name_with_handler 'Shift', .shift_handler
|
||||
; concrete modifiers
|
||||
shortcut_name_with_handler 'LCtrl', .lctrl_handler
|
||||
shortcut_name_with_handler 'RCtrl', .rctrl_handler
|
||||
shortcut_name_with_handler 'LAlt', .lalt_handler
|
||||
shortcut_name_with_handler 'RAlt', .ralt_handler
|
||||
shortcut_name_with_handler 'LShift', .lshift_handler
|
||||
shortcut_name_with_handler 'RShift', .rshift_handler
|
||||
.num_modifiers = 9
|
||||
; symbolic names of keys
|
||||
shortcut_name 'Home', 'End', 'PgUp', 'PgDn', 'Ins', 'Insert', 'Del', 'Delete'
|
||||
shortcut_name 'Tab', 'Plus', 'Esc', 'Enter', 'Backspace', 'Space', 'Left', 'Right'
|
||||
shortcut_name 'Up', 'Down'
|
||||
; end of table
|
||||
db 0
|
||||
ini.get_shortcut.names_scancodes:
|
||||
; scancodes for 'Home' ... 'Down'
|
||||
db 47h, 4Fh, 49h, 51h, 52h, 52h, 53h, 53h
|
||||
db 0Fh, 4Eh, 01h, 1Ch, 0Eh, 39h, 4Bh, 4Dh
|
||||
db 48h, 50h
|
||||
|
||||
;;================================================================================================;;
|
||||
;;////////////////////////////////////////////////////////////////////////////////////////////////;;
|
||||
@ -699,7 +904,7 @@ align 16
|
||||
|
||||
export \
|
||||
libini._.init , 'lib_init' , \
|
||||
0x00080008 , 'version' , \
|
||||
0x00080009 , 'version' , \
|
||||
ini.enum_sections , 'ini_enum_sections' , \
|
||||
ini.enum_keys , 'ini_enum_keys' , \
|
||||
ini.get_str , 'ini_get_str' , \
|
||||
@ -707,4 +912,5 @@ export \
|
||||
ini.get_color , 'ini_get_color' , \
|
||||
ini.set_str , 'ini_set_str' , \
|
||||
ini.set_int , 'ini_set_int' , \
|
||||
ini.set_color , 'ini_set_color'
|
||||
ini.set_color , 'ini_set_color' , \
|
||||
ini.get_shortcut , 'ini_get_shortcut'
|
||||
|
@ -621,3 +621,61 @@ proc libini._.int_to_str ;//////////////////////////////////////////////////////
|
||||
stosb
|
||||
retn
|
||||
endp
|
||||
|
||||
;;================================================================================================;;
|
||||
proc libini._.ascii_to_scan ;_ascii_code ;////////////////////////////////////////////////////////;;
|
||||
;;------------------------------------------------------------------------------------------------;;
|
||||
;? Translate ASCII code of key to scancode using standard mapping from keymap.key ;;
|
||||
;;------------------------------------------------------------------------------------------------;;
|
||||
;> _ascii_code = [esp+4] = ASCII code to convert ;;
|
||||
;;------------------------------------------------------------------------------------------------;;
|
||||
;< eax = 0 (error) / scancode (success) ;;
|
||||
;;================================================================================================;;
|
||||
; /sys/keymap.key
|
||||
sub esp, 256
|
||||
mov eax, esp
|
||||
push ebx
|
||||
push 'key'
|
||||
push 'map.'
|
||||
push '/key'
|
||||
push '/sys'
|
||||
push eax ; buffer in the stack
|
||||
push 0x100 ; read 0x100 bytes
|
||||
push 0
|
||||
push 0 ; from position zero
|
||||
push 0 ; subfunction: read
|
||||
mov ebx, esp
|
||||
push 70
|
||||
pop eax
|
||||
mcall
|
||||
add esp, 36
|
||||
pop ebx
|
||||
test eax, eax
|
||||
jnz .die
|
||||
mov al, [esp+256+4] ; get ASCII code
|
||||
push edi
|
||||
; first keytable - no modifiers pressed
|
||||
; check scancodes from 1 to 36h (inclusive)
|
||||
lea edi, [esp+4+1]
|
||||
mov edx, edi
|
||||
mov ecx, 36h
|
||||
repnz scasb
|
||||
jz .found
|
||||
; second keytable - Shift pressed
|
||||
lea edi, [esp+4+128+1]
|
||||
mov edx, edi
|
||||
mov ecx, 36h
|
||||
repnz scasb
|
||||
jz .found
|
||||
pop edi
|
||||
.die:
|
||||
xor eax, eax
|
||||
jmp .ret
|
||||
.found:
|
||||
mov eax, edi
|
||||
sub eax, edx
|
||||
pop edi
|
||||
.ret:
|
||||
add esp, 256
|
||||
ret 4
|
||||
endp
|
||||
|
Loading…
Reference in New Issue
Block a user