forked from KolibriOS/kolibrios
console: added gets2() with user callback
git-svn-id: svn://kolibrios.org@852 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
parent
4637e1f6a3
commit
abf7f61fb0
@ -1,2 +1,2 @@
|
|||||||
fasm console.asm ..\console.obj
|
fasm console.asm console.obj
|
||||||
e:\zhenya\program\menuet\kpack\kpack.exe ..\console.obj
|
kpack.exe console.obj
|
@ -1,5 +1,5 @@
|
|||||||
; ”ãªæ¨¨ à ¡®âë á ª®á®«ìî ¤«ï ¯à®£à ¬¬ Š®«¨¡à¨Ž‘
|
; ”ãªæ¨¨ à ¡®âë á ª®á®«ìî ¤«ï ¯à®£à ¬¬ Š®«¨¡à¨Ž‘
|
||||||
; diamond, 2006, 2007
|
; diamond, 2006-2008
|
||||||
|
|
||||||
|
|
||||||
format MS COFF
|
format MS COFF
|
||||||
@ -1139,16 +1139,21 @@ con_getch2:
|
|||||||
|
|
||||||
; void __stdcall con_gets(char* str, int n);
|
; void __stdcall con_gets(char* str, int n);
|
||||||
con_gets:
|
con_gets:
|
||||||
|
pop eax
|
||||||
|
push 0
|
||||||
|
push eax
|
||||||
|
; void __stdcall con_gets2(con_gets2_callback callback, char* str, int n);
|
||||||
|
con_gets2:
|
||||||
pushad
|
pushad
|
||||||
mov esi, [esp+20h+4] ; str
|
mov esi, [esp+20h+8] ; str
|
||||||
mov ebx, [esp+20h+8] ; n
|
mov ebx, [esp+20h+12] ; n
|
||||||
sub ebx, 1
|
sub ebx, 1
|
||||||
jle .ret
|
jle .ret
|
||||||
mov byte [esi], 0
|
mov byte [esi], 0
|
||||||
xor ecx, ecx ; ¤«¨ 㦥 ¢¢¥¤ñ®© áâப¨
|
xor ecx, ecx ; ¤«¨ 㦥 ¢¢¥¤ñ®© áâப¨
|
||||||
call con.get_data_ptr
|
call con.get_data_ptr
|
||||||
.loop:
|
.loop:
|
||||||
call con_getch
|
call con_getch2
|
||||||
test al, al
|
test al, al
|
||||||
jz .extended
|
jz .extended
|
||||||
cmp al, 8
|
cmp al, 8
|
||||||
@ -1157,6 +1162,8 @@ con_gets:
|
|||||||
jz .esc
|
jz .esc
|
||||||
cmp al, 13
|
cmp al, 13
|
||||||
jz .enter
|
jz .enter
|
||||||
|
cmp al, 9
|
||||||
|
jz .tab
|
||||||
inc ecx
|
inc ecx
|
||||||
mov dl, al
|
mov dl, al
|
||||||
call con.write_char_ex
|
call con.write_char_ex
|
||||||
@ -1183,6 +1190,7 @@ con_gets:
|
|||||||
call con.update_screen
|
call con.update_screen
|
||||||
cmp ecx, ebx
|
cmp ecx, ebx
|
||||||
jb .loop
|
jb .loop
|
||||||
|
.ret_us:
|
||||||
mov edx, [con.cur_x]
|
mov edx, [con.cur_x]
|
||||||
@@:
|
@@:
|
||||||
lodsb
|
lodsb
|
||||||
@ -1218,7 +1226,7 @@ con_gets:
|
|||||||
xor ecx, ecx
|
xor ecx, ecx
|
||||||
@@:
|
@@:
|
||||||
mov byte [esi], 0
|
mov byte [esi], 0
|
||||||
cmp esi, [esp+20h+4]
|
cmp esi, [esp+20h+8]
|
||||||
jbe .update_screen_and_loop
|
jbe .update_screen_and_loop
|
||||||
mov al, 8
|
mov al, 8
|
||||||
call con.write_special_char
|
call con.write_special_char
|
||||||
@ -1234,7 +1242,7 @@ con_gets:
|
|||||||
lodsb
|
lodsb
|
||||||
call con.write_char_ex
|
call con.write_char_ex
|
||||||
.backspace:
|
.backspace:
|
||||||
cmp esi, [esp+20h+4]
|
cmp esi, [esp+20h+8]
|
||||||
jbe .loop
|
jbe .loop
|
||||||
push esi
|
push esi
|
||||||
mov edx, [con.cur_x]
|
mov edx, [con.cur_x]
|
||||||
@ -1298,8 +1306,11 @@ con_gets:
|
|||||||
call con.write_special_char
|
call con.write_special_char
|
||||||
call con.update_screen
|
call con.update_screen
|
||||||
jmp .ret
|
jmp .ret
|
||||||
|
.tab:
|
||||||
|
mov al, 0
|
||||||
|
mov ah, 0xF
|
||||||
.extended:
|
.extended:
|
||||||
call con_getch
|
xchg al, ah
|
||||||
cmp al, 0x4B
|
cmp al, 0x4B
|
||||||
jz .left
|
jz .left
|
||||||
cmp al, 0x4D
|
cmp al, 0x4D
|
||||||
@ -1310,9 +1321,107 @@ con_gets:
|
|||||||
jz .end
|
jz .end
|
||||||
cmp al, 0x53
|
cmp al, 0x53
|
||||||
jz .delete
|
jz .delete
|
||||||
|
; give control to callback function
|
||||||
|
cmp dword [esp+20h+4], 0
|
||||||
|
jz .loop
|
||||||
|
; remember length of text before and length of text after
|
||||||
|
; and advance cursor to the end of line
|
||||||
|
push ecx
|
||||||
|
push eax
|
||||||
|
lea edx, [esi+1]
|
||||||
|
@@:
|
||||||
|
lodsb
|
||||||
|
test al, al
|
||||||
|
jz @f
|
||||||
|
call con.write_char_ex
|
||||||
|
jmp @b
|
||||||
|
@@:
|
||||||
|
sub esi, edx
|
||||||
|
pop eax
|
||||||
|
push esi
|
||||||
|
dec edx
|
||||||
|
sub edx, [esp+28h+8]
|
||||||
|
push edx
|
||||||
|
push esp ; ppos
|
||||||
|
mov ecx, [esp+30h+4]
|
||||||
|
lea edx, [esp+30h+12]
|
||||||
|
push edx ; pn
|
||||||
|
lea edx, [esp+34h+8]
|
||||||
|
push edx ; pstr
|
||||||
|
push eax ; keycode
|
||||||
|
call ecx
|
||||||
|
call con.get_data_ptr
|
||||||
|
dec eax
|
||||||
|
js .callback_nochange
|
||||||
|
jz .callback_del
|
||||||
|
dec eax
|
||||||
|
jz .callback_output
|
||||||
|
; callback returned 2 - exit
|
||||||
|
add esp, 12
|
||||||
|
jmp .ret
|
||||||
|
.callback_nochange:
|
||||||
|
; callback returned 0 - string was not changed, only restore cursor position
|
||||||
|
pop esi
|
||||||
|
pop ecx
|
||||||
|
test ecx, ecx
|
||||||
|
jz .cncs
|
||||||
|
@@:
|
||||||
|
mov al, 8
|
||||||
|
call con.write_special_char
|
||||||
|
loop @b
|
||||||
|
.cncs:
|
||||||
|
pop ecx
|
||||||
|
add esi, [esp+20h+8]
|
||||||
|
jmp .callback_done
|
||||||
|
.callback_del:
|
||||||
|
; callback returned 1 - string was changed, delete old string and output new
|
||||||
|
mov ecx, [esp+8]
|
||||||
|
test ecx, ecx
|
||||||
|
jz .cds
|
||||||
|
@@:
|
||||||
|
mov al, 8
|
||||||
|
call con.write_special_char
|
||||||
|
mov al, ' '
|
||||||
|
call con.write_char_ex
|
||||||
|
mov al, 8
|
||||||
|
call con.write_special_char
|
||||||
|
loop @b
|
||||||
|
.cds:
|
||||||
|
.callback_output:
|
||||||
|
; callback returned 2 - string was changed, output new string
|
||||||
|
pop edx
|
||||||
|
pop esi
|
||||||
|
pop ecx
|
||||||
|
mov esi, [esp+20h+8]
|
||||||
|
xor ecx, ecx
|
||||||
|
@@:
|
||||||
|
lodsb
|
||||||
|
test al, al
|
||||||
|
jz @f
|
||||||
|
call con.write_char_ex
|
||||||
|
inc ecx
|
||||||
|
jmp @b
|
||||||
|
@@:
|
||||||
|
dec esi
|
||||||
|
push ecx
|
||||||
|
sub ecx, edx
|
||||||
|
jz .cos
|
||||||
|
@@:
|
||||||
|
mov al, 8
|
||||||
|
call con.write_special_char
|
||||||
|
dec esi
|
||||||
|
loop @b
|
||||||
|
.cos:
|
||||||
|
pop ecx
|
||||||
|
.callback_done:
|
||||||
|
call con.update_screen
|
||||||
|
mov ebx, [esp+20h+12]
|
||||||
|
dec ebx
|
||||||
|
cmp ecx, ebx
|
||||||
|
jae .ret_us
|
||||||
jmp .loop
|
jmp .loop
|
||||||
.left:
|
.left:
|
||||||
cmp esi, [esp+20h+4]
|
cmp esi, [esp+20h+8]
|
||||||
jbe .loop
|
jbe .loop
|
||||||
dec esi
|
dec esi
|
||||||
mov al, 8
|
mov al, 8
|
||||||
@ -1325,7 +1434,7 @@ con_gets:
|
|||||||
call con.write_char_ex
|
call con.write_char_ex
|
||||||
jmp .update_screen_and_loop
|
jmp .update_screen_and_loop
|
||||||
.home:
|
.home:
|
||||||
cmp esi, [esp+20h+4]
|
cmp esi, [esp+20h+8]
|
||||||
jz .update_screen_and_loop
|
jz .update_screen_and_loop
|
||||||
dec esi
|
dec esi
|
||||||
mov al, 8
|
mov al, 8
|
||||||
@ -1342,7 +1451,7 @@ con_gets:
|
|||||||
jmp .update_screen_and_loop
|
jmp .update_screen_and_loop
|
||||||
.ret:
|
.ret:
|
||||||
popad
|
popad
|
||||||
ret 8
|
ret 12
|
||||||
|
|
||||||
con.update_screen:
|
con.update_screen:
|
||||||
push eax
|
push eax
|
||||||
@ -2018,7 +2127,7 @@ con.vscroll_pt dd -1
|
|||||||
align 16
|
align 16
|
||||||
EXPORTS:
|
EXPORTS:
|
||||||
dd szStart, START
|
dd szStart, START
|
||||||
dd szVersion, 0x00020003
|
dd szVersion, 0x00020004
|
||||||
dd szcon_init, con_init
|
dd szcon_init, con_init
|
||||||
dd szcon_write_asciiz, con_write_asciiz
|
dd szcon_write_asciiz, con_write_asciiz
|
||||||
dd szcon_printf, con_printf
|
dd szcon_printf, con_printf
|
||||||
@ -2029,6 +2138,7 @@ EXPORTS:
|
|||||||
dd szcon_getch, con_getch
|
dd szcon_getch, con_getch
|
||||||
dd szcon_getch2, con_getch2
|
dd szcon_getch2, con_getch2
|
||||||
dd szcon_gets, con_gets
|
dd szcon_gets, con_gets
|
||||||
|
dd szcon_gets2, con_gets2
|
||||||
dd szcon_get_font_height, con_get_font_height
|
dd szcon_get_font_height, con_get_font_height
|
||||||
dd szcon_get_cursor_height,con_get_cursor_height
|
dd szcon_get_cursor_height,con_get_cursor_height
|
||||||
dd szcon_set_cursor_height,con_set_cursor_height
|
dd szcon_set_cursor_height,con_set_cursor_height
|
||||||
@ -2061,6 +2171,7 @@ szcon_kbhit db 'con_kbhit',0
|
|||||||
szcon_getch db 'con_getch',0
|
szcon_getch db 'con_getch',0
|
||||||
szcon_getch2 db 'con_getch2',0
|
szcon_getch2 db 'con_getch2',0
|
||||||
szcon_gets db 'con_gets',0
|
szcon_gets db 'con_gets',0
|
||||||
|
szcon_gets2 db 'con_gets2',0
|
||||||
szcon_get_font_height db 'con_get_font_height',0
|
szcon_get_font_height db 'con_get_font_height',0
|
||||||
szcon_get_cursor_height db 'con_get_cursor_height',0
|
szcon_get_cursor_height db 'con_get_cursor_height',0
|
||||||
szcon_set_cursor_height db 'con_set_cursor_height',0
|
szcon_set_cursor_height db 'con_set_cursor_height',0
|
||||||
|
@ -112,3 +112,16 @@ void __stdcall con_gets(char* str, int n);
|
|||||||
новой строки, а также по прочтении n-1 символа (в зависимости от того, что
|
новой строки, а также по прочтении n-1 символа (в зависимости от того, что
|
||||||
произойдёт раньше). В первом случае символ новой строки также записывается в
|
произойдёт раньше). В первом случае символ новой строки также записывается в
|
||||||
str. Считанная строка дополняется нулевым символом.
|
str. Считанная строка дополняется нулевым символом.
|
||||||
|
|
||||||
|
typedef int (__stdcall * con_gets2_callback)(int keycode, char** pstr, int* pn, int* ppos);
|
||||||
|
void __stdcall con_gets2(con_gets2_callback callback, char* str, int n);
|
||||||
|
Полностью аналогична con_gets за исключением того, что когда пользователь
|
||||||
|
нажимает нераспознанную клавишу, вызывается указанная callback-процедура
|
||||||
|
(которая может, например, обрабатывать up/down для истории ввода и tab для
|
||||||
|
автодополнения). Процедуре передаётся код клавиши и три указателя - на строку,
|
||||||
|
на лимит и на текущую позицию в строке. Процедура может менять содержимое
|
||||||
|
строки и может менять саму строку (например, перераспределить память для
|
||||||
|
увеличения лимита), лимит, позицию в строке - для этого и передаются указатели.
|
||||||
|
Возвращаемое значение: 0=строка не менялась; 1=строка изменилась, необходимо
|
||||||
|
удалить старую и вывести новую; 2=строка изменилась, необходимо её вывести;
|
||||||
|
3=немедленно выйти из функции.
|
||||||
|
253
programs/develop/libraries/console/examples/test_gets2.asm
Normal file
253
programs/develop/libraries/console/examples/test_gets2.asm
Normal file
@ -0,0 +1,253 @@
|
|||||||
|
|
||||||
|
include 'proc32.inc'
|
||||||
|
|
||||||
|
DLL_ENTRY equ 1
|
||||||
|
DLL_EXIT equ -1
|
||||||
|
REQ_DLL_VER equ 4
|
||||||
|
|
||||||
|
use32
|
||||||
|
db 'MENUET01'
|
||||||
|
dd 1
|
||||||
|
dd start
|
||||||
|
dd i_end
|
||||||
|
dd mem
|
||||||
|
dd mem
|
||||||
|
dd 0
|
||||||
|
dd 0
|
||||||
|
|
||||||
|
start:
|
||||||
|
stdcall load_dll_and_import, dllname, imports
|
||||||
|
test eax, eax
|
||||||
|
jz exit
|
||||||
|
|
||||||
|
; check version
|
||||||
|
cmp word [dll_ver], REQ_DLL_VER
|
||||||
|
jb exit
|
||||||
|
cmp word [dll_ver+2], REQ_DLL_VER
|
||||||
|
ja exit
|
||||||
|
push DLL_ENTRY
|
||||||
|
call [dll_start]
|
||||||
|
|
||||||
|
; yes! Now do some work (gets2() demo in this case).
|
||||||
|
|
||||||
|
push caption
|
||||||
|
push -1
|
||||||
|
push -1
|
||||||
|
push -1
|
||||||
|
push -1
|
||||||
|
call [con_init]
|
||||||
|
|
||||||
|
; C-equivalent of the following code:
|
||||||
|
; for (;;)
|
||||||
|
; {
|
||||||
|
; con_write_asciiz("Enter string (empty for exit): ");
|
||||||
|
; con_gets2(mycallback,s,256);
|
||||||
|
; if (s[0] == '\n') break;
|
||||||
|
; con_write_asciiz("You entered: ");
|
||||||
|
; con_write_asciiz(s);
|
||||||
|
; }
|
||||||
|
mainloop:
|
||||||
|
push str1
|
||||||
|
call [con_write_asciiz]
|
||||||
|
push 256
|
||||||
|
push s
|
||||||
|
push mycallback
|
||||||
|
call [con_gets2]
|
||||||
|
cmp [s], 10
|
||||||
|
jz done
|
||||||
|
push str2
|
||||||
|
call [con_write_asciiz]
|
||||||
|
push s
|
||||||
|
call [con_write_asciiz]
|
||||||
|
jmp mainloop
|
||||||
|
done:
|
||||||
|
push 1
|
||||||
|
call [con_exit]
|
||||||
|
exit:
|
||||||
|
or eax, -1
|
||||||
|
int 0x40
|
||||||
|
|
||||||
|
proc mycallback stdcall, keycode:dword, pstr:dword, pn:dword, ppos:dword
|
||||||
|
mov eax, [keycode]
|
||||||
|
cmp al, 0x0F
|
||||||
|
jz .tab
|
||||||
|
cmp al, 0x3B
|
||||||
|
jz .f1
|
||||||
|
cmp al, 0x48
|
||||||
|
jz .up
|
||||||
|
cmp al, 0x50
|
||||||
|
jz .down
|
||||||
|
xor eax, eax
|
||||||
|
ret
|
||||||
|
.tab:
|
||||||
|
; Tab pressed - insert "[autocomplete]" to current position
|
||||||
|
push esi edi
|
||||||
|
mov eax, [ppos]
|
||||||
|
mov eax, [eax]
|
||||||
|
mov ecx, [pn]
|
||||||
|
mov ecx, [ecx]
|
||||||
|
mov esi, [pstr]
|
||||||
|
mov esi, [esi]
|
||||||
|
add ecx, esi
|
||||||
|
add esi, eax
|
||||||
|
mov edx, esi
|
||||||
|
@@:
|
||||||
|
lodsb
|
||||||
|
test al, al
|
||||||
|
jnz @b
|
||||||
|
lea edi, [esi+str3.len]
|
||||||
|
cmp edi, ecx
|
||||||
|
jbe @f
|
||||||
|
mov edi, ecx
|
||||||
|
lea esi, [edi-str3.len]
|
||||||
|
@@:
|
||||||
|
cmp esi, edx
|
||||||
|
jbe @f
|
||||||
|
dec esi
|
||||||
|
dec edi
|
||||||
|
mov al, [esi]
|
||||||
|
mov [edi], al
|
||||||
|
jmp @b
|
||||||
|
@@:
|
||||||
|
cmp edi, ecx
|
||||||
|
jb @f
|
||||||
|
dec edi
|
||||||
|
@@:
|
||||||
|
mov ecx, edi
|
||||||
|
sub ecx, edx
|
||||||
|
mov edi, edx
|
||||||
|
mov esi, str3
|
||||||
|
rep movsb
|
||||||
|
mov eax, [pstr]
|
||||||
|
sub edi, [eax]
|
||||||
|
mov eax, [ppos]
|
||||||
|
mov [eax], edi
|
||||||
|
pop edi esi
|
||||||
|
xor eax, eax
|
||||||
|
inc eax
|
||||||
|
ret
|
||||||
|
.f1:
|
||||||
|
; F1 pressed - say message
|
||||||
|
push str4
|
||||||
|
call [con_write_asciiz]
|
||||||
|
push str1
|
||||||
|
call [con_write_asciiz]
|
||||||
|
push 2
|
||||||
|
pop eax
|
||||||
|
ret
|
||||||
|
.up:
|
||||||
|
push esi
|
||||||
|
mov esi, str5
|
||||||
|
mov ecx, str5.len
|
||||||
|
jmp @f
|
||||||
|
.down:
|
||||||
|
push esi
|
||||||
|
mov esi, str6
|
||||||
|
mov ecx, str6.len
|
||||||
|
@@:
|
||||||
|
push edi
|
||||||
|
mov edi, [pstr]
|
||||||
|
mov edi, [edi]
|
||||||
|
mov eax, [ppos]
|
||||||
|
mov [eax], ecx
|
||||||
|
rep movsb
|
||||||
|
xor eax, eax
|
||||||
|
stosb
|
||||||
|
pop edi esi
|
||||||
|
inc eax
|
||||||
|
ret
|
||||||
|
endp
|
||||||
|
|
||||||
|
proc load_dll_and_import stdcall, _dllname:dword, _imports:dword
|
||||||
|
pushad
|
||||||
|
; load DLL
|
||||||
|
push 68
|
||||||
|
pop eax
|
||||||
|
push 19
|
||||||
|
pop ebx
|
||||||
|
mov ecx, [_dllname]
|
||||||
|
int 0x40
|
||||||
|
test eax, eax
|
||||||
|
jz import_fail
|
||||||
|
|
||||||
|
; initialize import
|
||||||
|
mov edi, eax
|
||||||
|
mov esi, [_imports]
|
||||||
|
import_loop:
|
||||||
|
lodsd
|
||||||
|
test eax, eax
|
||||||
|
jz import_done
|
||||||
|
mov edx, edi
|
||||||
|
import_find:
|
||||||
|
mov ebx, [edx]
|
||||||
|
test ebx, ebx
|
||||||
|
jz import_not_found
|
||||||
|
push eax
|
||||||
|
@@:
|
||||||
|
mov cl, [eax]
|
||||||
|
cmp cl, [ebx]
|
||||||
|
jnz import_find_next
|
||||||
|
test cl, cl
|
||||||
|
jz import_found
|
||||||
|
inc eax
|
||||||
|
inc ebx
|
||||||
|
jmp @b
|
||||||
|
import_find_next:
|
||||||
|
pop eax
|
||||||
|
add edx, 8
|
||||||
|
jmp import_find
|
||||||
|
import_found:
|
||||||
|
pop eax
|
||||||
|
mov eax, [edx+4]
|
||||||
|
mov [esi-4], eax
|
||||||
|
jmp import_loop
|
||||||
|
import_not_found:
|
||||||
|
import_fail:
|
||||||
|
popad
|
||||||
|
xor eax, eax
|
||||||
|
ret
|
||||||
|
import_done:
|
||||||
|
popad
|
||||||
|
xor eax, eax
|
||||||
|
inc eax
|
||||||
|
ret
|
||||||
|
endp
|
||||||
|
|
||||||
|
align 4
|
||||||
|
|
||||||
|
imports:
|
||||||
|
dll_start dd szStart
|
||||||
|
dll_ver dd szVersion
|
||||||
|
con_init dd szcon_init
|
||||||
|
con_write_asciiz dd szcon_write_asciiz
|
||||||
|
con_exit dd szcon_exit
|
||||||
|
con_gets2 dd szcon_gets2
|
||||||
|
dd 0
|
||||||
|
|
||||||
|
szStart db 'START',0
|
||||||
|
szVersion db 'version',0
|
||||||
|
szcon_init db 'con_init',0
|
||||||
|
szcon_write_asciiz db 'con_write_asciiz',0
|
||||||
|
szcon_exit db 'con_exit',0
|
||||||
|
szcon_gets2 db 'con_gets2',0
|
||||||
|
|
||||||
|
dllname db '/sys/lib/console.obj',0
|
||||||
|
|
||||||
|
caption db 'Console test - gets2()',0
|
||||||
|
str1 db 'Enter string (empty for exit): ',0
|
||||||
|
str2 db 'You entered: ',0
|
||||||
|
str3 db '[autocomplete]'
|
||||||
|
str3.len = $ - str3
|
||||||
|
str4 db 13,10,'Help? What help do you need?',13,10,0
|
||||||
|
str5 db 'previous line in the history'
|
||||||
|
str5.len = $ - str5
|
||||||
|
str6 db 'next line in the history'
|
||||||
|
str6.len = $ - str6
|
||||||
|
|
||||||
|
i_end:
|
||||||
|
|
||||||
|
s rb 256
|
||||||
|
|
||||||
|
align 4
|
||||||
|
rb 2048 ; stack
|
||||||
|
mem:
|
Loading…
Reference in New Issue
Block a user