DELETED freshlib/ForthScript/ForthLib.asm Index: freshlib/ForthScript/ForthLib.asm ================================================================== --- freshlib/ForthScript/ForthLib.asm +++ /dev/null @@ -1,390 +0,0 @@ -; _______________________________________________________________________________________ -;| | -;| ..::FreshLib::.. Free, open source. Licensed under "Fresh artistic license." | -;|_______________________________________________________________________________________| -; -; Description: ForthScript standard word library. -; -; Target OS: Any -; -; Dependencies: -; -; Notes: -;_________________________________________________________________________________________ - -macro ForthBlock blockname { - forth@block equ blockname - forth@block@size equ blockname#.size - - label blockname byte - - macro forthword name \{ - \local nnnn - - macro endfw \\{ - \\local ..footer - endp - label ..footer byte - db name - db 16-($-..footer) dup 0 - dd nnnn - blockname - \\purge endfw - \\} - \proc nnnn - \} -} - -macro EndForthBlock { - forth@block@size = $ - forth@block - restore forth@block, forth@block@size - purge forthword -} - - - -ForthBlock ForthStandardLib - -; "->" word. -forthword '->' -begin - or [ebx+TForthContext.Status], forthAssignMode - clc - retn -endfw - - -forthword '+' -begin - mov eax, [ebx+TForthContext.pAStack] - mov ecx, [eax+TArray.count] - cmp ecx, 2 - jb .error - - dec ecx - imul ecx, [eax+TArray.itemsize] - lea ecx, [eax+TArray.array+ecx] - - mov edx, [ecx+TFStackCell.value] - sub ecx, [eax+TArray.itemsize] - add [ecx+TFStackCell.value], edx - mov [ecx+TFStackCell.type], ftypeNumber - - mov ecx, [eax+TArray.count] - dec ecx - stdcall DeleteArrayItem, [ebx+TForthContext.pAStack], ecx - mov [ebx+TForthContext.pAStack], edx - clc - return - -.error: - stc - return -endfw - - -forthword '-' -begin - mov eax, [ebx+TForthContext.pAStack] - mov ecx, [eax+TArray.count] - cmp ecx, 2 - jb .error - - dec ecx - imul ecx, [eax+TArray.itemsize] - lea ecx, [eax+TArray.array+ecx] - - mov edx, [ecx+TFStackCell.value] - sub ecx, [eax+TArray.itemsize] - sub [ecx+TFStackCell.value], edx - mov [ecx+TFStackCell.type], ftypeNumber - - mov ecx, [eax+TArray.count] - dec ecx - stdcall DeleteArrayItem, [ebx+TForthContext.pAStack], ecx - mov [ebx+TForthContext.pAStack], edx - clc - return - -.error: - stc - return -endfw - - - -forthword '*' -begin - mov eax, [ebx+TForthContext.pAStack] - mov ecx, [eax+TArray.count] - cmp ecx, 2 - jb .error - - dec ecx - imul ecx, [eax+TArray.itemsize] - lea ecx, [eax+TArray.array+ecx] - - mov edx, [ecx+TFStackCell.value] - sub ecx, [eax+TArray.itemsize] - imul edx, [ecx+TFStackCell.value] - mov [ecx+TFStackCell.value], edx - mov [ecx+TFStackCell.type], ftypeNumber - - mov ecx, [eax+TArray.count] - dec ecx - stdcall DeleteArrayItem, [ebx+TForthContext.pAStack], ecx - mov [ebx+TForthContext.pAStack], edx - clc - return - -.error: - stc - return -endfw - - - -forthword '/' -begin - mov eax, [ebx+TForthContext.pAStack] - mov ecx, [eax+TArray.count] - cmp ecx, 2 - jb .error - - dec ecx - imul ecx, [eax+TArray.itemsize] - lea ecx, [eax+TArray.array+ecx] - - mov edx, [ecx+TFStackCell.value] - sub ecx, [eax+TArray.itemsize] - - push eax - mov eax, edx - cdq - idiv [ecx+TFStackCell.value] - mov [ecx+TFStackCell.value], eax - mov [ecx+TFStackCell.type], ftypeNumber - pop eax - - mov ecx, [eax+TArray.count] - dec ecx - stdcall DeleteArrayItem, [ebx+TForthContext.pAStack], ecx - mov [ebx+TForthContext.pAStack], edx - clc - return - -.error: - stc - return -endfw - - -forthword '%' -begin - mov eax, [ebx+TForthContext.pAStack] - mov ecx, [eax+TArray.count] - cmp ecx, 2 - jb .error - - dec ecx - shl ecx, 3 - lea ecx, [eax+TArray.array+ecx] - - mov edx, [ecx+TFStackCell.value] - sub ecx, [eax+TArray.itemsize] - - push eax - mov eax, edx - cdq - idiv [ecx+TFStackCell.value] - mov [ecx+TFStackCell.value], eax - mov [ecx+TFStackCell.type], ftypeNumber - pop eax - - mov ecx, [eax+TArray.count] - dec ecx - stdcall DeleteArrayItem, [ebx+TForthContext.pAStack], ecx - mov [ebx+TForthContext.pAStack], edx - clc - return - -.error: - stc - return -endfw - - - - -forthword 'swap' -begin - mov eax, [ebx+TForthContext.pAStack] - mov ecx, [eax+TArray.count] - cmp ecx, 2 - jb .finish ; jb == jc - - shl ecx, 3 - add ecx, [ebx+TForthContext.pAStack] -; lea ecx, [ecx+TArray.array-2*sizeof.TFStackCell] TArray.array = 2*sizeof.TFStackCell - - mov eax, [ecx+TFStackCell.value] - mov edx, dword [ecx+TFStackCell.type] - xchg eax, [ecx+sizeof.TFStackCell+TFStackCell.value] - xchg edx, dword [ecx+sizeof.TFStackCell+TFStackCell.type] - mov [ecx+TFStackCell.value], ecx - mov dword [ecx+TFStackCell.type], edx - - clc -.finish: - return -endfw - - - -forthword 'dup' -begin - mov eax, [ebx+TForthContext.pAStack] - mov ecx, [eax+TArray.count] - cmp ecx, 1 - jb .finish ; jb == jc - - shl ecx, 3 - add ecx, [ebx+TForthContext.pAStack] - lea ecx, [ecx+TArray.array-sizeof.TFStackCell] - - stdcall AddArrayItem, [ebx+TForthContext.pAStack] - mov [ebx+TForthContext.pAStack], edx - jc .finish - - pushd [ecx+TFStackCell.value] dword [ecx+TFStackCell.type] - popd dword [eax+TFStackCell.type] [eax+TFStackCell.value] - - clc -.finish: - return -endfw - - - -forthword 'label' -begin - - -endfw - - - - -forthword 'jump' -begin - - -endfw - - - - -forthword '?branch' -begin - - -endfw - - - -; : if +1 ?branch ; -forthword 'if' -begin - - -endfw - - - -; : else label not +1 ?branch ; -forthword 'else' -begin - - -endfw - - -; : then label ; -forthword 'then' -begin - - -endfw - - - - - -; : do label ; -forthword 'do' -begin - - -endfw - - -; : loop -1 ?branch ; -forthword 'loop' - - - - -forthword '.' -begin - mov eax, [ebx+TForthContext.pAStack] - mov ecx, [eax+TArray.count] - jecxz .exit - - dec ecx - mov edx, ecx - - imul ecx, [eax+TArray.itemsize] - lea ecx, [eax+TArray.array+ecx] - - cmp [ecx+TFStackCell.type], ftypeNumber - jne .printstring - - stdcall NumToStr, [ecx+TFStackCell.value], ntsSigned or ntsDec - mov [ecx+TFStackCell.value], eax - mov [ecx+TFStackCell.type], ftypeStringFree - -.printstring: - stdcall StrPtr, [ecx+TFStackCell.value] - stdcall Output, eax - - cmp [ecx+TFStackCell.type], ftypeStringFree - jne .popit - - stdcall StrDel, [ecx+TFStackCell.value] - -.popit: - stdcall DeleteArrayItem, [ebx+TForthContext.pAStack], edx - mov [ebx+TForthContext.pAStack], edx - -.exit: - clc - return - -endfw - - - -forthword 'crlf' -begin - stdcall Output, sCRLF - clc - return -endfw - - - -EndForthBlock - - - -sCRLF db 13, 10, 0, 0 - DELETED freshlib/ForthScript/ForthScript.asm Index: freshlib/ForthScript/ForthScript.asm ================================================================== --- freshlib/ForthScript/ForthScript.asm +++ /dev/null @@ -1,721 +0,0 @@ -; _______________________________________________________________________________________ -;| | -;| ..::FreshLib::.. Free, open source. Licensed under "Fresh artistic license." | -;|_______________________________________________________________________________________| -; -; Description: ForthScript engine. -; -; Target OS: Any -; -; Dependencies: -; -; Notes: -;_________________________________________________________________________________________ -module "Forth script compiler" - -include 'ForthLib.asm' - -; NOTE: E8 is the opcode for relative call -; B8 is the opcode for mov eax, dword const -; BA is the opcode for mov edx, dword const -; FF D0 is the opcode for call eax -; C3 is the opcode for retn -; e9 is the opcode for jmp long offset - - - -ftypeNumber = 0 -ftypeString = 1 -ftypeStringFree = 2 ; this string should be destroyed after use. - -struct TFStackCell - .value dd ? ; number or handle of the string. - .type db ? ; number/string - align 4 -ends - - -struct TFLoopStackCell -ends - - - -struct TFWordFooter - .name rb 16 ; max 12 bytes name paded with 0 - .entry dd ? ; offset to the code of the word [.entry]-4 points to the footer of the previous word. -ends - - -; values for the Status flags. - -forthCompileMode = 1 ; if set the script is compiled instead of interpreted -forthNextNewName = 2 ; if set the next extracted word should be interpreted as a new name. -forthAssignMode = 4 ; if set the next variable word must pop value from the stack, instead of push. - - - -struct TForthContext - .pAStack dd ? ; pointer to the aritmetic stack TArray. - .pLStack dd ? ; pointer to the loop stack TArray. - .pWords dd ? ; pointer to the words memory. - .iWords dd ? ; offset to the first free byte in the words memory. - .iLastWord dd ? ; offset to the end of the last word defined. - .sizeWords dd ? ; size of the words memory. - - .Status dd ? - - .pUserWords dd ? ; pointer to the user words memory. - .iUserWords dd ? ; offset of the end of the user word memory. - .pUser dd ? ; pointer to the user provided object for example TFreshEdit or other. -ends - - -ForthInitWordsMemory = 1024 - - -proc ForthCreateContext -begin - push edi - - stdcall GetMem, sizeof.TForthContext - mov edi, eax - - stdcall CreateArray, sizeof.TFStackCell - mov [edi+TForthContext.pAStack], eax - - stdcall CreateArray, sizeof.TFLoopStackCell - mov [edi+TForthContext.pLStack], eax - - mov [edi+TForthContext.sizeWords], ForthInitWordsMemory - stdcall GetMem, [edi+TForthContext.sizeWords] - mov [edi+TForthContext.pWords], eax - - mov eax, edi - pop edi - return -endp - - -proc ForthFreeContext, .forth_context -begin - - - return -endp - - - -ferrSyntaxError = 1 -ferrUnknownWord = 2 -ferrOutOfMemory = 3 -ferrInvalidNumber = 4 -ferrInvalidString = 5 -ferrMissingBracket = 6 - -ferrMaxError = 6 - -dmsgEndWithoutBegin db 'Syntax error', 0 -dmsgUnknownWord db 'Unknown word', 0 -dmsgOutOfMemory db 'Out of memory', 0 -dmsgInvalidNumber db 'Invalid number', 0 -dmsgInvalidString db 'Invalid string', 0 -dmsgMissingBracket db 'Missing ")"', 0 -dmsgUnknownError db 'Unknown error. Probably bug.', 0 - - - -ForthErrorMessages dd 0 - dd dmsgEndWithoutBegin - dd dmsgUnknownWord - dd dmsgOutOfMemory - dd dmsgInvalidNumber - dd dmsgInvalidString - dd dmsgMissingBracket -; this should be last. - dd dmsgUnknownError - - -proc GetForthErrorMsg, .errcode -begin - mov eax, [.errcode] - cmp eax, ferrMaxError - jbe @f - mov eax, ferrMaxError+1 -@@: - mov eax, [ForthErrorMessages+4*eax] - return -endp - - - -proc ForthExecScript, .pcontext, .psource -.word rb 16 -.newword rb 16 -.entry dd ? ; the entry point of the currently compiled word. -.ofs_error dd ? -.sign dd ? -begin - push ebx ecx esi edi - - mov ebx, [.pcontext] - mov esi, [.psource] - -.script_loop: - - xor eax, eax - mov dword [.word], eax - mov dword [.word+4], eax - mov dword [.word+8], eax - mov dword [.word+12], eax - xor ecx, ecx - - dec esi - -.start_scan: - - inc esi - mov al, [esi] - -; offset for the error message, if any - mov edx, esi - sub edx, [.psource] - mov [.ofs_error], edx - - test al, al - jz .end_of_script - - cmp al, '+' - je .maybe_number - cmp al, '-' - je .maybe_number - - cmp al, '0' - jb .nan - cmp al, '9' - jbe .extract_number - -.nan: - cmp al, '"' - je .extract_string - cmp al, "'" - je .extract_string - - cmp al, ' ' - jbe .start_scan - - cmp al, ':' - jne @f - - test [ebx+TForthContext.Status], forthCompileMode - jnz .syntax_error - - or [ebx+TForthContext.Status], forthCompileMode or forthNextNewName - mov eax, [ebx+TForthContext.iWords] - mov [.entry], eax - jmp .start_scan - -@@: - cmp al, ';' - jne @f - - test [ebx+TForthContext.Status], forthCompileMode - jz .syntax_error - -; finalize the compilation of a word. - - mov eax, sizeof.TFWordFooter+1 - call .allocate_bytes - jc .err_out_of_memory - - sub eax, sizeof.TFWordFooter - mov byte [eax+edx-1], $c3 ; retn - - pushd dword [.newword] dword [.newword+4] dword [.newword+8] dword [.newword+12] - popd [eax+edx+12] [eax+edx+8] [eax+edx+4] [eax+edx] - - push [.entry] - pop [eax+edx+TFWordFooter.entry] - - push [ebx+TForthContext.iWords] - pop [ebx+TForthContext.iLastWord] - - and [ebx+TForthContext.Status], not forthCompileMode - - jmp .start_scan - -@@: - cmp al, '(' - jne @f - -; comment () -.comment_loop: - inc esi - mov al, [esi] - test al, al - jz .err_missing_bracket - - cmp al, ')' - jne .comment_loop - inc esi - jmp .script_loop - -@@: - cmp al, '\' - jne .extract_word - -; one line comment -.comment_loop2: - inc esi - mov al, [esi] - cmp al, ' ' - jae .comment_loop2 - jmp .script_loop - -.extract_word: - mov [.word+ecx], al - inc ecx - and ecx, $0f - inc esi - mov al, [esi] - cmp al, ' ' - ja .extract_word - -;.word_ok: - test [ebx+TForthContext.Status], forthNextNewName - jz .process_word - -; copy the word as a new word name to be placed at the end of the word definition. - mov eax, dword [.word] - mov ecx, dword [.word+4] - mov dword [.newword], eax - mov dword [.newword+4], ecx - - mov eax, dword [.word+8] - mov ecx, dword [.word+12] - mov dword [.newword+8], eax - mov dword [.newword+12], ecx - - and [ebx+TForthContext.Status], not forthNextNewName - jmp .script_loop - - -.process_word: - call .search_word ; eax offset relative to [TForthContext.pWords] - jc .err_unknown_word - - test [ebx+TForthContext.Status], forthCompileMode - jnz .compile_the_word - - push esi - - mov esi, [ebx+TForthContext.pUser] - add eax, [ebx+TForthContext.pWords] - call eax - - pop esi - jmp .script_loop - -.compile_the_word: - mov ecx, eax ; offset of the word entry - - cmp eax, [ebx+TForthContext.iWords] - jb .internal_call - -;.external_call: - add ecx, [ebx+TForthContext.pWords] ; absolute address - - mov eax, 7 - call .allocate_bytes - jc .err_out_of_memory - - mov byte [edx+eax-7], $b8 ; mov eax, const - mov [edx+eax-6], ecx - mov word [edx+eax-2], $d0ff - - jmp .script_loop - - -.internal_call: - mov eax, 5 - call .allocate_bytes ; return new offset in eax and pointer to the memory block in edx - jc .err_out_of_memory - -; relative call to the word entry point. - sub ecx, eax - mov byte [edx+eax-5], $e8 ; call instruction opcode. - mov [edx+eax-4], ecx - - jmp .script_loop - - -.maybe_number: - cmp byte [esi+1], '0' - jb .extract_word - cmp byte [esi+1], '9' - ja .extract_word - -.extract_number: - xor edx, edx - movzx eax, al - - mov byte [.sign], al - cmp al, '-' - je .next - cmp al, '+' - je .next - -.num_loop: - cmp al, ' ' - jbe .number_ok - - cmp al, '0' - jb .err_invalid_number - cmp al, '9' - ja .err_invalid_number - - sub al, '0' - imul edx, 10 - add edx, eax - -.next: - inc esi - mov al, [esi] - jmp .num_loop - -.number_ok: - cmp byte [.sign], '-' - jne @f - neg edx -@@: - test [ebx+TForthContext.Status], forthCompileMode - jnz .compile_number - - call forth_push_number - jmp .script_loop - - -.compile_number: ; $b8 forth_push_number $ba number $ff $d0 - mov ecx, edx - - mov eax, 12 - call .allocate_bytes - jc .err_out_of_memory - - mov byte [edx+eax-12], $b8 ; mov eax, const - mov dword [edx+eax-11], forth_push_number - mov byte [edx+eax-7], $ba ; mov edx, const - mov dword [edx+eax-6], ecx - mov word [edx+eax-2], $d0ff - - jmp .script_loop - - -.extract_string: - mov ah, al ; end character. - xor ecx, ecx ; length of the string - lea edi, [esi+1] - -.str_loop: - inc esi - mov al, [esi] - test al, al - jz .err_invalid_string - - cmp al, ah - je .string_ok - - inc ecx - jmp .str_loop - -.string_ok: - mov ecx, esi - sub ecx, edi - - inc esi - - test [ebx+TForthContext.Status], forthCompileMode - jnz .compile_string - - stdcall StrNew - mov edx, eax - - stdcall StrCopyPart, edx, edi, 0, ecx - - push edx - stdcall AddArrayItem, [ebx+TForthContext.pAStack] - mov [ebx+TForthContext.pAStack], edx - mov [eax+TFStackCell.type], ftypeStringFree - pop [eax+TFStackCell.value] - - jmp .script_loop - -.compile_string: - push esi - mov esi, edi - mov edi, [ebx+TForthContext.iWords] - - lea eax, [ecx+1+17] - stdcall .allocate_bytes - jc .err_out_of_memory - - lea eax, [edi+17] - add edi, [ebx+TForthContext.pWords] - - mov byte [edi], $ba ; mov edx, offset of string - mov dword [edi+1], eax ; offset of string - mov byte [edi+5], $b8 ; mov eax, forth_push_string - mov dword [edi+6], forth_push_string - mov word [edi+10], $d0ff ; call eax - lea eax, [ecx+1] - mov byte [edi+12], $e9 ; jmp end - mov dword [edi+13], eax ; - - add edi, 17 - - rep movsb - mov al, 0 - stosb - - pop esi - jmp .script_loop - - -.end_of_script: - mov ecx, [ebx+TForthContext.pAStack] - mov eax, [ecx+TArray.count] - test eax, eax - jz @f - - lea eax, [ecx+TArray.array+8*eax-8] - mov eax, [eax+TFStackCell.value] - dec [ecx+TArray.count] - -@@: - clc - jmp .finish - -; error handlers -.err_missing_bracket: - mov eax, ferrMissingBracket - jmp .error - -.err_invalid_string: - mov eax, ferrInvalidString - jmp .error - -.err_invalid_number: - mov eax, ferrInvalidNumber - jmp .error - -.err_out_of_memory: - mov eax, ferrOutOfMemory - jmp .error - -.err_unknown_word: - mov eax, ferrUnknownWord - jmp .error - -.syntax_error: - mov eax, ferrSyntaxError - -.error: - mov edx, [.ofs_error] - stc - -.finish: - pop edi esi ecx ebx - return - - -; internal subroutines - - -; returns: -; CF=0 - word found. -; eax - offset of word entry point in pWords memory. -; -; CF=1 - word not found. -.search_word: - push edx esi - -; search in the compiled words - mov edx, [ebx+TForthContext.pWords] - mov esi, [ebx+TForthContext.iLastWord] - call .search_list - jnc .word_found - -; if not found, search in the user provided words, if any. - mov edx, [ebx+TForthContext.pUserWords] - test edx, edx - jz .check_std - - mov esi, [ebx+TForthContext.iUserWords] - call .search_list - jnc .word_found - -.check_std: - mov edx, ForthStandardLib - mov esi, ForthStandardLib.size - call .search_list - jnc .word_found - - stc - pop esi edx - retn - -.word_found: - clc - pop esi edx - retn - - - -; arguments: -; esi - offset of the end of the word area. -; edx - pointer to the begin of the word area. -; returns: -; CF=0; eax=offset of the word entry in the word area. -; CF=1 - not found -.search_list: - add esi, edx - -.search_loop: - sub esi, sizeof.TFWordFooter - cmp esi, edx - jb .notfound - - mov eax, dword [esi+TFWordFooter.name] - cmp eax, dword [.word] - jne .prev_word - - mov eax, dword [esi+TFWordFooter.name+4] - cmp eax, dword [.word+4] - jne .prev_word - - mov eax, dword [esi+TFWordFooter.name+8] - cmp eax, dword [.word+8] - jne .prev_word - - mov eax, dword [esi+TFWordFooter.name+12] - cmp eax, dword [.word+12] - je .found - -.prev_word: - mov esi, [esi+TFWordFooter.entry] - add esi, edx - jmp .search_loop - -.found: - mov eax, [esi+TFWordFooter.entry] - add eax, edx - sub eax, [ebx+TForthContext.pWords] ; relatively to TForthContext.pWords - clc - retn - -.notfound: - stc - retn - - -; argument: eax - count of bytes to allocate. -; returns: -; eax - offset in pWords of the new end ( iWords ) -; edx - pointer of pWords memory. - -.allocate_bytes: - push ecx - - mov edx, [ebx+TForthContext.iWords] - add edx, eax - cmp edx, [ebx+TForthContext.sizeWords] - jb .sizeok - - mov ecx, [ebx+TForthContext.sizeWords] - call [ResizeIt] - mov [ebx+TForthContext.sizeWords], ecx - - stdcall ResizeMem, [ebx+TForthContext.pWords], ecx - jc .end_alloc - mov [ebx+TForthContext.pWords], eax - -.sizeok: - mov [ebx+TForthContext.iWords], edx - mov eax, edx - mov edx, [ebx+TForthContext.pWords] - clc - -.end_alloc: - pop ecx - retn - -endp - -; arguments: -; ebx - TForthContext -; edx - number to be pushed -; returns -; -forth_push_number: - push edx - stdcall AddArrayItem, [ebx+TForthContext.pAStack] - mov [ebx+TForthContext.pAStack], edx - mov [eax+TFStackCell.type], ftypeNumber - pop [eax+TFStackCell.value] - retn - - -; arguments: -; ebx - TForthContext -; returns -; eax - value from the top of the stack -proc forth_pop_number -begin - mov edx, [ebx+TForthContext.pAStack] - mov eax, [edx+TArray.count] - dec eax - js .empty_stack - - push eax - - imul eax, [edx+TArray.itemsize] - mov eax, [edx+TArray.array+edx+TFStackCell.value] - - stdcall DeleteArrayItem, edx ; from the stack - clc - return - -.empty_stack: - xor eax, eax - stc - return -endp - - - -; arguments: -; ebx - TForthContext -; edx - offset to the string related to pWords memory. -; returns -; -proc forth_push_string -begin - add edx, [ebx+TForthContext.pWords] - push edx - stdcall AddArrayItem, [ebx+TForthContext.pAStack] - mov [ebx+TForthContext.pAStack], edx - mov [eax+TFStackCell.type], ftypeString - pop [eax+TFStackCell.value] - return -endp - - - - - - -endmodule - - - - - Index: freshlib/FreshEdit/FreshEdit.asm ================================================================== --- freshlib/FreshEdit/FreshEdit.asm +++ freshlib/FreshEdit/FreshEdit.asm @@ -17,11 +17,11 @@ ; - Associated debug information ; - save with format information (bookmarks and breakpoints) ; - Read-only lines ; - Undo and Redo functions. ; - Adjustable colors, keyboard and behavior. -; - Char, Block and Line selections. +; - Char and Block selections. ; - Syntax highlighters interface for different languages. ; - Interface to visual programming tools and auto source generators. ;_________________________________________________________________________________________ include "FreshEditThemes.asm" @@ -40,31 +40,38 @@ lfBookmark = 1 ; the line have bookmark set. lfFocused = 2 ; the line is focused until the user press some key. lfProtected = 4 ; the line can not be edited. lfWordWrap = 8 ; the line must be word wrapped. After changes, the format have to be updated. -lfBreakpoint = 16 ; set breakpoint in debug mode. -lfFoldHeader = 32 ; this is the first line of foldable part of the text. +lfHidden = 16 ; this line is hidden +lfBreakpoint = 32 ; set breakpoint in debug mode. struct TEditorLine .Data dd ? ; pointer to line data. .flags dd ? ; line flags + .syn_context dd ? ; flags about current syntax highlighter context after processing line. - .syn_context dd ? ; flags about current syntax highlighter context. + .fold_level dd ? .debugdata dd ? ; pointer to debug data, associated to this line - .fold_level dd ? ; the level of folding. - .width dd ? ; width of the line text in chars. It is the length of the string for non wrapped lines and maximal subline for wrapped. + .subcount dd ? ; count of wrapped sublines + .pSublines dd ? ; pointer to array containing offsets to the sublines inside the line. + align 32 .shift = 5 ends + +struct TScreenLine + .IndexLine dd ? + .Subline dd ? +ends + undoInsertText = 0 undoDeleteText = 1 - struct TUndoInfo .operation db ? ; what was changed??? .selMode db ? align 4 @@ -94,25 +101,28 @@ chgfNeedRefresh = 2 chgfFinished = 4 ; insert modes -modeInsert = 0 +modeInsert = 0 modeOverwrite = 1 ; selection modes selmChar = 0 -selmBlock = 1 +selmBlock = 1 ; when the editor is in block selection mode, the word wrap + ; feature must be switched OFF, because it is not possible + ; to select rectangular region, on word wrapped lines. ; flag ReadOnly values froReadWrite = 0 froReadOnlyWithCaret = 1 froReadOnlyNoCaret = 2 object TFreshEdit, TScrollWindow + ._Font dd ? ; font of the editor. ; main editor font sizes ._fontheight dd ? ; in pixels. ._fontwidth dd ? ; in pixels. @@ -123,49 +133,49 @@ ._fontwidth2 dd ? ; in pixels. ._fontdescent2 dd ? ; in pixels. .__LeftMargin dd ? ; width of the left margin field. Auto computed. .__NumberMargin dd ? ; width of the field for the line number. Auto computed. - ._ExtraFont dd ? ; ._cols dd ? ; width of the window in text columns. ._rows dd ? ; height of the window in text rows. - ; must to be update on resize and on font change. + ; must be updated on resize and on font change. ._pLines dd ? ; pointer to TArray of TEditorLine items. - ._pIndex dd ? ; pointer to TArray of dword that contains numbers of TEditorLine for the screen. ._pLengths dd ? ; pointer to TArray with counts of the lines with given length. ._pUndoList dd ? ; pointer to TArray of TUndoInfo ._pRedoList dd ? ; pointer to TArray of TUndoInfo - ._pShadow dd ? ; double buffer pointer to TBackBuffer object. + ._pShadow dd ? ; pointer to TBackBuffer object. ._fShadowValid dd ? ; + .pScreenIndex dd ? ; pointer to array of TScreenLine structures, containing + ; view change fields - ._TopLine dd ? ; number of the line that is at the topmost line of the window. ._LeftColumn dd ? ; the column of the text at the leftmost side of the window. - ._xCaret dd ? ; horizontal position of the caret inside the current line. - ._yCaret dd ? ; vertical position of the caret inside the text. + ._xCaret dd ? ; the number of the char the caret resides. + ._yCaret dd ? ; the index of the line the caret resides. ._xSelection dd ? ._ySelection dd ? ._fReadOnly dd ? - ._SelMode dd ? + ._SelMode dd ? ; NOTE: on selmBlock, the word wrap should be OFF ._InsMode dd ? ._TabStop dd ? ; end change fields ._prevTopLine dd ? + ._prevTopOffset dd ? ._prevLeftColumn dd ? - ._prevxCaret dd ? - ._prevyCaret dd ? + ._prevCaretChar dd ? + ._prevCaretLine dd ? ._prevxDelta dd ? ._prevyDelta dd ? ._prevSelMode dd ? @@ -173,102 +183,75 @@ ; end backup fields ._DragButton dd ? -; ._Theme TFETheme - ._procSyntax dd ? ; syntax highlighter procedure. +; icons and masks for the left margin ._iconBreakpointA dd ? ; active breakpoint icon. ._iconBreakpointI dd ? ; inactive breakpoint icon. ._iconDebugInfo dd ? ._maskBreakpointA dd ? ._maskBreakpointI dd ? ._maskDebugInfo dd ? - - ._iconUnfold dd ? ._iconFold dd ? - ._maskUnfold dd ? ; Event handlers .OnControlKey dd ? ; Parameters param .Selection ; selected text read/write - param .CurrentLine ; TEditorLine where caret resides. - param .Text + param .CurrentLine ; TEditorLine where caret resides. read only + param .Text ; whole text; read/write param .MaxLineLen -; Methods +; Commands - method .Clear ; clears the text in the editor. + method .Clear -; navigation methods - - method .Move, .direction, .count, .force ; moves the caret + method .Left + method .Right + method .Up + method .Down method .LineBegin method .LineEnd - method .ScreenBegin - method .ScreenEnd + method .FileBegin method .FileEnd -; editing methods + method .PageUp + method .PageDown + method .InsertString, .hString + +; + + method .GetText, .LineFrom, .CharFrom, .LineTo, .CharTo method .DeleteSel - method .InsertLine, .index ; index = -1 inserts at current position of the caret. - ; index = -2 appends the line at the end of the text. - method .DeleteLine, .index ; index = -1 deletes the line on the current position of the caret. - -; block processing methods. - method .DeleteText, .indexFrom, .charFrom, .indexTo, .charTo - method .GetText, .indexFrom, .charFrom, .indexTo, .charTo - -; Undo/Redo functions. - - method .RegisterForUndo, .operation, .data - - method .Undo - method .Redo - - method .ClearUndo - -; these two methods are flexible, but very slow. .Text parameter seting is fastest way to change whole text of the editor. - method .InsertChar, .char - method .InsertString, .hstring ; inserts a string at the caret position. - ; If the string contains formating chars they are processed properly. - method .DelChar ; deletes the char under the caret. - -; appearance methods - method .FormatLine, .index + +; Coordinates convertions + + method .PixelToCaret, .xPixel, .yPixel + method .CaretToPixel, .iRow, .xChar ; themes methods method LoadTheme, .configdb, .directory endobj -; about .pIndex field: -; -; This array contains the number of text lines that have to be displayed on the -; respective screen lines. -; Not every text line have screen line representation - it means the count of items of [pIntex] -; can be smaller than count of items of [pLines]. This case is when some lines are folded and not visible. -; On the other hand, another variant is also possible - several items of [pIndex] to point to -; one line in [pLines] - when the text line is wraped and displayed on several lines of the screen. -; -;_________________________________________________________________________________________ cDefaultEditorFont text 'Fixedsys Excelsior 3.01' ;cDefaultEditorFont text 'Droid sans mono' + ; left margin icons. ;iglobal getfile iconBreakpointA, 'images/breakpoint.gif' getfile iconBreakpointI, 'images/breakpoint_inactive.gif' @@ -279,20 +262,22 @@ getfile iconUnfold, 'images/unfold.gif' getfile iconFold, 'images/fold.gif' getfile maskUnfold, 'images/unfold_mask.gif' ;endg + proc TFreshEdit.Create, .pobj begin - push eax edx + push edx mov ebx, [.pobj] ; Main Font settings. stdcall FontCreate, cDefaultEditorFont, 0, 0, ffMonospaced mov [ebx+TFreshEdit._Font], eax + mov [ebx+TFreshEdit._cursor], mcText stdcall FontGetCharSize, [ebx+TFreshEdit.handle], [ebx+TFreshEdit._Font], __HeightProbeString test edx, edx jnz @f @@ -336,23 +321,16 @@ stdcall CreateImageGIF, maskUnfold, maskUnfold.size mov [ebx+TFreshEdit._maskUnfold], eax ; Init some values. - mov [ebx+TFreshEdit._TabStop], 8 - - mov [eax+TFETheme.WrapPos], 80 - mov [eax+TFETheme.UndoLevels], 20 - + mov [ebx+TFreshEdit._TabStop], 4 mov [ebx+TFreshEdit._DragButton], -1 stdcall CreateArray, sizeof.TEditorLine mov [ebx+TFreshEdit._pLines], eax - stdcall CreateArray, 4 - mov [ebx+TFreshEdit._pIndex], eax - stdcall CreateArray, 4 mov [ebx+TFreshEdit._pLengths], eax stdcall CreateArray, sizeof.TUndoInfo mov [ebx+TFreshEdit._pUndoList], eax @@ -361,11 +339,11 @@ mov [ebx+TFreshEdit._pRedoList], eax stdcall CreateBackBuffer, [ebx+TFreshEdit.handle], 1, 1 mov [ebx+TFreshEdit._pShadow], eax - pop edx eax + pop edx clc return endp @@ -374,28 +352,32 @@ proc TFreshEdit.Destroy, .pobj begin mov ebx, [.pobj] + +; free all text data execute ebx, TFreshEdit.Clear + +; free the allocated buffers stdcall FreeMem, [ebx+TFreshEdit._pLines] - stdcall FreeMem, [ebx+TFreshEdit._pIndex] stdcall FreeMem, [ebx+TFreshEdit._pLengths] stdcall FreeMem, [ebx+TFreshEdit._pUndoList] stdcall FreeMem, [ebx+TFreshEdit._pRedoList] +; destroy the shadow buffer. stdcall DestroyBackBuffer, [ebx+TFreshEdit._pShadow] +; destroy icon images. stdcall DestroyImage, [ebx+TFreshEdit._iconBreakpointA] stdcall DestroyImage, [ebx+TFreshEdit._iconBreakpointI] stdcall DestroyImage, [ebx+TFreshEdit._iconDebugInfo] stdcall DestroyImage, [ebx+TFreshEdit._maskBreakpointA] stdcall DestroyImage, [ebx+TFreshEdit._maskBreakpointI] stdcall DestroyImage, [ebx+TFreshEdit._maskDebugInfo] stdcall DestroyImage, [ebx+TFreshEdit._iconUnfold] stdcall DestroyImage, [ebx+TFreshEdit._iconFold] - stdcall DestroyImage, [ebx+TFreshEdit._maskUnfold] clc return endp @@ -424,42 +406,19 @@ .exit: return ;................................................................ .get_selection: - push esi - - mov esi, [.pobj] - mov eax, [esi+TFreshEdit._SelMode] - cmp eax, selmChar - je .get_sel_char - cmp eax, selmBlock - je .get_sel_block - - stc - return - -.get_sel_char: - execute esi, TFreshEdit.GetText, [esi+TFreshEdit._yCaret], [esi+TFreshEdit._xCaret], \ - [esi+TFreshEdit._ySelection], [esi+TFreshEdit._xSelection] - - clc - pop esi - return - - -.get_sel_block: - xor eax, eax - clc - pop esi - return - + mov ecx, [.pobj] + execute ecx, TFreshEdit.GetText, [ecx+TFreshEdit._yCaret], [ecx+TFreshEdit._xCaret], \ + [ecx+TFreshEdit._ySelection], [ecx+TFreshEdit._xSelection], [ecx+TFreshEdit._SelMode] + clc + return ;................................................................ .gettext: - push ebx ecx edx esi edi - + push ebx edx esi edi stdcall StrNew mov ebx, eax mov edi, [.pobj] @@ -468,12 +427,10 @@ jecxz .text_ready lea esi, [esi+TArray.array] .line_loop: - stdcall TFreshEdit.__AddFormatLine, ebx, [esi+TEditorLine.flags] - stdcall StrDup, [esi+TEditorLine.Data] push eax push eax push eax stdcall StrLen, eax @@ -493,57 +450,31 @@ jnz .loop_char .line_ready: stdcall StrCat, ebx ; from the stack. stdcall StrDel ; from the stack - stdcall StrCharCat, ebx, $0a0d + stdcall TFreshEdit.__AddFormatLine, ebx, [esi+TEditorLine.flags] .next_line: add esi, sizeof.TEditorLine loop .line_loop .text_ready: mov eax, ebx - pop edi esi edx ecx ebx + pop edi esi edx ebx clc return ;................................................................ .currentline: - push ebx edx edi - - mov edi, [.pobj] - mov eax, [edi+TFreshEdit._yCaret] - mov ebx, [edi+TFreshEdit._pIndex] - cmp eax, [ebx+TArray.count] - jae .errorcl - -.lineloop: - mov edx, [ebx+TArray.array+4*eax] - cmp edx, -1 - jne .found - - dec eax - jns .lineloop - -.errorcl: - stc - pop edi edx ebx - return - -; edx is the number of string in the lines array. -.found: - mov ebx, [edi+TFreshEdit._pLines] - cmp edx, [ebx+TArray.count] - jae .errorcl - - shl edx, TEditorLine.shift - lea eax, [ebx+TArray.array+edx] - + mov ecx, [.pobj] + stdcall GetArrayItem, [ecx+TFreshEdit._pLines], [ecx+TFreshEdit._yCaret] + jnc .endgcl + xor eax, eax +.endgcl: clc - pop edi edx ebx return ;................................................................ .maxlinelen: @@ -563,24 +494,17 @@ ;_________________________________________________________________________________________ proc TFreshEdit.Set, .pobj, .paramID, .value begin - push eax ebx edx esi edi - mov edi, [.pobj] - - mov eax, [.paramID] - cmp eax, TFreshEdit.Text + cmp [.paramID], TFreshEdit.Text je .settext - cmp eax, TFreshEdit.Selection + cmp [.paramID], TFreshEdit.Selection je .set_selection stc - -.finish: - pop edi esi edx ebx eax return ;......................................................................................... .set_selection: ; delete the old selection @@ -598,29 +522,23 @@ return ;......................................................................................... .settext: + locals .pLine dd ? -.flags dd ? endl + push eax ebx edx esi edi + + mov edi, [.pobj] execute edi, TFreshEdit.Clear stdcall StrPtr, [.value] mov esi, eax .lineloop: - mov [.flags], 0 - - stdcall TFreshEdit.__DecodeFormatLine, esi - jc .line_begin - - mov [.flags], eax - add esi, ecx - -.line_begin: push esi .char: lodsb test al, al @@ -668,32 +586,39 @@ pop edi esi ecx ; insert text line. stdcall AddArrayItems, [edi+TFreshEdit._pLines], 1 + jc .end_set_text + mov [edi+TFreshEdit._pLines], edx - mov ecx, [edx+TArray.count] mov [.pLine], eax mov [eax+TEditorLine.Data], ebx - push [.flags] - pop [eax+TEditorLine.flags] - mov [eax+TEditorLine.syn_context], 0 - mov [eax+TEditorLine.debugdata], 0 - mov [eax+TEditorLine.width], -1 - -; insert index line. - stdcall AddArrayItems, [edi+TFreshEdit._pIndex], 1 - mov [edi+TFreshEdit._pIndex], edx - + xor ecx, ecx + mov [eax+TEditorLine.flags], ecx + mov [eax+TEditorLine.syn_context], ecx + mov [eax+TEditorLine.debugdata], ecx + mov [eax+TEditorLine.fold_level], ecx dec ecx - mov [eax], ecx +; mov [eax+TEditorLine.width], ecx + + stdcall StrPtr, ebx + stdcall TFreshEdit.__DecodeFormatLine, eax + jc .format_ok + + mov edx, [.pLine] + mov [edx+TEditorLine.flags], eax + stdcall StrCopyPart, ebx, ebx, 0, ecx + +.format_ok: ; format the line mov ecx, [edx+TArray.count] dec ecx - execute edi, TFreshEdit.FormatLine, ecx + +; execute edi, TFreshEdit.FormatLine, ecx ; goto next line. cmp byte [esi], 0 jne .lineloop @@ -703,14 +628,15 @@ mov eax, [edi+TFreshEdit._pLengths] stdcall TFreshEdit.__UpdateScrollBars, edi mov [edi+TFreshEdit._fShadowValid], 0 +.end_set_text: clc - jmp .finish + pop edi esi edx ebx eax + return endp - ;_________________________________________________________________________________________ ; move commands @@ -734,296 +660,118 @@ cmp [.method], TFreshEdit.LineBegin je .linebegin cmp [.method], TFreshEdit.LineEnd je .lineend + + cmp [.method], TFreshEdit.FileBegin + je .filebegin + + cmp [.method], TFreshEdit.FileEnd + je .fileend + + cmp [.method], TFreshEdit.ScreenBegin + je .pagebegin + + cmp [.method], TFreshEdit.ScreenEnd + je .pageend cmp [.method], TFreshEdit.DeleteSel je .delete_selection cmp [.method], TFreshEdit.DeleteText je .delete_text cmp [.method], TFreshEdit.GetText je .get_text + + cmp [.method], TFreshEdit.InsertText + je .insert_text cmp [.method], TFreshEdit.DeleteLine je .delete_line - cmp [.method], TFreshEdit.InsertChar - je .insert_char - cmp [.method], TFreshEdit.InsertString je .insert_string cmp [.method], TFreshEdit.InsertLine je .insert_line - cmp [.method], TFreshEdit.FormatLine - je .format_line - cmp [.method], TFreshEdit.DelChar je .del_char + + cmp [.method], TFreshEdit.PixelToCaret + je .pixel_to_caret + + cmp [.method], TFreshEdit.CaretToPixel + je .caret_to_pixel stc return ;......................................................................................... .refresh: - mov eax, [.self] - mov [eax+TFreshEdit._fShadowValid], 0 + mov ecx, [.self] + mov [ecx+TFreshEdit._fShadowValid], 0 stc return -;......................................................................................... -; formats some line of the text, depending on the flags. Also, fix the index items for -; this line. -.format_line: -virtual at ebx - .index dd ? -end virtual - -; first get the line pointer -locals - .imin dd ? - .imax dd ? - .start_count dd ? - .rows dd ? - - .caret_ofs dd ? - .wrap_here dd ? - - .retval dd ? ; correction count on tab-expansion -endl - push ecx esi edi - - mov esi, [.self] - mov edi, [esi+TFreshEdit._pIndex] - - mov ecx, [.index] - cmp ecx, [edi+TArray.count] - jae .error_format - -.loop_end: - inc ecx - cmp ecx, [edi+TArray.count] - jae .end_found - cmp [edi+TArray.array+4*ecx], -1 - je .loop_end - -.end_found: - dec ecx - mov [.imax], ecx - - mov ecx, [.index] - inc ecx - -.loop_start: - dec ecx - js .error_format - - cmp [edi+TArray.array+4*ecx], -1 - je .loop_start - - mov [.imin], ecx - mov [.rows], 1 ; how many lines are withit the line - - mov ecx, [edi+TArray.array+4*ecx] ; index in _pLines array. - shl ecx, TEditorLine.shift - add ecx, [esi+TFreshEdit._pLines] - lea edi, [ecx+TArray.array] ; edi points to TEditorLine structure. - -; begin of formating - stdcall StrClipSpacesR, [edi+TEditorLine.Data] - stdcall ExpandTabs, [edi+TEditorLine.Data], [esi+TFreshEdit._TabStop] - mov [.retval], eax - stdcall StrLen, [edi+TEditorLine.Data] - mov ecx, eax - mov [.start_count], eax - jecxz .wrap_ok - - stdcall StrPtr, [edi+TEditorLine.Data] - mov edx, eax - -; first replace $01 with $20 (wrap char to space) - push edx ecx -.spc_loop: - cmp byte [edx], $01 - jne @f - mov byte [edx], $20 -@@: - inc edx - loop .spc_loop - pop ecx edx - -; word wrap? - test [edi+TEditorLine.flags], lfWordWrap - jz .wrap_ok - - push edi - - mov edi, edx -.wrap_outer: - mov ecx, [FreshEditTheme.WrapPos] - inc ecx - mov [.wrap_here], -1 - xor edx, edx - -.wrap_loop: - add edi, edx - stdcall DecodeUtf8, [edi] - test eax, eax - jz .wrap_ready - - cmp eax, ' ' - jne @f - mov [.wrap_here], edi -@@: - loop .wrap_loop - - cmp [.wrap_here], -1 - jne .do_wrap - -.forward: - add edi, edx - stdcall DecodeUtf8, [edi] - test eax, eax - jz .wrap_ready - - cmp eax, ' ' - jne .forward - - mov [.wrap_here], edi - -.do_wrap: - mov edi, [.wrap_here] - mov byte [edi], $01 ; wrap the line. - inc edi - inc [.rows] - jmp .wrap_outer - - -.wrap_ready: -; ready, so fix the index. - pop edi - -.wrap_ok: - mov eax, [.imin] - inc eax - - mov ecx, [.imax] - sub ecx, [.imin] - inc ecx - sub ecx, [.rows] ; ecx>0 means some rows from the index must be deleted - ; ecx<0 means some rows must be added. - ; ecx=0 means the index is ok - jz .index_ok - js .add_more_index - - stdcall DeleteArrayItems, [esi+TFreshEdit._pIndex], eax, ecx - mov [esi+TFreshEdit._pIndex], edx - jmp .index_ok - -.add_more_index: - neg ecx - stdcall InsertArrayItems, [esi+TFreshEdit._pIndex], eax, ecx - mov [esi+TFreshEdit._pIndex], edx - -.fill_new_items: - mov dword [eax], -1 - lea eax, [eax+4] - loop .fill_new_items - -.index_ok: - stdcall TFreshEdit.__LineWidth, [edi+TEditorLine.Data] - xchg eax, [edi+TEditorLine.width] - stdcall TFreshEdit.__FixLength, esi, [edi+TEditorLine.width], eax - - clc - mov eax, [.retval] - mov edx, [.imin] - pop edi esi ecx - return - -.error_format: - int3 - mov eax, -1 - clc - pop edi esi ecx - return ;......................................................................................... .delete_line: virtual at ebx - .del_index dd ? + .del_index dd ? end virtual - push edx esi edi + push edx esi mov esi, [.self] mov eax, [.del_index] cmp eax, -1 jne @f mov eax, [esi+TFreshEdit._yCaret] @@: - mov edi, [esi+TFreshEdit._pIndex] - cmp eax, [edi+TArray.count] + mov edx, [esi+TFreshEdit._pLines] + cmp eax, [edx+TArray.count] jae .end_del_line -.beg_search: - cmp [edi+TArray.array+4*eax], -1 ; word wrap - jne .do_del - dec eax - jnz .beg_search - -.do_del: - mov ecx, [edi+TArray.array+4*eax] - shl ecx, TEditorLine.shift - add ecx, TArray.array - add ecx, [esi+TFreshEdit._pLines] + shl eax, TEditorLine.shift + lea ecx, [edx+TArray.array+eax] + shr eax, TEditorLine.shift + stdcall StrDel, [ecx+TEditorLine.Data] stdcall TFreshEdit.__FixLength, esi, -1, [ecx+TEditorLine.width] - - stdcall DeleteArrayItems, [esi+TFreshEdit._pLines], [edi+TArray.array+4*eax], 1 + stdcall DeleteArrayItems, edx, eax, 1 mov [esi+TFreshEdit._pLines], edx -.del_index2: - stdcall DeleteArrayItems, edi, eax, 1 - mov edi, edx - cmp eax, [edi+TArray.count] - jae .end_del_index2 - - cmp [edi+TArray.array+4*eax], -1 - je .del_index2 - -.end_del_index2: - mov [esi+TFreshEdit._pIndex], edi - push eax - -; fix the index to the end: -.fix_index_del: - cmp eax, [edi+TArray.count] - jae .end_fix_index - - cmp [edi+TArray.array+4*eax], -1 - je @f - dec [edi+TArray.array+4*eax] -@@: - inc eax - jmp .fix_index_del - -.end_fix_index: - pop eax +; delete the wrapped line (if any) .end_del_line: clc - pop edi esi edx + pop esi edx return ;......................................................................................... .get_text: ; have the same arguments and local variables as .delete_text +virtual at ebx ; arguments + .indexFrom dd ? + .charFrom dd ? + .indexTo dd ? + .charTo dd ? + .BlockKind dd ? +end virtual +locals + .final_str dd ? + .final_flags dd ? + .final_level dd ? + .fromline dd ? + .toline dd ? + .ret_str dd ? +endl + pushad + mov [.ret_str], 0 ; sort the "from" and "To" in order to have "From" < "To" mov eax, [.indexFrom] mov ecx, [.charFrom] @@ -1036,26 +784,35 @@ xchg eax, [.indexTo] xchg ecx, [.charTo] mov [.indexFrom], eax mov [.charFrom], ecx @@: + mov esi, [.self] ; last line processing - stdcall TFreshEdit.__PosToPointer, [.self], [.charTo], [.indexTo] - mov [.toline], edx + stdcall GetArrayItem, [esi+TFreshEdit._pLines], [.indexTo] + jc .error_get - stdcall StrExtract, [edx+TEditorLine.Data], 0, eax + mov [.toline], eax + mov edx, eax + stdcall StrOffsUtf8, [edx+TEditorLine.Data], [.charTo] + stdcall StrExtract, [edx+TEditorLine.Data], 0, eax mov [.final_str], eax ; first line processing - stdcall TFreshEdit.__PosToPointer, [.self], [.charFrom], [.indexFrom] - mov [.fromline], edx + stdcall GetArrayItem, [esi+TFreshEdit._pLines], [.indexFrom] + jc .error_get + + mov [.fromline], eax + mov edx, eax + stdcall StrOffsUtf8, [edx+TEditorLine.Data], [.charFrom] mov edi, [edx+TEditorLine.Data] cmp edx, [.toline] jne .dup_first mov edi, [.final_str] + .dup_first: push eax stdcall StrDup, edi mov edi, eax pop eax @@ -1113,480 +870,350 @@ clc popad mov eax, [.ret_str] return +.error_get: + clc + popad + xor eax, eax + return + +;......................................................................................... +; method .InsertText, .lineFrom, .charFrom, .hString, .fInsert +.insert_text: +virtual at ebx + .lineFrom2 dd ? + .charFrom2 dd ? + .hString2 dd ? + .fInsert dd ? +end virtual + +locals + .suffix dd ? + .end_ptr dd ? + .current_line dd ? + .current_char dd ? + .ptr_line dd ? + .char_count dd ? +endl + pushad + + mov esi, [.self] + +.search_line: + stdcall GetArrayItem, [esi+TFreshEdit._pLines], [.lineFrom2] + jnc .linefound + + execute esi, TFreshEdit.InsertLine, -2 + jmp .search_line + +.linefound: + mov edi, eax + mov eax, [.lineFrom2] + mov [.current_line], eax + + mov [.suffix], 0 + + stdcall StrOffsUtf8, [edi+TEditorLine.Data], [.charFrom2] + test ecx, ecx + jnz .add_spaces + + stdcall StrSplit, [edi+TEditorLine.Data], eax + mov [.suffix], eax + jmp .do_insertion + +.add_spaces: + stdcall StrCharCat, [edi+TEditorLine.Data], ' ' + dec ecx + jnz .add_spaces + +.do_insertion: + stdcall StrPtr, [.hString2] + mov esi, eax + stdcall StrLen, [.hString2] + lea eax, [esi+eax] + mov [.end_ptr], eax + + stdcall StrLen, [edi+TEditorLine.Data] + mov ecx, eax + stdcall StrLen, [.hString2] + add ecx, eax + +.loop_lines: + mov [.ptr_line], edi + + stdcall StrSetCapacity, [edi+TEditorLine.Data], ecx + mov edi, eax + lea ecx, [edi+string.len] + add edi, [ecx] ; append the string to the end... + mov [.char_count], 0 + +.append_loop: + stdcall DecodeUtf8, [esi] + test eax, eax + jz .end_of_string + + cmp eax, $0d + je .new_line + cmp eax, $0a + je .new_line + + mov eax, [esi] + mov [edi], eax + add esi, edx + add edi, edx + + add [ecx], edx + inc [.char_count] + jmp .append_loop + +.new_line: + xor al, $0d xor $0a + inc esi + cmp [esi], al + jne @f + inc esi +@@: + call .finish_current_line + + inc [.current_line] + execute [.self], TFreshEdit.InsertLine, [.current_line] + mov edi, eax + + mov ecx, [.end_ptr] + sub ecx, esi + jmp .loop_lines + + +.finish_current_line: + xor eax, eax + stosd + + cmp [.fInsert], modeInsert + je .overwrite_ok + + cmp [.suffix], 0 + je .overwrite_ok + + stdcall StrOffsUtf8, [.suffix], [.char_count] + jecxz .split_suffix + + stdcall StrDel, [.suffix] + mov [.suffix], 0 + retn + +.split_suffix: + stdcall StrSplit, [.suffix], eax + xchg [.suffix], eax + stdcall StrDel, eax + +.overwrite_ok: + retn + + +.end_of_string: + call .finish_current_line + + mov edi, [.ptr_line] + + stdcall StrLenUtf8, [edi+TEditorLine.Data], -1 + mov [.current_char], eax + + cmp [.suffix], 0 + je .last_ok + + stdcall StrCat, [edi+TEditorLine.Data], [.suffix] + stdcall StrDel, [.suffix] + +.last_ok: + +.finish_ins_text: + popad + mov eax, [.current_line] + mov edx, [.current_char] + clc + return + ;......................................................................................... .delete_text: -virtual at ebx ; arguments - .indexFrom dd ? - .charFrom dd ? - .indexTo dd ? - .charTo dd ? -end virtual -locals - .final_str dd ? - .final_flags dd ? - .final_level dd ? - .fromline dd ? - .toline dd ? - .ret_str dd ? -endl +; have the same arguments and local variables as .get_text pushad ; sort the "from" and "To" in order to have "From" < "To" mov eax, [.indexFrom] mov ecx, [.charFrom] cmp eax, [.indexTo] jne @f cmp ecx, [.charTo] @@: - je .nothing_to_delete ; from == to so nothing to delete. + je .finish_delete ; from == to so nothing to delete. jb @f xchg eax, [.indexTo] xchg ecx, [.charTo] mov [.indexFrom], eax mov [.charFrom], ecx @@: - + mov esi, [.self] ; last line processing - stdcall TFreshEdit.__PosToPointer, [.self], [.charTo], [.indexTo] + stdcall GetArrayItem, [esi+TFreshEdit._pLines], [.indexTo] + jc .finish_delete + mov edx, eax + stdcall StrOffsUtf8, [edx+TEditorLine.Data], [.charTo] stdcall StrSplit, [edx+TEditorLine.Data], eax mov [.final_str], eax mov eax, [edx+TEditorLine.flags] mov ecx, [edx+TEditorLine.fold_level] mov [.final_flags], eax mov [.final_level], ecx ; first line processing - stdcall TFreshEdit.__PosToPointer, [.self], [.charFrom], [.indexFrom] - mov [.fromline], edx + stdcall GetArrayItem, [esi+TFreshEdit._pLines], [.indexFrom] + jc .finish_delete + mov edx, eax + mov [.fromline], eax - jecxz .splitit - add eax, ecx + stdcall StrOffsUtf8, [edx+TEditorLine.Data], [.charFrom] + stdcall StrTrim, [edx+TEditorLine.Data], eax + .addspc: - stdcall StrCharCat, [edx+TEditorLine.Data], ' ' dec ecx - jnz .addspc + js .catit + stdcall StrCharCat, [edx+TEditorLine.Data], ' ', eax + jmp .addspc -.splitit: - stdcall StrSplit, [edx+TEditorLine.Data], eax - stdcall StrDel, eax +.catit: stdcall StrCat, [edx+TEditorLine.Data], [.final_str] stdcall StrDel, [.final_str] mov eax, [.final_level] mov ecx, [.final_flags] mov [edx+TEditorLine.fold_level], eax or [edx+TEditorLine.flags], ecx ; now delete all lines except the first. - - mov edi, [.indexTo] - -.del_loop: - stdcall TFreshEdit.__PosToPointer, [.self], -1, edi - cmp edx, [.fromline] - je .delete_ok - - execute [.self], TFreshEdit.DeleteLine, edi - mov edi, eax - dec edi - jmp .del_loop - - -.delete_ok: - execute [.self], TFreshEdit.FormatLine, [.indexFrom] - + mov eax, [.indexFrom] + mov ecx, [.indexTo] + sub ecx, eax + inc eax + stdcall DeleteArrayItems, [esi+TFreshEdit._pLines], eax, ecx + mov [esi+TFreshEdit._pLines], edx + +.finish_delete: clc popad mov eax, [.indexFrom] mov edx, [.charFrom] return -.nothing_to_delete: - clc - popad - xor eax, eax - dec eax - return ;......................................................................................... ; delete the selection .delete_selection: - mov esi, [.self] - mov eax, [esi+TFreshEdit._SelMode] - cmp eax, selmChar - je .del_sel_char - cmp eax, selmBlock - je .del_sel_block - - stc - return - -.del_sel_char: - execute esi, TFreshEdit.DeleteText, [esi+TFreshEdit._yCaret], [esi+TFreshEdit._xCaret], \ - [esi+TFreshEdit._ySelection], [esi+TFreshEdit._xSelection] - clc - return - - -.del_sel_block: + mov ecx, [.self] + execute ecx, TFreshEdit.DeleteText, [ecx+TFreshEdit._yCaret], [ecx+TFreshEdit._xCaret], \ + [ecx+TFreshEdit._ySelection], [ecx+TFreshEdit._xSelection], [ecx+TFreshEdit._SelMode] + clc return ;......................................................................................... + .insert_line: virtual at ebx .ins_index dd ? end virtual - push esi edi + push edx esi + mov esi, [.self] - -; first where to search. The next line is OK, but if the line is wrapped... - cmp [.ins_index], -1 - jne @f - mov eax, [esi+TFreshEdit._yCaret] - mov [.ins_index], eax -@@: - - mov edi, [esi+TFreshEdit._pIndex] - mov edx, [.ins_index] - - cmp edx, [edi+TArray.count] - jb .search_begin - -; insert as a last line - mov edx, [edi+TArray.count] - mov ecx, -1 - jmp .ins_here - -; if the line is wrapped, search for the begin. -.search_begin: - mov ecx, [edi+TArray.array+4*edx] - cmp ecx, -1 ; wrapped line? - jne .ins_here - dec edx - jns .search_begin - jmp .err_ins_line - -; ...insert index item. -; edx contains the index in _pIndex where the new line have to be inserted. -; ecx contains the index in _pLines where the new line have to be inserted. -.ins_here: - push edx - stdcall InsertArrayItems, [esi+TFreshEdit._pIndex], edx, 1 - mov [esi+TFreshEdit._pIndex], edx - mov edi, edx - pop edx - jc .err_ins_line + mov edx, [esi+TFreshEdit._pLines] + mov ecx, [.ins_index] cmp ecx, -1 - jne .storeline - - mov ecx, [esi+TFreshEdit._pLines] - mov ecx, [ecx+TArray.count] - -.storeline: - mov [eax], ecx - -; ...then fix the index to the end. - - sub edx, [edi+TArray.count] - neg edx - dec edx - jle .index_fixed - -.inc_index: - lea eax, [eax+4] - cmp dword [eax], -1 - je @f - inc dword [eax] + jne @f + mov ecx, [esi+TFreshEdit._yCaret] + inc ecx +@@: + cmp ecx, [edx+TArray.count] + jb @f + mov ecx, [edx+TArray.count] @@: - dec edx - jnz .inc_index - -.index_fixed: -; then insert new line - stdcall InsertArrayItems, [esi+TFreshEdit._pLines], ecx, 1 + stdcall InsertArrayItems, edx, ecx, 1 mov [esi+TFreshEdit._pLines], edx jc .err_ins_line + mov ebx, eax - mov edx, eax stdcall StrNew - - mov [edx+TEditorLine.Data], eax + mov [ebx+TEditorLine.Data], eax xor eax, eax - mov [edx+TEditorLine.flags], eax - mov [edx+TEditorLine.syn_context], eax - mov [edx+TEditorLine.debugdata], eax - mov [edx+TEditorLine.width], eax - mov eax, edx + mov [ebx+TEditorLine.flags], eax + mov [ebx+TEditorLine.syn_context], eax + mov [ebx+TEditorLine.debugdata], eax + mov [ebx+TEditorLine.fold_level], eax + mov [ebx+TEditorLine.width], eax stdcall TFreshEdit.__FixLength, esi, 0, -1 - pop edi esi + mov eax, ebx + +.finish_ins_line: + pop esi edx clc return .err_ins_line: - pop edi esi - stc - return + xor eax, eax + jmp .finish_ins_line ;......................................................................................... .del_char: locals - .del_char_line dd ? - .del_line_index dd ? - .byte_offs dd ? + .del_char_to_line dd ? + .del_char_to_char dd ? endl - push ecx edx esi edi + push eax ecx edx esi mov esi, [.self] - stdcall TFreshEdit.__PosToPointer, esi, [esi+TFreshEdit._xCaret], [esi+TFreshEdit._yCaret] - jc .end_del_char + mov eax, [esi+TFreshEdit._xCaret] + mov ecx, [esi+TFreshEdit._yCaret] + mov [.del_char_to_char], eax + mov [.del_char_to_line], ecx + inc [.del_char_to_char] - test [edx+TEditorLine.flags], lfProtected - jnz .end_del_char + stdcall GetArrayItem, [esi+TFreshEdit._pLines], ecx + jc .do_del_char + stdcall StrOffsUtf8, [eax+TEditorLine.Data], [.del_char_to_char] jecxz .do_del_char -.del_pad_spc: - stdcall StrCharInsert, [edx+TEditorLine.Data], ' ', eax - inc eax - loop .del_pad_spc + mov [.del_char_to_char], 0 + inc [.del_char_to_line] .do_del_char: - mov [.byte_offs], eax - mov [.del_char_line], edx - mov ebx, eax - stdcall StrLen, [edx+TEditorLine.Data] - cmp ebx, eax - je .join_next_line - - mov ecx, eax - sub ecx, ebx - - stdcall StrPtr, [edx+TEditorLine.Data] - mov edi, eax - stdcall DecodeUtf8, [edi+ebx] - lea esi, [edi+edx] - sub [edi+string.len], edx - add esi, ebx - add edi, ebx - cld - rep movsb - -.end_del_char: - mov eax, [.byte_offs] - pop edi esi edx ecx - clc - return - -.join_next_line: - mov eax, [.del_char_line] - mov edx, [esi+TFreshEdit._pLines] - sub eax, edx - sub eax, TArray.array - shr eax, TEditorLine.shift - inc eax - cmp eax, [edx+TArray.count] - jae .end_del_char - - mov [.del_line_index], eax - - mov edx, [.del_char_line] - mov ebx, edx - add edx, sizeof.TEditorLine - test [edx+TEditorLine.flags], lfProtected - jz .do_join - - stdcall StrLen, [ebx+TEditorLine.Data] - test eax, eax - jnz .end_del_char - -.do_join: - stdcall StrCat, [ebx+TEditorLine.Data], [edx+TEditorLine.Data] - mov eax, [edx+TEditorLine.flags] - or [ebx+TEditorLine.flags], eax - -; now delete the line - stdcall TFreshEdit.__FixLength, esi, -1, [edx+TEditorLine.width] - stdcall StrDel, [edx+TEditorLine.Data] - stdcall DeleteArrayItems, [esi+TFreshEdit._pLines], [.del_line_index], 1 - mov [esi+TFreshEdit._pLines], edx - -; then fix the index. - mov edi, [esi+TFreshEdit._pIndex] - mov eax, [esi+TFreshEdit._yCaret] - mov edx, [.del_line_index] - inc eax - -.char_fix_index: - cmp eax, [edi+TArray.count] - jae .end_del_char - - cmp [edi+TArray.array+4*eax], -1 - je .next_line_fix - cmp [edi+TArray.array+4*eax], edx - je .del_index_elements - - dec [edi+TArray.array+4*eax] - -.next_line_fix: - inc eax - jmp .char_fix_index - -.del_index_elements: - mov ecx, eax - -.char_scan_loop: - inc ecx - cmp ecx, [edi+TArray.count] - jae .end_char_scan - cmp [edi+TArray.array+4*ecx], -1 - je .char_scan_loop - -.end_char_scan: - sub ecx, eax - stdcall DeleteArrayItems, edi, eax, ecx - mov [esi+TFreshEdit._pIndex], edx - mov edi, edx - mov edx, [.del_line_index] - jmp .char_fix_index - -;......................................................................................... -.insert_char: -; arguments -virtual at ebx - .ins_char dd ? -end virtual - - push ecx edx esi edi - - mov esi, [.self] -.ins_loop: - stdcall TFreshEdit.__PosToPointer, esi, [esi+TFreshEdit._xCaret], [esi+TFreshEdit._yCaret] - jnc .line_found - - execute [.self], TFreshEdit.InsertLine, -2 - jnc .ins_loop ; possible hang! - - xor edx, edx - jmp .end_ins_char - -.line_found: - test [edx+TEditorLine.flags], lfProtected - jz .not_protected - - lea edx, [eax+ecx] - jmp .end_ins_char - -.not_protected: - cmp [.ins_char], $0d - je .split_here - cmp [.ins_char], $0a - je .split_here - - jecxz .spaces_ok - -.addspc2: - stdcall StrCharInsert, [edx+TEditorLine.Data], ' ', eax - inc eax - loop .addspc2 - -.spaces_ok: -.do_ins_char: - stdcall StrCharInsert, [edx+TEditorLine.Data], [.ins_char], eax - mov esi, eax - stdcall DecodeUtf8, [.ins_char] - add edx, esi - jmp .end_ins_char - -.split_here: - push eax edx - - mov eax, [esi+TFreshEdit._yCaret] - inc eax - execute [.self], TFreshEdit.InsertLine, eax - mov edi, eax - - pop edx eax - stdcall StrSplit, [edx+TEditorLine.Data], eax - - stdcall StrDel, [edi+TEditorLine.Data] - mov [edi+TEditorLine.Data], eax - - mov eax, [esi+TFreshEdit._yCaret] - inc eax - execute esi, TFreshEdit.FormatLine, eax - execute esi, TFreshEdit.FormatLine, [esi+TFreshEdit._yCaret] - -.split_ok: - execute esi, TFreshEdit.LineBegin - execute esi, TFreshEdit.Move, mvcMoveY, 1, TRUE - xor edx, edx - -.end_ins_char: - push edx - mov esi, [.self] - stdcall TFreshEdit.__PointerToPos, [.self], [esi+TFreshEdit._yCaret], edx - mov [esi+TFreshEdit._xCaret], edx - mov [esi+TFreshEdit._yCaret], eax - pop eax - clc - pop edi esi edx ecx - return -;......................................................................................... - -.insert_string: -; arguments + execute esi, TFreshEdit.DeleteText, [esi+TFreshEdit._yCaret], [esi+TFreshEdit._xCaret], [.del_char_to_line], [.del_char_to_char], selmChar + pop esi edx ecx eax + clc + return + +;......................................................................................... + +.insert_string: virtual at ebx .hstring dd ? end virtual - push ecx edx esi - - stdcall StrPtr, [.hstring] - mov esi, eax - -.char_loop: - stdcall DecodeUtf8, [esi] - jc .end_ins_str - - mov eax, [esi] - add esi, edx - - lea ecx, [8*edx] - mov edx, 1 - shl edx, cl - dec edx - and eax, edx - - cmp eax, 0 - je .end_ins_str - - cmp eax, $0d - je .ins_cr - cmp eax, $0a - jne .ins_it - -.ins_cr: - xor al, $0d xor $0a - cmp al, [esi] - je .char_loop - -.ins_it: - execute [.self], TFreshEdit.InsertChar, eax - jmp .char_loop - -.end_ins_str: - clc - pop esi edx ecx + push eax edx + mov ecx, [.self] + + execute ecx, TFreshEdit.InsertText, [ecx+TFreshEdit._yCaret], [ecx+TFreshEdit._xCaret], [.hstring], [ecx+TFreshEdit._InsMode] + mov [ecx+TFreshEdit._yCaret], eax + mov [ecx+TFreshEdit._xCaret], edx + + pop edx eax + clc return ;......................................................................................... .linebegin: stdcall TFreshEdit.__FitCaretInWindow, [.self] @@ -1600,47 +1227,117 @@ clc return ;......................................................................................... .lineend: - push ecx edx esi edi + push edx esi edi mov esi, [.self] stdcall TFreshEdit.__FitCaretInWindow, esi jnz .endle - mov esi, [.self] - mov ecx, [esi+TFreshEdit._yCaret] - mov ebx, [esi+TFreshEdit._pIndex] - - stdcall TFreshEdit.__PosToPointer, esi, [esi+TFreshEdit._xCaret], [esi+TFreshEdit._yCaret] - mov ebx, eax - - stdcall StrPtr, [edx+TEditorLine.Data] - mov edi, eax - -; search the end of the current line -.el_loop: - stdcall DecodeUtf8, [edi+ebx] - test eax, eax - jz .el_found - cmp eax, $01 - je .el_found - - add ebx, edx - jmp .el_loop - -.el_found: - stdcall TFreshEdit.__PointerToPos, esi, [esi+TFreshEdit._yCaret], ebx - mov [esi+TFreshEdit._yCaret], eax - mov [esi+TFreshEdit._xCaret], edx + + stdcall GetArrayItem, [esi+TFreshEdit._pLines], [esi+TFreshEdit._yCaret] + jnc .inline + + mov [esi+TFreshEdit._xCaret], 0 + jmp .endle + +.inline: + mov eax, [eax+TEditorLine.width] + mov [esi+TFreshEdit._xCaret], eax .endle: - stdcall TFreshEdit.__FitCaretInWindow, esi - pop edi esi edx ecx + pop edi esi edx + clc + return + + +;......................................................................................... +.filebegin: + mov ecx, [.self] + + stdcall TFreshEdit.__FitCaretInWindow, ecx + jnz .endfb + + mov [ecx+TFreshEdit._TopLine], 0 + mov [ecx+TFreshEdit._yCaret], 0 + mov [ecx+TFreshEdit._ySelection], 0 + +.endfb: + clc + return + +;......................................................................................... +.fileend: + mov ecx, [.self] + + stdcall TFreshEdit.__FitCaretInWindow, ecx + jnz .endfe + + mov eax, [ecx+TFreshEdit._pLines] + mov eax, [eax+TArray.count] + dec eax + jns @f + inc eax +@@: + mov [ecx+TFreshEdit._yCaret], eax + mov [ecx+TFreshEdit._ySelection], eax + + inc eax + sub eax, [ecx+TFreshEdit._rows] + jns @f + xor eax, eax +@@: + mov [ecx+TFreshEdit._TopLine], eax + +.endfe: + clc + return + +;......................................................................................... +.pagebegin: + mov ecx, [.self] + stdcall TFreshEdit.__FitCaretInWindow, ecx + jnz .endpb + + mov eax, [ecx+TFreshEdit._TopLine] + mov [ecx+TFreshEdit._yCaret], eax + mov [ecx+TFreshEdit._ySelection], eax + +.endpb: + clc + return + +;......................................................................................... +.pageend: + push edx + + mov ecx, [.self] + stdcall TFreshEdit.__FitCaretInWindow, ecx + jnz .endpe + + mov eax, [ecx+TFreshEdit._TopLine] + add eax, [ecx+TFreshEdit._rows] + dec eax + jns @f + xor eax, eax +@@: + mov edx, [ecx+TFreshEdit._pLines] + cmp eax, [edx+TArray.count] + jb @f + mov eax, [edx+TArray.count] + dec eax +@@: + mov [ecx+TFreshEdit._yCaret], eax + mov [ecx+TFreshEdit._ySelection], eax + +.endpe: + pop edx clc return + ;......................................................................................... ; The method TFreshEdit.Move moves the caret towards given direction and on ; the given count of steps. ; @@ -1661,15 +1358,16 @@ cmp [.force], 0 jne .fitok stdcall TFreshEdit.__FitCaretInWindow, esi - - test eax, eax jnz .endmove .fitok: + test [.direction], mvcMoveX or mvcMoveY or mvcScrollX or mvcScrollY + jz .endmove + test [.direction], mvcMoveX or mvcScrollX jnz .move_horizontal test [.direction], mvcMoveY or mvcScrollY jnz .move_vertical @@ -1682,34 +1380,30 @@ .move_horizontal: test [.direction], mvcMoveX jz .xcaretok - mov ecx, [esi+TFreshEdit._xCaret] - add ecx, [.count] - jns @f - xor ecx, ecx -@@: - mov [esi+TFreshEdit._xCaret], ecx + mov ecx, [.count] + add [esi+TFreshEdit._xCaret], ecx + jns .xcaretok + mov [esi+TFreshEdit._xCaret], 0 .xcaretok: test [.direction], mvcScrollX jz .leftcolok - mov ecx, [esi+TFreshEdit._LeftColumn] - add ecx, [.count] - jns @f - xor ecx, ecx -@@: - mov [esi+TFreshEdit._LeftColumn], ecx + mov ecx, [.count] + add [esi+TFreshEdit._LeftColumn], ecx + jns .leftcolok + mov [esi+TFreshEdit._LeftColumn], 0 .leftcolok: - mov ecx, [esi+TFreshEdit._xCaret] mov edx, [esi+TFreshEdit._LeftColumn] cmp ecx, edx jb .hscroll + add edx, [esi+TFreshEdit._cols] cmp ecx, edx jb .endmove .hscroll: @@ -1735,42 +1429,27 @@ .move_vertical: test [.direction], mvcMoveY jz .ycaretok - mov ecx, [esi+TFreshEdit._yCaret] - add ecx, [.count] - jns @f - xor ecx, ecx -@@: - mov [esi+TFreshEdit._yCaret], ecx + mov ecx, [.count] + add [esi+TFreshEdit._yCaret], ecx + jns .ycaretok + mov [esi+TFreshEdit._yCaret], 0 .ycaretok: test [.direction], mvcScrollY jz .toplineok - mov ecx, [esi+TFreshEdit._TopLine] - add ecx, [.count] - jns @f - xor ecx, ecx -@@: - mov edx, [esi+TFreshEdit._pIndex] - mov edx, [edx+TArray.count] - sub edx, [esi+TFreshEdit._rows] - jns @f - xor edx, edx -@@: - cmp ecx, edx - jl @f - mov ecx, edx -@@: - mov [esi+TFreshEdit._TopLine], ecx + mov ecx, [.count] + add [esi+TFreshEdit._TopLine], ecx + jns .toplineok + mov [esi+TFreshEdit._TopLine], 0 .toplineok: - mov ecx, [esi+TFreshEdit._yCaret] - mov eax, [esi+TFreshEdit._pIndex] + mov eax, [esi+TFreshEdit._pLines] mov eax, [eax+TArray.count] cmp ecx, eax jb @f lea ecx, [eax-1] @@: @@ -1778,10 +1457,13 @@ mov edx, [esi+TFreshEdit._TopLine] cmp ecx, edx jb .vscroll add edx, [esi+TFreshEdit._rows] + cmp edx, eax + jae .vscroll + cmp ecx, edx jb .endmove .vscroll: test [.direction], mvcMoveX or mvcMoveY @@ -1821,17 +1503,13 @@ dec ecx jmp .clrloop .endclr: mov ebx, [.self] - stdcall FreeMem, [ebx+TFreshEdit._pIndex] stdcall FreeMem, [ebx+TFreshEdit._pLines] stdcall FreeMem, [ebx+TFreshEdit._pLengths] - stdcall CreateArray, 4 - mov [ebx+TFreshEdit._pIndex], eax - stdcall CreateArray, sizeof.TEditorLine mov [ebx+TFreshEdit._pLines], eax stdcall CreateArray, 4 mov [ebx+TFreshEdit._pLengths], eax @@ -1847,10 +1525,91 @@ execute ebx, TFreshEdit.Refresh stdcall TFreshEdit.__UpdateScrollBars, ebx clc return + + +;......................................................................................... +; method .PixelToCaret, .xPixel, .yPixel +; .xPixel, .yPixel - coordinates of pixel related to the editor window. +; Returns: +; eax - index of the text line in TFreshEdit._pLines array. +; edx - character in the line. +.pixel_to_caret: +virtual at ebx + .xPixel dd ? + .yPixel dd ? +end virtual + + mov esi, [.self] + + mov ecx, [.xPixel] + mov eax, [.yPixel] + + mov edi, [esi+TFreshEdit._FreeArea.x] + mov edx, [esi+TFreshEdit._FreeArea.y] + + cmp ecx, edi + jl .pixel_outside + cmp eax, edx + jl .pixel_outside + + add edi, [esi+TFreshEdit._FreeArea.width] + add edx, [esi+TFreshEdit._FreeArea.height] + + cmp ecx, edi + jge .pixel_outside + cmp eax, edx + jge .pixel_outside + + sub ecx, [esi+TFreshEdit.__LeftMargin] + jge @f + xor ecx, ecx +@@: + cdq + idiv [esi+TFreshEdit._fontheight] + add eax, [esi+TFreshEdit._TopOffset] + mov [.yPixel], eax + + mov eax, ecx + cdq + idiv [esi+TFreshEdit._fontwidth] + add eax, [esi+TFreshEdit._LeftColumn] + mov [.xPixel], eax + +; search the line and char + +; first the line: + mov edi, [esi+TFreshEdit._TopLine] + stdcall GetArrayItem, [esi+TFreshEdit._pLines], edi + + test [eax+TEditorLine.flags], lfWordWrap + + + + + + mov edx, [.xPixel] + mov eax, [.yPixel] + clc + return + +.pixel_outside: + xor eax, eax + dec eax + clc + return + +;......................................................................................... +; method .CaretToPixel, .iRow, .xChar +.caret_to_pixel: + + + + + endp ;_________________________________________________________________________________________ @@ -1858,11 +1617,11 @@ proc TFreshEdit.SysEventHandler, .pobj, .pEvent .changes dd ? begin - push eax ebx ecx edx esi edi + push eax ebx edx esi edi mov [.changes], 0 mov ebx, [.pEvent] mov esi, [.pobj] @@ -1893,15 +1652,14 @@ je .mousebtnrelease cmp [ebx+TSysEvent.event], seMouseMove je .mousemove - .continue: stc .finish: - pop edi esi edx ecx ebx eax + pop edi esi edx ebx eax return ;......................................................................................... .mousemove: mov ecx, mcText @@ -1913,12 +1671,16 @@ mov [esi+TFreshEdit._cursor], ecx cmp [esi+TFreshEdit._DragButton], mbLeft jne .continue - stdcall TFreshEdit.__MoveCaretToPixel, esi, [ebx+TMouseMoveEvent.x], [ebx+TMouseMoveEvent.y] + stdcall TFreshEdit.__PixelToCaretPos, esi, [ebx+TMouseMoveEvent.x], [ebx+TMouseMoveEvent.y] jc .continue + + mov [esi+TFreshEdit._yCaret], eax + mov [esi+TFreshEdit._xCaret], edx + jmp .refresh ;......................................................................................... .mousebtnrelease: mov eax, [ebx+TMouseButtonEvent.Button] @@ -1958,84 +1720,87 @@ mov [esi+TFreshEdit._DragButton], eax cmp [ebx+TMouseButtonEvent.Button], mbLeft jne .continue - stdcall TFreshEdit.__MoveCaretToPixel, esi, [ebx+TMouseButtonEvent.x], [ebx+TMouseButtonEvent.y] + stdcall TFreshEdit.__PixelToCaretPos, esi, [ebx+TMouseButtonEvent.x], [ebx+TMouseButtonEvent.y] jc .continue + + mov [esi+TFreshEdit._yCaret], eax + mov [esi+TFreshEdit._xCaret], edx jmp .refresh .left_margin_process: - sub edx, 16 - cmp ecx, edx - jl .continue ; number or breakpoint click - -; Fold/unfold click -; check for the fold/unfold icon under the cursor - xor edx, edx - div [esi+TFreshEdit._fontheight] - add eax, [esi+TFreshEdit._TopLine] - - mov edx, [esi+TFreshEdit._pIndex] - cmp eax, [edx+TArray.count] - jae .continue - - mov ecx, [edx+TArray.array+4*eax] - cmp ecx, -1 - je .continue ; it is not fold icon row. - - shl ecx, TEditorLine.shift - add ecx, [esi+TFreshEdit._pLines] - add ecx, TArray.array ; pointer to TEditorLine - - test [ecx+TEditorLine.flags], lfFoldHeader - jz .continue - -; determine what is the current state folded or expanded -locals - .current dd ? - .next dd ? -endl - mov [.current], eax ; current line index - mov ecx, [edx+TArray.array+4*eax] - inc ecx - -.next_loop: - inc eax - cmp eax, [edx+TArray.count] - jae .folded - - cmp [edx+TArray.array+4*eax], -1 - je .next_loop - - mov [.next], eax - cmp ecx, [edx+TArray.array+4*eax] ; the next index == current+1 -> expanded - jne .folded - -; so, fold it... - stdcall TFreshEdit.__FoldZoneLen, esi, [.current] - - mov ecx, [.next] - sub ecx, [.current] - inc ecx - - cmp eax, ecx - jbe .continue ; nothing to fold - - sub eax, ecx - stdcall DeleteArrayItems, [esi+TFreshEdit._pIndex], [.next], eax - mov [esi+TFreshEdit._pIndex], edx - - stdcall TFreshEdit.__UpdateScrollBars, esi - or [.changes], chgfNeedRefresh - jmp .refresh - -.folded: -; the zone is folded, so restore the index items. - stdcall TFreshEdit.__RestoreIndex, esi, [.current], [.next] - stdcall TFreshEdit.__UpdateScrollBars, esi - or [.changes], chgfNeedRefresh +; sub edx, 16 +; cmp ecx, edx +; jl .continue ; number or breakpoint click +; +;; Fold/unfold click +;; check for the fold/unfold icon under the cursor +; xor edx, edx +; div [esi+TFreshEdit._fontheight] +; add eax, [esi+TFreshEdit._TopLine] +; +; mov edx, [esi+TFreshEdit._pIndex] +; cmp eax, [edx+TArray.count] +; jae .continue +; +; mov ecx, [edx+TArray.array+4*eax] +; cmp ecx, -1 +; je .continue ; it is not fold icon row. +; +; shl ecx, TEditorLine.shift +; add ecx, [esi+TFreshEdit._pLines] +; add ecx, TArray.array ; pointer to TEditorLine +; +; test [ecx+TEditorLine.flags], lfFoldHeader +; jz .continue +; +;; determine what is the current state folded or expanded +;locals +; .current dd ? +; .next dd ? +;endl +; mov [.current], eax ; current line index +; mov ecx, [edx+TArray.array+4*eax] +; inc ecx +; +;.next_loop: +; inc eax +; cmp eax, [edx+TArray.count] +; jae .folded +; +; cmp [edx+TArray.array+4*eax], -1 +; je .next_loop +; +; mov [.next], eax +; cmp ecx, [edx+TArray.array+4*eax] ; the next index == current+1 -> expanded +; jne .folded +; +;; so, fold it... +; stdcall TFreshEdit.__FoldZoneLen, esi, [.current] +; +; mov ecx, [.next] +; sub ecx, [.current] +; inc ecx +; +; cmp eax, ecx +; jbe .continue ; nothing to fold +; +; sub eax, ecx +; stdcall DeleteArrayItems, [esi+TFreshEdit._pIndex], [.next], eax +; mov [esi+TFreshEdit._pIndex], edx +; +; stdcall TFreshEdit.__UpdateScrollBars, esi +; or [.changes], chgfNeedRefresh +; jmp .refresh +; +;.folded: +;; the zone is folded, so restore the index items. +; stdcall TFreshEdit.__RestoreIndex, esi, [.current], [.next] +; stdcall TFreshEdit.__UpdateScrollBars, esi +; or [.changes], chgfNeedRefresh jmp .refresh ;......................................................................................... .scroll: cmp [ebx+TScrollEvent.ScrollBar], scrollX @@ -2123,25 +1888,32 @@ endl cmp [esi+TFreshEdit._fReadOnly], froReadWrite jne .refresh execute esi, TFreshEdit.DeleteSel - test eax, eax - js @f - mov [esi+TFreshEdit._yCaret], eax - mov [esi+TFreshEdit._xCaret], edx -@@: - execute esi, TFreshEdit.InsertChar, [ebx+TKeyboardEvent.key] - mov [.byte_offs], eax - - execute esi, TFreshEdit.FormatLine, [esi+TFreshEdit._yCaret] - add [.byte_offs], eax - - stdcall TFreshEdit.__PointerToPos, esi, [esi+TFreshEdit._yCaret], [.byte_offs] - - mov [esi+TFreshEdit._yCaret], eax - mov [esi+TFreshEdit._xCaret], edx + mov [esi+TFreshEdit._yCaret], eax + mov [esi+TFreshEdit._xCaret], edx + + stdcall StrNew + push eax + + stdcall StrCharCat, eax, [ebx+TKeyboardEvent.key] + + execute esi, TFreshEdit.InsertString, eax + + stdcall StrDel ; from the stack + + mov [.byte_offs], 0 + +; is it necessary??? +; execute esi, TFreshEdit.FormatLine, [esi+TFreshEdit._yCaret] +; add [.byte_offs], eax +; +; stdcall GetArrayItem, [esi+TFreshEdit._pLines], [esi+TFreshEdit._yCaret] +; +; stdcall StrCharUtf8, [eax+TEditorLine.Data], [.byte_offs] +; mov [esi+TFreshEdit._xCaret], eax stdcall TFreshEdit.__UpdateScrollBars, esi stdcall TFreshEdit.__FitCaretInWindow, esi or [.changes], chgfNeedRefresh @@ -2257,11 +2029,10 @@ mov eax, [esi+TFreshEdit._rows] dec eax mov ecx, mvcMoveY or mvcScrollY jmp .moveit - .moveit: test [ebx+TKeyboardEvent.kbdStatus], maskScrLk jnz .scroll_override cmp [esi+TFreshEdit._fReadOnly], froReadOnlyNoCaret @@ -2294,25 +2065,29 @@ jmp .refresh ;. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .handler_pgbeg: + execute esi, TFreshEdit.ScreenBegin jmp .refresh ;. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .handler_pgend: + execute esi, TFreshEdit.ScreenEnd jmp .refresh ;. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .handler_txtbeg: + execute esi, TFreshEdit.FileBegin jmp .refresh ;. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .handler_txtend: + execute esi, TFreshEdit.FileEnd jmp .refresh ;. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .handler_wordleft: @@ -2329,53 +2104,56 @@ .byte_offs2 dd ? endl cmp [esi+TFreshEdit._fReadOnly], froReadWrite jne .refresh - execute esi, TFreshEdit.DeleteSel - test eax, eax - jns .deleted + mov eax, [esi+TFreshEdit._yCaret] + mov ecx, [esi+TFreshEdit._xCaret] + cmp eax, [esi+TFreshEdit._ySelection] + jne .havesel + cmp ecx, [esi+TFreshEdit._xSelection] + jne .havesel execute esi, TFreshEdit.DelChar - mov [.byte_offs2], eax - execute esi, TFreshEdit.FormatLine, [esi+TFreshEdit._yCaret] - stdcall TFreshEdit.__PointerToPos, esi, edx, [.byte_offs2] + jmp .end_del -.deleted: +.havesel: + execute esi, TFreshEdit.DeleteSel mov [esi+TFreshEdit._yCaret], eax mov [esi+TFreshEdit._xCaret], edx +.end_del: stdcall TFreshEdit.__FitCaretInWindow, esi stdcall TFreshEdit.__UpdateScrollBars, esi or [.changes], chgfNeedRefresh jmp .refresh ;. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . -; BUG: it does not works as expected, but I don't have anough patience to fix it just now..... +; BUG: it does not works as expected, but I don't have enough patience to fix it just now..... .handler_backspc: cmp [esi+TFreshEdit._fReadOnly], froReadWrite jne .refresh - push [esi+TFreshEdit._xCaret] [esi+TFreshEdit._yCaret] - execute esi, TFreshEdit.Move, mvcMoveX, -1, FALSE - pop edx eax - - cmp eax, [esi+TFreshEdit._xCaret] - jne .do_del - cmp edx, [esi+TFreshEdit._yCaret] - je .refresh - -.do_del: - stdcall TFreshEdit.__PosToPointer, esi, [esi+TFreshEdit._xCaret], [esi+TFreshEdit._yCaret] - test ecx, ecx - jnz .refresh - - stdcall StrLen, [edx+TEditorLine.Data] - cmp ecx, eax - jae .refresh - - jmp .handler_delete + mov edx, [esi+TFreshEdit._yCaret] + mov ecx, [esi+TFreshEdit._xCaret] + + dec ecx + jns .posok + + dec edx + stdcall GetArrayItem, [esi+TFreshEdit._pLines], edx + jc .refresh + + stdcall StrLenUtf8, [eax+TEditorLine.Data], -1 + mov ecx, eax + +.posok: + execute esi, TFreshEdit.DeleteText, edx, ecx, [esi+TFreshEdit._yCaret], [esi+TFreshEdit._xCaret] + mov [esi+TFreshEdit._yCaret], eax + mov [esi+TFreshEdit._xCaret], edx + jmp .end_del + ;. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .handler_linedel: cmp [esi+TFreshEdit._fReadOnly], froReadWrite jne .refresh @@ -2396,11 +2174,10 @@ stdcall Get, esi, TFreshEdit.CurrentLine jc .refresh xor [eax+TEditorLine.flags], lfWordWrap - execute esi, TFreshEdit.FormatLine, [esi+TFreshEdit._yCaret] stdcall TFreshEdit.__UpdateScrollBars, esi or [.changes], chgfNeedRefresh jmp .refresh ;. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . @@ -2485,13 +2262,13 @@ .scrollerok: mov eax, [esi+TFreshEdit._xCaret] mov ecx, [esi+TFreshEdit._yCaret] mov edx, [esi+TFreshEdit._InsMode] - cmp eax, [esi+TFreshEdit._prevxCaret] + cmp eax, [esi+TFreshEdit._prevCaretChar] jne .caretmoved - cmp ecx, [esi+TFreshEdit._prevyCaret] + cmp ecx, [esi+TFreshEdit._prevCaretLine] jne .caretmoved cmp edx, [esi+TFreshEdit._prevInsMode] je .caretposok .caretmoved: @@ -2522,12 +2299,12 @@ mov [esi+TFreshEdit._prevLeftColumn], ecx mov eax, [esi+TFreshEdit._xCaret] mov ecx, [esi+TFreshEdit._yCaret] mov edx, [esi+TFreshEdit._InsMode] - mov [esi+TFreshEdit._prevxCaret], eax - mov [esi+TFreshEdit._prevyCaret], ecx + mov [esi+TFreshEdit._prevCaretChar], eax + mov [esi+TFreshEdit._prevCaretLine], ecx mov [esi+TFreshEdit._prevInsMode], edx mov eax, [esi+TFreshEdit._xSelection] mov ecx, [esi+TFreshEdit._ySelection] sub eax, [esi+TFreshEdit._xCaret] @@ -2549,20 +2326,37 @@ jz .continue clc jmp .finish ;......................................................................................... +uglobal + Prevtime dd ? +endg .paint: + + if defined options.DebugMode and options.DebugMode + stdcall GetTimestamp + xchg eax, [Prevtime] + sub eax, [Prevtime] + neg eax + OutputRegister regEAX, 10 + end if + cmp [esi+TFreshEdit._fShadowValid], 0 jne @f stdcall TFreshEdit.__DrawShadow, esi @@: stdcall SetClipRectangle, [ebx+TPaintEvent.context], 0 stdcall TScrollWindow.SysEventHandler, [.pobj], [.pEvent] stdcall DrawBackBuffer, [ebx+TPaintEvent.context], [esi+TFreshEdit._pShadow], 0, 0 +; debug mode of autoscroll with maximal speed. +; execute esi, TFreshEdit.Move, mvcMoveY or mvcScrollY, 2, TRUE +; execute esi, TFreshEdit.Refresh +; stdcall TFreshEdit.__UpdateScrollBars, esi + clc jmp .finish ;......................................................................................... @@ -2598,80 +2392,10 @@ endp ;_________________________________________________________________________________________ - - - -proc TFreshEdit.__MoveCaretToPixel, .editor, .x, .y -begin - push ecx edx esi - - xor ecx, ecx - mov esi, [.editor] - -; x - mov eax, [.y] - mov edx, [esi+TFreshEdit._FreeArea.y] - cmp eax, edx - jl .nomove - - add edx, [esi+TFreshEdit._FreeArea.height] - cmp eax, edx - jge .nomove - - mov eax, [.x] - mov edx, [esi+TFreshEdit._FreeArea.x] - cmp eax, edx - jl .nomove - - add edx, [esi+TFreshEdit._FreeArea.width] - cmp eax, edx - jge .nomove - - sub eax, [esi+TFreshEdit.__LeftMargin] - jge @f - xor eax, eax -@@: - cdq - idiv [esi+TFreshEdit._fontwidth] - add eax, [esi+TFreshEdit._LeftColumn] - - cmp [esi+TFreshEdit._xCaret], eax - je @f - - test eax, eax - js @f - - mov [esi+TFreshEdit._xCaret], eax -@@: -; y - mov eax, [.y] - cdq - idiv [esi+TFreshEdit._fontheight] - add eax, [esi+TFreshEdit._TopLine] - - cmp [esi+TFreshEdit._yCaret], eax - je @f - - test eax, eax - js @f - mov [esi+TFreshEdit._yCaret], eax -@@: - mov eax, ecx - clc - -.finish: - pop esi edx ecx - return - -.nomove: - stc - jmp .finish -endp - proc TFreshEdit.__DrawShadow, .editor .context dd ? @@ -2745,62 +2469,39 @@ stdcall SetSimpleLine, [.context], [FreshEditTheme.clWrapColumn] stdcall DrawLine, [.context], eax, 0, eax, [edi+TBackBuffer.height] .wrapok: -; ebx is pointer to the index array. - mov ebx, [esi+TFreshEdit._pIndex] - -; edx is the number of the line in [pIndex] + mov ebx, [esi+TFreshEdit._pLines] mov edx, [esi+TFreshEdit._TopLine] - -; ecx is the y coordinate of the line. - mov ecx, [esi+TFreshEdit._fontheight] - sub ecx, [esi+TFreshEdit._fontdescent] -; sub ecx, 3 ; this is not good. - -; check the first line -.searchbegin: - cmp [ebx+TArray.array+4*edx], -1 - jne .lineloop - - sub ecx, [esi+TFreshEdit._fontheight] - dec edx - jnz .searchbegin + xor ecx, ecx ; so draw the lines. .lineloop: - mov eax, ecx - sub eax, [esi+TFreshEdit._fontheight] - add eax, [esi+TFreshEdit._fontdescent] - cmp eax, [edi+TBackBuffer.height] + cmp ecx, [edi+TBackBuffer.height] jge .endlines cmp edx, [ebx+TArray.count] jae .endlines ; call the TFreshEditLineType.procDraw for the current line type. stdcall TFreshEdit.__DrawLine, esi, [.context], edx, ecx add ecx, [esi+TFreshEdit._fontheight] - inc edx jmp .lineloop .endlines: ; fix the left line border to the end of the windows. - add ecx, [esi+TFreshEdit._fontdescent] mov eax, [esi+TFreshEdit.__LeftMargin] - sub ecx, [esi+TFreshEdit._fontheight] sub eax, 2 stdcall SetSimpleLine, [.context], [FreshEditTheme.clLeftMarginBorder] stdcall DrawLine, [.context], eax, ecx, eax, [edi+TBackBuffer.height] stdcall SetSimpleLine, [.context], [FreshEditTheme.clLeftMargin] dec eax stdcall DrawLine, [.context], eax, ecx, eax, [edi+TBackBuffer.height] dec eax stdcall DrawLine, [.context], eax, ecx, eax, [edi+TBackBuffer.height] - stdcall ReleaseContext, [.context] .finish: mov [esi+TFreshEdit._fShadowValid], 1 @@ -2807,160 +2508,48 @@ popad return endp +; y is the coordinate of the top of the line! +; returns the height of the line in characters. +; if the line is not drawn (because is hidden) returns 0 -proc TFreshEdit.__DrawLine, .editor, .context, .indexLine, .y - .line dd ? - .last_line dd ? +proc TFreshEdit.__DrawLine, .editor, .context, .iLine, .y .attr dd ? .ysel0 dd ? .xsel0 dd ? .ysel1 dd ? .xsel1 dd ? - - .unfold dd ? - - .next dd ? - .markh dd ? - - .linenumber dd ? - - .fold_icon dd ? - .fold_line dd ? - begin pushad - mov edi, [.editor] - - mov [.line], -1 - mov [.unfold], 0 - - mov eax, [.indexLine] - lea ecx, [eax+1] - mov edx, [edi+TFreshEdit._pIndex] - -.nextloop: - cmp ecx, [edx+TArray.count] - jae .unfoldok - cmp [edx+TArray.array+4*ecx], -1 - jne @f - inc ecx - jmp .nextloop -@@: - push ecx - mov ecx, [edx+TArray.array+4*ecx] - dec ecx - cmp ecx, [edx+TArray.array+4*eax] - pop ecx - je .unfoldok - - mov [.unfold], 1 - -.unfoldok: - mov [.next], ecx - -; if the line is part of the word-wrapped line, don't draw the text, because it is already OK. - mov edx, [edx+TArray.array+4*eax] ; index in pLines - mov [.linenumber], edx - inc [.linenumber] ; count it from 1 - cmp edx, -1 - je .end_draw_text ; wrapped line. - - mov eax, [edi+TFreshEdit._pLines] - mov [.last_line], 0 - mov eax, [eax+TArray.count] - dec eax - cmp eax, edx - jne @f - inc [.last_line] ; flag that this line is the last line. -@@: - shl edx, TEditorLine.shift - add edx, [edi+TFreshEdit._pLines] - add edx, TArray.array - mov [.line], edx ; pointer to TEditorLines - -; draw the text of the line -;. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . - stdcall StrLen, [edx+TEditorLine.Data] - test eax, eax - jz .empty_string - - mov ecx, eax - shl eax, 4 ; sizeof.TCharAttr = 16 - - stdcall GetMem, eax ; attr array. - mov [.attr], eax - mov esi, eax - - mov ebx, [FreshEditTheme.clSimpleText] - test [edx+TEditorLine.flags], lfProtected - jz @f - mov ebx, [FreshEditTheme.clProtectedText] -@@: - mov edx, [edi+TFreshEdit._Font] - -; fill the attribute array with the default values. -.attrloop: - mov [esi+TCharAttr.color], ebx - mov [esi+TCharAttr.font], edx - lea esi, [esi+sizeof.TCharAttr] - loop .attrloop - - mov edx, [.line] - test [edx+TEditorLine.flags], lfProtected - jnz .syntaxok - -; Call the syntax highlighter if any: - xor ecx, ecx - cmp [.indexLine], ecx - je @f - mov ecx, [edx-sizeof.TEditorLine+TEditorLine.syn_context] -@@: - cmp [edi+TFreshEdit._procSyntax], 0 - je .syntaxok - - push edi edx - stdcall [edi+TFreshEdit._procSyntax], [edx+TEditorLine.Data], [.attr], ecx - pop edx edi - mov [edx+TEditorLine.syn_context], eax - -.syntaxok: - stdcall StrPtr, [edx+TEditorLine.Data] - cmp byte [eax], 0 - je .end_draw_text - - stdcall DrawColoredString, [.context], eax, [.attr], [eax+string.len], [edi+TFreshEdit.__LeftMargin], \ - [.y], [edi+TFreshEdit._LeftColumn], [edi+TFreshEdit._fontwidth], [edi+TFreshEdit._fontheight] - - stdcall FreeMem, [.attr] - -.end_draw_text: - -; draw left margin graphics: - stdcall TFreshEdit.__DrawLeftMargin, edi, [.context], [.indexLine] + mov esi, [.editor] + + mov eax, [.iLine] + mov edi, [esi+TFreshEdit._pLines] + shl eax, TEditorLine.shift + lea edi, [edi+TArray.array+eax] ; now draw transparent selection ; selection bounds. - mov eax, [edi+TFreshEdit._xSelection] - mov ecx, [edi+TFreshEdit._ySelection] - mov ebx, [edi+TFreshEdit._xCaret] - mov edx, [edi+TFreshEdit._yCaret] + mov eax, [esi+TFreshEdit._xSelection] + mov ecx, [esi+TFreshEdit._ySelection] + mov ebx, [esi+TFreshEdit._xCaret] + mov edx, [esi+TFreshEdit._yCaret] cmp ecx, edx jl @f je .sortx xchg ecx, edx - cmp [edi+TFreshEdit._SelMode], selmChar + cmp [esi+TFreshEdit._SelMode], selmChar jne @f xchg eax, ebx @@: - cmp [edi+TFreshEdit._SelMode], selmChar + cmp [esi+TFreshEdit._SelMode], selmChar je .endsort .sortx: cmp eax, ebx jle @f @@ -2971,122 +2560,177 @@ mov [.xsel0], eax mov [.ysel0], ecx mov [.xsel1], ebx mov [.ysel1], edx - mov eax, [.indexLine] + mov eax, [.iLine] cmp eax, [.ysel0] jl .end_sel cmp eax, [.ysel1] jg .end_sel - mov eax, [edi+TFreshEdit._SelMode] + mov eax, [esi+TFreshEdit._SelMode] cmp eax, selmChar je .selchar ; sel block mov eax, [.xsel0] cmp eax, [.xsel1] je .end_sel - sub eax, [edi+TFreshEdit._LeftColumn] + sub eax, [esi+TFreshEdit._LeftColumn] jge @f xor eax, eax @@: - imul eax, [edi+TFreshEdit._fontwidth] - add eax, [edi+TFreshEdit.__LeftMargin] + imul eax, [esi+TFreshEdit._fontwidth] + add eax, [esi+TFreshEdit.__LeftMargin] mov ecx, [.xsel1] - sub ecx, [edi+TFreshEdit._LeftColumn] + sub ecx, [esi+TFreshEdit._LeftColumn] jge @f xor ecx, ecx @@: - imul ecx, [edi+TFreshEdit._fontwidth] - add ecx, [edi+TFreshEdit.__LeftMargin] + imul ecx, [esi+TFreshEdit._fontwidth] + add ecx, [esi+TFreshEdit.__LeftMargin] sub ecx, eax jmp .drawsel .selchar: xor eax, eax - mov edx, [.indexLine] + mov edx, [.iLine] cmp edx, [.ysel0] jne .firstok mov eax, [.xsel0] - sub eax, [edi+TFreshEdit._LeftColumn] + sub eax, [esi+TFreshEdit._LeftColumn] jge .firstok xor eax, eax .firstok: - imul eax, [edi+TFreshEdit._fontwidth] - add eax, [edi+TFreshEdit.__LeftMargin] + imul eax, [esi+TFreshEdit._fontwidth] + add eax, [esi+TFreshEdit.__LeftMargin] - mov ecx, [edi+TFreshEdit._cols] ; selection is to the end of the line, for the intermediate lines. + mov ecx, [esi+TFreshEdit._cols] ; selection is to the end of the line, for the intermediate lines. inc ecx cmp edx, [.ysel1] jne .lastok mov ecx, [.xsel1] - sub ecx, [edi+TFreshEdit._LeftColumn] + sub ecx, [esi+TFreshEdit._LeftColumn] test ecx, ecx jns .lastok xor ecx, ecx .lastok: - imul ecx, [edi+TFreshEdit._fontwidth] - add ecx, [edi+TFreshEdit.__LeftMargin] + imul ecx, [esi+TFreshEdit._fontwidth] + add ecx, [esi+TFreshEdit.__LeftMargin] sub ecx, eax .drawsel: mov edx, [.y] - sub edx, [edi+TFreshEdit._fontheight] - add edx, 3 +; sub edx, [esi+TFreshEdit._fontheight] +; add edx, 3 - stdcall SetDrawMode, [.context], [FreshEditTheme.clSelMode] - stdcall DrawFillRect, [.context], eax, edx, ecx, [edi+TFreshEdit._fontheight], [FreshEditTheme.clSelBack] +; stdcall SetDrawMode, [.context], [FreshEditTheme.clSelMode] stdcall SetDrawMode, [.context], cmCopy + stdcall DrawFillRect, [.context], eax, edx, ecx, [esi+TFreshEdit._fontheight], [FreshEditTheme.clSelBack] .end_sel: + mov eax, [.iLine] + mov edi, [esi+TFreshEdit._pLines] + shl eax, TEditorLine.shift + lea edi, [edi+TArray.array+eax] + +; draw the text of the line + +; allocate memory for the color data. + stdcall StrLen, [edi+TEditorLine.Data] + test eax, eax + jz .end_draw_text + + mov ecx, eax + shl eax, 4 ; sizeof.TCharAttr = 16 + + stdcall GetMem, eax ; attr array. + mov [.attr], eax + mov edx, eax + + mov ebx, [FreshEditTheme.clSimpleText] + test [edi+TEditorLine.flags], lfProtected + jz @f + mov ebx, [FreshEditTheme.clProtectedText] +@@: + mov eax, [esi+TFreshEdit._Font] + +; fill the attribute array with the default values. +.attrloop: + mov [edx+TCharAttr.color], ebx + mov [edx+TCharAttr.font], eax + lea edx, [edx+sizeof.TCharAttr] + loop .attrloop + +.attrok: +; Call the syntax highlighter if any: + cmp [esi+TFreshEdit._procSyntax], 0 + je .syntaxok + +; get the syntax context of the previous line: + xor ecx, ecx + cmp [.iLine], ecx + je .prev_ok ; there is no previous line + + lea edx, [edi-sizeof.TEditorLine] + + mov ecx, [edx+TEditorLine.syn_context] + or ecx, ttNewLine + +; ecx contains the syntax context: +.prev_ok: + stdcall [esi+TFreshEdit._procSyntax], [edi+TEditorLine.Data], [.attr], ecx + mov [edi+TEditorLine.syn_context], eax + +.syntaxok: + stdcall StrPtr, [edi+TEditorLine.Data] + mov ecx, [.y] + add ecx, [esi+TFreshEdit._fontheight] + sub ecx, [esi+TFreshEdit._fontdescent] + stdcall DrawColoredString, [.context], eax, [.attr], [eax+string.len], [esi+TFreshEdit.__LeftMargin], \ + ecx, [esi+TFreshEdit._LeftColumn], [esi+TFreshEdit._fontwidth], [esi+TFreshEdit._fontheight] + + stdcall FreeMem, [.attr] + +.end_draw_text: + + stdcall TFreshEdit.__DrawLeftMargin, esi, [.context], edi, [.y] + + + +.finish_draw_line: popad return - -.empty_string: - mov eax, [.indexLine] - mov ecx, [FreshEditTheme.clBackground] - cmp eax, [.ysel0] - jb .setback - cmp eax, [.ysel1] - jae .setback - - mov ecx, [FreshEditTheme.clSelBack] - -.setback: - jmp .end_draw_text - endp -proc TFreshEdit.__DrawLeftMargin, .editor, .context, .indexLine +proc TFreshEdit.__DrawLeftMargin, .editor, .context, .pLine, .y .x dd ? -.y dd ? .width dd ? .height dd ? + +.maxptr dd ? .ytext dd ? .yicons dd ? .unfold dd ? ; is the line folded? -.indexNext dd ? ; the index of the next line in TFreshEdit._pIndex - -.ipLines dd ? ; the index of the current line in pLines array. -.ptrLine dd ? ; pointer of the current TEditorLine. +.pNext dd ? ; pointer to the next line. +.pPrev dd ? ; pointer to the previous line. .fold_icon dd ? .fold_line dd ? begin @@ -3097,66 +2741,42 @@ test [FreshEditTheme.Options], eoLeftMargin jz .finish stdcall SetDrawMode, [.context], cmCopy -; search for the next line index; - mov ecx, [.indexLine] - mov edx, [esi+TFreshEdit._pIndex] - cmp [edx+TArray.array+4*ecx], -1 - je .finish + mov edx, [esi+TFreshEdit._pLines] + mov ecx, [edx+TArray.count] + shl ecx, TEditorLine.shift + lea ecx, [edx+TArray.array+ecx] + mov [.maxptr], ecx + + mov ecx, [.pLine] + sub ecx, sizeof.TEditorLine + cmp ecx, [esi+TFreshEdit._pLines] + ja @f + xor ecx, ecx +@@: + mov [.pPrev], ecx + + mov ecx, [.pLine] + add ecx, sizeof.TEditorLine + mov [.pNext], ecx mov [.unfold], 0 - - xor eax, eax - dec eax - -.nextloop: - inc ecx - cmp ecx, [edx+TArray.count] - jae .found_next - - cmp [edx+TArray.array+4*ecx], eax - je .nextloop - -.found_next: - mov [.indexNext], ecx - - mov eax, [.indexLine] - mov eax, [edx+TArray.array+4*eax] ; current line - index in pLines - mov [.ipLines], eax - - cmp ecx, [edx+TArray.count] - jae .unfoldok - - mov ecx, [edx+TArray.array+4*ecx] ; next line index in pLines - dec ecx - cmp ecx, eax - setne byte [.unfold] - -.unfoldok: - mov edx, eax - shl edx, TEditorLine.shift - add edx, TArray.array - add edx, [esi+TFreshEdit._pLines] - mov [.ptrLine], edx + mov edx, [.pLine] ; determine the bounds of the drawing - mov ecx, [.indexNext] - sub ecx, [.indexLine] + mov eax, [esi+TFreshEdit.__LeftMargin] - imul ecx, [esi+TFreshEdit._fontheight] + mov ecx, [esi+TFreshEdit._fontheight] + mov [.width], eax mov [.height], ecx xor eax, eax mov [.x], eax - - mov eax, [.indexLine] - sub eax, [esi+TFreshEdit._TopLine] - imul eax, [esi+TFreshEdit._fontheight] - mov [.y], eax ; it can be negative for the word wrapped lines, partially displayed. + mov eax, [.y] add eax, [esi+TFreshEdit._fontheight] sub eax, [esi+TFreshEdit._fontdescent] mov [.ytext], eax @@ -3166,10 +2786,11 @@ sar eax, 1 adc eax, [.y] mov [.yicons], eax ; draw the bookmark background. + test [edx+TEditorLine.flags], lfBookmark jz .bookmarkok mov eax, [.width] sub eax, 4 stdcall DrawFillRect, [.context], [.x], [.y], eax, [.height], [FreshEditTheme.clBookmarkBack] @@ -3201,20 +2822,24 @@ jmp .borderok .wrap_border: dec ecx - push ecx eax [.y] eax [.context] ; vertical - push [.y] eax [.y] eax [.context] ; upper edge + push ecx eax [.y] eax [.context] ; vertical ye x ys x + push [.y] eax [.y] eax [.context] ; upper edge ys push ecx eax ecx eax [.context] ; down edge +; down edge + mov ebx, [.pNext] + sub dword [esp+4], 2 sub dword [esp+12], 2 sub dword [esp+16], 2 stdcall DrawLine - sub dword [esp+12], 2 + sub dword [esp+4], 2 add dword [esp+16], 2 + sub dword [esp+12], 2 stdcall DrawLine sub dword [esp+4], 2 add dword [esp+8], 2 sub dword [esp+12], 2 @@ -3226,59 +2851,63 @@ jz @f mov ebx, [FreshEditTheme.clBookmarkBack] @@: stdcall SetSimpleLine, [.context], ebx - push [.y] eax [.y] eax [.context] ; upper edge - push [.y] eax [.y] eax [.context] ; upper edge - push ecx eax ecx eax [.context] ; down corner pixels - push ecx eax ecx eax [.context] ; down corner pixels + mov ebx, [.pNext] + + push ecx eax ecx eax [.context] ; down edge + push ecx eax ecx eax [.context] ; down edge sub dword [esp+4], 2 stdcall DrawLine sub dword [esp+4], 2 sub dword [esp+8], 1 sub dword [esp+12], 2 stdcall DrawLine + + push [.y] eax [.y] eax [.context] ; upper edge + push [.y] eax [.y] eax [.context] ; upper edge sub dword [esp+4], 2 stdcall DrawLine sub dword [esp+4], 2 add dword [esp+8], 1 sub dword [esp+12], 2 stdcall DrawLine -.borderok: ; Line number draw +.borderok: test [FreshEditTheme.Options], eoLineNumbers jz .line_numbers_ok - mov ecx, [.ipLines] - test ecx, ecx - jl .line_numbers_ok - + mov ecx, [.pLine] + sub ecx, [esi+TFreshEdit._pLines] + sub ecx, TArray.array + shr ecx, TEditorLine.shift inc ecx + stdcall NumToStr, ecx, ntsDec or ntsUnsigned push eax eax stdcall StrLen, eax mov ecx, eax stdcall StrPtr ; from the stack mov ebx, eax - stdcall GetTextBounds, [.context], eax, ecx, 0 ; [edi+TFreshEdit._Font] + stdcall GetTextBounds, [.context], eax, ecx, 0 sub eax, [esi+TFreshEdit.__NumberMargin] neg eax stdcall DrawString, [.context], ebx, ecx, eax, [.ytext], 0, [FreshEditTheme.clLeftMarginText] stdcall StrDel ; from the stack .line_numbers_ok: ; draw icons in the middle ; icon breakpoint - mov edx, [.ptrLine] + mov edx, [.pLine] test [edx+TEditorLine.flags], lfBreakpoint jnz .draw_breakpoint cmp [edx+TEditorLine.debugdata], 0 je .breakpoint_ok @@ -3302,47 +2931,43 @@ stdcall DrawMaskedImage, [.context], eax, ecx .breakpoint_ok: ; draw fold tree. - - mov edx, [.ptrLine] + mov edx, [.pLine] ; first, determine, what icon should be set for fold/unfold icon: xor ecx, ecx - mov ebx, [esi+TFreshEdit._pIndex] - mov eax, [.indexNext] - cmp eax, [ebx+TArray.count] + mov eax, [.pNext] + cmp eax, [.maxptr] jae @f - mov eax, [ebx+TArray.array+4*eax] ; index in pLines of the next visible line. - shl eax, TEditorLine.shift - mov ecx, [esi+TFreshEdit._pLines] - lea ecx, [ecx+TArray.array+eax] + mov ecx, eax @@: - test [edx+TEditorLine.flags], lfFoldHeader - jnz .fold_fold + cmp [.pPrev], 0 + je .fold_fold + + mov eax, [.pPrev] + mov eax, [edx-sizeof.TEditorLine+TEditorLine.fold_level] + cmp eax, [edx+TEditorLine.fold_level] + jb .fold_fold jecxz .fold_end mov eax, [ecx+TEditorLine.fold_level] cmp eax, [edx+TEditorLine.fold_level] ja .fold_continue jb .fold_end - test [ecx+TEditorLine.flags], lfFoldHeader - jz .fold_continue - .fold_end: xor eax, eax mov ecx, 2 ; 2 means corner up/right jmp .fold_ok .fold_fold: mov ecx, 1 ; 1 means half vertical down mov eax, [esi+TFreshEdit._iconUnfold] - cmp [.unfold], 0 - jne .fold_ok + mov eax, [esi+TFreshEdit._iconFold] jmp .fold_ok .fold_continue: xor eax, eax @@ -3416,11 +3041,10 @@ begin push eax ebx edx mov ebx, [.editor] - mov eax, [ebx+TFreshEdit._fontheight] mov edx, [ebx+TFreshEdit._fontwidth] mov [.offset], 0 @@ -3477,11 +3101,11 @@ push eax ebx ecx edx mov ebx, [.editor] ; V scroller - mov eax, [ebx+TFreshEdit._pIndex] + mov eax, [ebx+TFreshEdit._pLines] mov eax, [eax+TArray.count] sub eax, [ebx+TFreshEdit._rows] mov [ebx+TFreshEdit._VScroller.Max], eax mov eax, [ebx+TFreshEdit._TopLine] @@ -3564,233 +3188,75 @@ test eax, eax pop esi edx ecx ebx return endp -; Converts x,y position in the text to memory parameters -; arguments: -; .x, .y - x and y coordinates of the position. -; returns: -; edx - pointer to the TEditorLine -; eax - byte offset inside the string that corresponds with the given position. -; ecx - count of the spaces that have to be inserted on offset eax in the string -; in order to reach the .x coordinate (when the position is beyond the end of the line) -proc TFreshEdit.__PosToPointer, .editor, .x, .y -.pline dd ? -.start dd ? -begin - push ebx esi edi - - mov edi, [.editor] - mov eax, [.y] - mov ebx, [edi+TFreshEdit._pIndex] - cmp eax, [ebx+TArray.count] - jae .error - - xor ecx, ecx - -.lineloop: - mov edx, [ebx+TArray.array+4*eax] - cmp edx, -1 - jne .found - - inc ecx - dec eax - jns .lineloop - -.error: - stc - jmp .finish - -.crash_error: - int3 - jmp .error - -; ecx is the wrapped line count. -; edx is the number of string in the lines array. -.found: - mov ebx, [edi+TFreshEdit._pLines] - cmp edx, [ebx+TArray.count] - jae .crash_error - - shl edx, TEditorLine.shift - lea eax, [ebx+TArray.array+edx] - - mov [.pline], eax ; handle of the string. - - cmp [.x], -1 - je .only_line - - stdcall StrPtr, [eax+TEditorLine.Data] - mov esi, eax - mov [.start], eax - jecxz .wrapok - -.wraploop: - stdcall DecodeUtf8, dword [esi] - add esi, edx - - test eax, eax - jz .crash_error - - cmp eax, $01 ; line wrap char - jne .wraploop - - dec ecx - jnz .wraploop - -.wrapok: - mov ecx, [.x] - jecxz .endofstring - -.charloop: - stdcall DecodeUtf8, dword [esi] - test eax, eax - jz .endofstring - cmp eax, $01 - je .endofstring - - add esi, edx - dec ecx - jnz .charloop - -.endofstring: - sub esi, [.start] - mov eax, esi - -.only_line: - mov edx, [.pline] - - clc - -.finish: - pop edi esi ebx - return -endp - - -; Converts the pointer parameters to caret coordinate. -; arguments: -; .index - index of the line -; .offset - byte offset inside the string. -; returns: -; eax - y coordinate of the caret -; edx - x coordinate of the caret -; ecx - pointer to the current TEditorLine - -proc TFreshEdit.__PointerToPos, .editor, .index, .offset -.base dd ? -.x dd ? -begin - push esi edi - - mov esi, [.editor] - mov edi, [esi+TFreshEdit._pIndex] - mov ecx, [.index] - -.line_loop: - cmp [edi+TArray.array+4*ecx], -1 - jne .found - dec ecx - jns .line_loop - -.error: - stc - jmp .finish - -.found: - mov [.base], ecx ; base index - mov [.x], 0 - - mov ecx, [edi+TArray.array+4*ecx] ; index in pLines - shl ecx, TEditorLine.shift - add ecx, [esi+TFreshEdit._pLines] - add ecx, TArray.array - - cmp [.offset], 0 - je .ready - - stdcall StrPtr, [ecx+TEditorLine.Data] - mov esi, eax - -.char_loop: - stdcall DecodeUtf8, [esi] - jc .error - add esi, edx - - cmp eax, 1 ; wrap char - jne .no_wrap - - inc [.base] - mov [.x], -1 - -.no_wrap: - inc [.x] - sub [.offset], edx - ja .char_loop - -.ready: - mov eax, [.base] - mov edx, [.x] - clc - -.finish: - pop edi esi - return -endp - - - -; .hString - the string containing the line. -; -; returns: -; eax - the width of the line in chars. -; if the line contains wrapped sublines, -; the maximal length will be returned. - -proc TFreshEdit.__LineWidth, .hString -.maxlen dd ? -begin - push esi ecx edx - - mov [.maxlen], 0 - stdcall StrPtr, [.hString] - mov esi, eax - -.outer: - xor ecx, ecx - -.loop: - stdcall DecodeUtf8, [esi] - jc .error - - add esi, edx - - test eax, eax - jz .endofline - - cmp eax, $01 ; wrap char - je .endofline - - inc ecx - jmp .loop - -.endofline: - cmp ecx, [.maxlen] - jbe .maxok - mov [.maxlen], ecx -.maxok: - test eax, eax - jnz .outer - - mov eax, [.maxlen] - clc - -.error: - pop edx ecx esi - return -endp + + +; Arguments: +; +; Returns: +; CF=0 +; eax - number of the line +; edx - offset inside the line +; CF=1 +; the pixel is outside the client area. +; +proc TFreshEdit.__PixelToCaretPos, .editor, .x, .y +begin + push ebx ecx esi edi + + xor ecx, ecx + mov esi, [.editor] + +; x + mov eax, [.y] + mov edx, [esi+TFreshEdit._FreeArea.y] + cmp eax, edx + jl .nomove + + add edx, [esi+TFreshEdit._FreeArea.height] + cmp eax, edx + jge .nomove + + mov eax, [.x] + mov edx, [esi+TFreshEdit._FreeArea.x] + cmp eax, edx + jl .nomove + + add edx, [esi+TFreshEdit._FreeArea.width] + cmp eax, edx + jge .nomove + + sub eax, [esi+TFreshEdit.__LeftMargin] + jge @f + xor eax, eax +@@: + cdq + idiv [esi+TFreshEdit._fontwidth] + add eax, [esi+TFreshEdit._LeftColumn] + + push eax +; y + mov eax, [.y] + cdq + idiv [esi+TFreshEdit._fontheight] + + add eax, [esi+TFreshEdit._TopLine] + pop edx + clc + +.finish: + pop edi esi ecx ebx + return + +.nomove: + stc + jmp .finish +endp + + proc TFreshEdit.__FixLength, .editor, .newlen, .oldlen @@ -3856,10 +3322,11 @@ pop edi esi edx ecx eax return endp + proc TFreshEdit.__ComputeLeftMargin, .editor begin pushad mov esi, [.editor] @@ -3909,96 +3376,60 @@ begin pushad mov [.result], 0 - mov esi, [.editor] - mov edi, [esi+TFreshEdit._pLines] - mov edx, [esi+TFreshEdit._pIndex] - - mov eax, [.index] - cmp eax, [edx+TArray.count] - jae .finish - - mov ecx, [edx+TArray.array+4*eax] ; index of the first element. - shl ecx, TEditorLine.shift - mov ebx, [edi+TArray.array+ecx+TEditorLine.fold_level] - -.loop: - inc [.result] - inc eax - cmp eax, [edx+TArray.count] - je .finish - - mov ecx, [edx+TArray.array+4*eax] - cmp ecx, -1 - je .loop - - shl ecx, TEditorLine.shift - - cmp [edi+TArray.array+ecx+TEditorLine.fold_level], ebx - jb .finish - ja .loop - - test [edi+TArray.array+ecx+TEditorLine.flags], lfFoldHeader - jz .loop +; mov esi, [.editor] +; mov edi, [esi+TFreshEdit._pLines] +; mov edx, [esi+TFreshEdit._pIndex] +; +; mov eax, [.index] +; cmp eax, [edx+TArray.count] +; jae .finish +; +; mov ecx, [edx+TArray.array+4*eax] ; index of the first element. +; shl ecx, TEditorLine.shift +; mov ebx, [edi+TArray.array+ecx+TEditorLine.fold_level] +; +;.loop: +; inc [.result] +; inc eax +; cmp eax, [edx+TArray.count] +; je .finish +; +; mov ecx, [edx+TArray.array+4*eax] +; cmp ecx, -1 +; je .loop +; +; shl ecx, TEditorLine.shift +; +; cmp [edi+TArray.array+ecx+TEditorLine.fold_level], ebx +; jb .finish +; ja .loop +; +; test [edi+TArray.array+ecx+TEditorLine.flags], lfFoldHeader +; jz .loop .finish: popad mov eax, [.result] return endp -proc TFreshEdit.__RestoreIndex, .editor, .start_index, .end_index -begin - pushad - - mov esi, [.editor] - mov edi, [esi+TFreshEdit._pIndex] - - mov eax, [.start_index] - mov edx, [.end_index] - - mov ebx, [edi+TArray.array+4*edx] - mov ecx, [edi+TArray.array+4*eax] ; index of the first element - sub ebx, ecx - dec ebx - jz .finish - - stdcall InsertArrayItems, [esi+TFreshEdit._pIndex], edx, ebx - mov [esi+TFreshEdit._pIndex], edx - - add [.end_index], ebx - -.fill_loop: - inc ecx - mov [eax], ecx - add eax, 4 - dec ebx - jnz .fill_loop - - mov ecx, [.end_index] - -.format_loop: - execute esi, TFreshEdit.FormatLine, ecx - dec ecx - cmp ecx, [.start_index] - jne .format_loop - -.finish: - popad - return -endp + + + + proc TFreshEdit.__AddFormatLine, .hstring, .format begin test [.format], lfBookmark or lfWordWrap or lfProtected jz .format_ok - stdcall StrCharCat, [.hstring], ';#F:' + stdcall StrCharCat, [.hstring], ';' test [.format], lfBookmark jz @f stdcall StrCharCat, [.hstring], 'b' ; ctrl-B == Bookmark @@: @@ -4008,10 +3439,11 @@ @@: test [.format], lfProtected jz @f stdcall StrCharCat, [.hstring], 'p' ; ctrl-D == Protected @@: + stdcall StrCharCat, [.hstring], ':F#;' stdcall StrCharCat, [.hstring], $0a0d .format_ok: return endp @@ -4021,16 +3453,29 @@ ; returns: ; CF=0 if the line contains format information. ; eax - format flags ; ecx - format line length; ; + +; decodes format line (ending with ':F#;') +; returns: +; CF=0 if the line contains format information. +; eax - format flags +; ecx - format line length; +; proc TFreshEdit.__DecodeFormatLine, .pString begin push ebx esi + + std mov esi, [.pString] + mov ecx, [esi+string.len] + jecxz .not_format + + lea esi, [esi+ecx-1] lodsb cmp al, ';' jne .not_format lodsb @@ -4045,16 +3490,13 @@ xor ebx, ebx .format_loop: lodsb - test al, al - jz .not_format + jecxz .eol - cmp al, $0d - je .eol - cmp al, $0a + cmp al, ';' je .eol cmp al, 'b' jne @f or ebx, lfBookmark @@ -4073,27 +3515,28 @@ .not_format: xor eax, eax pop esi ebx stc + cld return .eol: - mov ah, al - xor ah, $0a xor $0d - lodsb - cmp al, ah - je .format_ok - dec esi - -.format_ok: sub esi, [.pString] mov ecx, esi mov eax, ebx pop esi ebx clc + cld return endp + + + + + + endmodule + ADDED freshlib/FreshEdit/FreshEdit2.asm Index: freshlib/FreshEdit/FreshEdit2.asm ================================================================== --- /dev/null +++ freshlib/FreshEdit/FreshEdit2.asm @@ -0,0 +1,882 @@ + +include "FreshEditThemes.asm" +include "LineProcessors.asm" + + +ObjectClass FreshEdit, \ + ScrollWindow, \ + TFreshEdit.Create, \ + TFreshEdit.Destroy, \ + TFreshEdit.Get, \ + TFreshEdit.Set, \ + TFreshEdit.ExecCmd, \ + TFreshEdit.SysEventHandler + + +; values for ._EditorMode field +femSelBlock = 1 +femOverwrite = 2 + + + +object TFreshEdit, TScrollWindow + +; system font sizes (used for additional texts and line numbers) + ._Font2 dd ? ; Supplementary font. + + ._fontwidth2 dd ? ; in pixels. + ._fontheight2 dd ? ; in pixels. + ._fontdescent2 dd ? ; in pixels. + + +; Shadow object for double buffered paint and other paint related fields. + + ._pShadow dd ? ; pointer to TBackBuffer object. + ._fShadowValid dd ? ; the shadow buffer is valid and should not be repainted. + +; Text related data structures. + + ._pLines dd ? ; TArray of dword pointers to TEditorLine structures. + ._pLengths dd ? ; TArray with count of the lines of given width (in pixels). + ; It is needed for horizontal scrollbar adjustment. + +; when non textual lines are selected, the entire lines should be selected actually. + ._CaretLine dd ? ; index of the line where caret resides. + ._CaretChar dd ? ; char of the line where caret resides. It can be bigger than the line length. + + ._SelLine dd ? ; index of the line where selection starts. + ._SelChar dd ? ; char of the line where selection starts. + + ._WrapX dd ? ; X coordinate (in pixels) where the lines should be word wraped. + + + .__LeftMargin dd ? ; width of the left margin field. + .__NumberMargin dd ? + +; Syntax highlighter + + ._procSyntax dd ? ; procedure for syntax highlighting. + + +; params of TFreshEdit + +; methods of TFreshEdit + +; internal methods + + method .__DrawShadow + method .__ComputeLeftMargin + +; public methods + method .Clear ; clears the text of the editor. + + method .AppendLine, .hText ; appends the line at the end of the text. + method .LoadFromFile, .hFilename + +endobj + + + + +; TEditorLine.flags + +lfBookmark = 1 ; the line have bookmark set. +lfProtected = 2 ; the line can not be edited. +lfWordWrap = 4 ; the line must be word wrapped. +lfBreakpoint = 8 ; set breakpoint in debug mode. + +lfFormatted = $10 + +struct TEditorLine + .pProcessor dd ? ; pointer to TLineProcessor structure, that will process this line. + + .pData dd ? ; internal representation of the line data. + ; Can differs for different types of lines. + ; the canonical content of this field is a handle of string with the text + ; of the line in UTF-8 encoding. All editors must understand this type + ; and to convert back to it. + + .LineY dd ? ; Y coordinate of the line in pixels inside the document. + .LineH dd ? ; Height of the line in pixels. + + .flags dd ? + + .syn_context dd ? + .debug_data dd ? + + .pRenderInfo dd ? ; pointer to some internal rendering info for this line. + ; this array must exists only when the line is inside the + ; visible window. +ends + + + + +;_______________________________________________________________________________________________ + +proc TFreshEdit.Create, .pobj +begin + mov ebx, [.pobj] + + mov [ebx+TFreshEdit._cursor], mcText + mov [ebx+TFreshEdit._WrapX], 640 + + stdcall CreateBackBuffer, [ebx+TFreshEdit.handle], 1, 1 + mov [ebx+TFreshEdit._pShadow], eax + + execute ebx, TFreshEdit.Clear + + + clc + return +endp + + + +;_______________________________________________________________________________________________ + + + +proc TFreshEdit.Destroy, .pobj +begin + mov ebx, [.pobj] + + execute ebx, TFreshEdit.Clear + +; destroy arrays. + stdcall FreeMem, [ebx+TFreshEdit._pLines] + stdcall FreeMem, [ebx+TFreshEdit._pLengths] + +; destroy the shadow buffer. + stdcall DestroyBackBuffer, [ebx+TFreshEdit._pShadow] + + clc + return +endp + + + +;_______________________________________________________________________________________________ + + + +dproc TFreshEdit.Get, .pobj, .paramID +begin + mov ecx, [.pobj] + + dispatch [.paramID] + stc + return +enddp + + + +;_______________________________________________________________________________________________ + + + + +dproc TFreshEdit.Set, .pobj, .paramID, .value +begin + pushad + + mov esi, [.pobj] + mov ebx, [.value] + + dispatch [.paramID] + +.continue: + stc + popad + return + +enddp + + + +;_______________________________________________________________________________________________ + + + +dproc TFreshEdit.ExecCmd, .self, .method +begin + pushad + mov esi, [.self] + + dispatch [.method] + stc + popad + return + +oncase TFreshEdit.LoadFromFile +virtual at ebx + .hFilename dd ? +end virtual + execute esi, TFreshEdit.Clear + + stdcall FileOpen, [.hFilename] + jc .error + + mov edx, eax + +.load_loop: + stdcall FileReadLine, edx + jc .error_close + + test eax, eax + jz .end_of_file + + push eax + execute esi, TFreshEdit.AppendLine, eax + stdcall StrDel ; from the stack. + jmp .load_loop + +.end_of_file: + stdcall FileClose, edx + mov [esi+TFreshEdit._fShadowValid], 0 + + popad + xor eax, eax + clc + return + +.error_close: + stdcall FileClose, edx + mov [esi+TFreshEdit._fShadowValid], 0 + +.error: + mov [esp+4*regEAX], eax + popad + clc + return + +;.............................................................................................. + +oncase TFreshEdit.AppendLine +virtual at ebx + .hText dd ? +end virtual + + stdcall GetMem, sizeof.TEditorLine + mov edi, eax + +; append the line to the text... + stdcall AddArrayItems, [esi+TFreshEdit._pLines], 1 + mov [esi+TFreshEdit._pLines], edx + mov [eax], edi + + mov [edi+TEditorLine.pProcessor], lprTextLine + + stdcall textLineCreate, edi, [.hText] + + xor edx, edx + + mov ebx, [esi+TFreshEdit._pLines] + mov eax, [ebx+TArray.count] + cmp eax, 1 + je .coor_ok + + mov eax, [ebx+TArray.array+4*eax-8] + mov edx, [eax+TEditorLine.LineY] + add edx, [eax+TEditorLine.LineH] + +.coor_ok: + mov [edi+TEditorLine.LineY], edx + mov [edi+TEditorLine.LineH], 16 + + stdcall TFreshEdit.__UpdateScrollbars + + clc + popad + return + +;.............................................................................................. + + +oncase TFreshEdit.Clear + + mov ebx, [esi+TFreshEdit._pLines] + test ebx, ebx + jz .endclr1 + + mov ecx, [ebx+TArray.count] + +.clrloop: + dec ecx + js .endclr + + mov edi, [ebx+TArray.array+4*ecx] + + mov edx, [edi+TEditorLine.pProcessor] + test edx, edx + jz .line_ok + stdcall [edx+TLineProcessor.__Free], edi +.line_ok: + stdcall FreeMem, edi + mov [ebx+TArray.array+4*ecx], 0 + jmp .clrloop + +.endclr: + stdcall FreeMem, ebx + +.endclr1: + mov eax, [esi+TFreshEdit._pLengths] + test eax, eax + jz .all_cleared + stdcall FreeMem, eax + +.all_cleared: + stdcall CreateArray, 4 + mov [esi+TFreshEdit._pLines], eax + + stdcall CreateArray, 4 + mov [esi+TFreshEdit._pLengths], eax + + xor eax, eax + mov [esi+TFreshEdit._fShadowValid], eax + mov [esi+TFreshEdit._CaretLine], eax + mov [esi+TFreshEdit._CaretChar], eax + mov [esi+TFreshEdit._SelLine], eax + mov [esi+TFreshEdit._SelChar], eax + + clc + popad + return + + +;.............................................................................................. + + +oncase TFreshEdit.__ComputeLeftMargin + + xor ebx, ebx + mov [esi+TFreshEdit.__NumberMargin], ebx + + test [FreshEditTheme.Options], eoLeftMargin + jz .marginok + + test [FreshEditTheme.Options], eoLineNumbers + jz .marginok1 + + mov eax, [esi+TFreshEdit._pLines] + mov eax, [eax+TArray.count] + test eax, eax + jz .marginok1 + mov ecx, 10 + +.digits: + add ebx, [esi+TFreshEdit._fontwidth2] + cdq + div ecx + test eax, eax + jnz .digits + + mov [esi+TFreshEdit.__NumberMargin], ebx + +.marginok1: + add ebx, 17+11+3+1 ; 17px breakpoints and other icons; 11px fold tree; 3px word-wrap cut; 1px whitespace at the begining of the line. + +.marginok: + xchg [esi+TFreshEdit.__LeftMargin], ebx + cmp ebx, [esi+TFreshEdit.__LeftMargin] + je .end_clm + + +.end_clm: + clc + popad + return + +;.............................................................................................. + + + +oncase TFreshEdit.__DrawShadow +locals + .context dd ? + .clip TBounds + .line dd ? +endl + execute esi, TFreshEdit.__ComputeLeftMargin + + mov edi, [esi+TFreshEdit._pShadow] + stdcall AllocateContext, [edi+TBackBuffer.raster] + mov [.context], eax + + mov eax, [edi+TBackBuffer.width] + sub eax, [esi+TFreshEdit.__LeftMargin] + mov [.clip.width], eax +; stdcall DrawFillRect, [.context], [esi+TFreshEdit.__LeftMargin], 0, eax, [edi+TBackBuffer.height], [FreshEditTheme.clBackground] + + mov ecx, [esi+TFreshEdit.__LeftMargin] + mov edx, [edi+TBackBuffer.height] + mov [.clip.x], ecx + mov [.clip.height], edx + mov [.clip.y], 0 + + lea eax, [.clip] + stdcall SetClipRectangle, [.context], eax + + mov ebx, [esi+TFreshEdit._pLines] + mov edx, [esi+TFreshEdit._VScroller.Pos] + +; search the first line + + stdcall __SearchLine, ebx, edx + jc .end_draw_lines + +; ecx - index of the line. +; edx - offset inside the line. + neg edx + +.line_loop: + + mov eax, [FreshEditTheme.clBackground] + test [FreshEditTheme.Options], eoStripedBackground + jz .color_ok + test ecx, 1 + jz .color_ok + mov eax, [FreshEditTheme.clAltBack] +.color_ok: + push eax + + mov eax, [ebx+TArray.array+4*ecx] + stdcall DrawFillRect, [.context], 0, edx, [edi+TBackBuffer.width], [eax+TEditorLine.LineH] ; color from the stack + + add [.clip.x], 2 + sub [.clip.width], 2 + lea eax, [.clip] + stdcall SetClipRectangle, [.context], eax + + push edx ; Y + + mov eax, [esi+TFreshEdit._HScroller.Pos] + neg eax + add eax, [esi+TFreshEdit.__LeftMargin] + add eax, 2 + push eax ; X + + mov eax, [ebx+TArray.array+4*ecx] + push eax + + mov [.line], eax + + mov eax, [eax+TEditorLine.pProcessor] + stdcall [eax+TLineProcessor.Draw], [.context] ; remaining parameters from the stack... + + mov eax, [.line] + add edx, [eax+TEditorLine.LineH] ; the Draw procedure can changes the line height + ; that is why the change of the Y coordinate + ; should be after draw call. + + sub [.clip.x], 2 + add [.clip.width], 2 + lea eax, [.clip] + stdcall SetClipRectangle, [.context], eax + + cmp edx, [edi+TBackBuffer.height] + jae .end_draw_lines + + inc ecx + cmp ecx, [ebx+TArray.count] + jb .line_loop + +; clear to the end of the screen... + + mov eax, [edi+TBackBuffer.height] + sub eax, edx + + stdcall DrawFillRect, [.context], 0,edx, [edi+TBackBuffer.width], eax, [FreshEditTheme.clAfterBackground] + +.end_draw_lines: + mov eax, [esi+TFreshEdit._WrapX] + sub eax, [esi+TFreshEdit._HScroller.Pos] + add eax, [esi+TFreshEdit.__LeftMargin] + add eax, 2 + + stdcall SetSimpleLine, [.context], [FreshEditTheme.clWrapColumn] + stdcall DrawLine, [.context], eax, 0, eax, [edi+TBackBuffer.height] + + xor eax, eax + xchg eax, [.clip.x] + test eax, eax + jz .left_ok + + mov [.clip.width], eax + + lea eax, [.clip] + stdcall SetClipRectangle, [.context], eax + + stdcall DrawFillRect, [.context], 0, 0, [esi+TFreshEdit.__LeftMargin], [edi+TBackBuffer.height], [FreshEditTheme.clLeftMargin] + + stdcall SetSimpleLine, [.context], [FreshEditTheme.clLeftMarginBorder] + mov eax, [esi+TFreshEdit.__LeftMargin] + dec eax + stdcall DrawLine, [.context], eax, 0, eax, [edi+TBackBuffer.height] + +.left_ok: + stdcall ReleaseContext, [.context] + + clc + popad + return +enddp + + + +;_______________________________________________________________________________________________ + + + + +dproc TFreshEdit.SysEventHandler, .pobj, .pEvent +begin + pushad + + mov esi, [.pobj] + mov ebx, [.pEvent] + + dispatch [ebx+TSysEvent.event] + +.continue: + stc + popad + return + +;.............................................................................................. + +oncase sePaint + + xor eax, eax + cmp [esi+TFreshEdit._pShadow], eax + je .continue + + cmp [esi+TFreshEdit._fShadowValid], 0 + jne @f + execute esi, TFreshEdit.__DrawShadow +@@: + stdcall SetClipRectangle, [ebx+TPaintEvent.context], 0 + + stdcall TScrollWindow.SysEventHandler, esi, [.pEvent] + + stdcall DrawBackBuffer, [ebx+TPaintEvent.context], [esi+TFreshEdit._pShadow], 0, 0 + clc + popad + return + +;.............................................................................................. + +oncase seScroll + cmp [ebx+TScrollEvent.ScrollBar], scrollX + je .xscroll + +; yscroll + xor edx, edx + mov ecx, [ebx+TScrollEvent.Value] + cmp [ebx+TScrollEvent.ScrollCmd], scTrack + je .track + + cmp [ebx+TScrollEvent.ScrollCmd], scWheelUp + je .scrollwheelup + cmp [ebx+TScrollEvent.ScrollCmd], scWheelDn + je .scrollwheeldn + + cmp [ebx+TScrollEvent.ScrollCmd], scUp + je .scrollup + cmp [ebx+TScrollEvent.ScrollCmd], scDown + je .scrolldn + + jmp .continue + +; scroll down +.scrollwheelup: + neg ecx + +.scrollwheeldn: + imul ecx, [FreshEditTheme.MouseWheel] + +.scrolldn: +.scrollup: + mov eax, [esi+TFreshEdit._VScroller.Pos] + add eax, ecx + jns .vsignok + xor eax, eax +.vsignok: + cmp eax, [esi+TFreshEdit._VScroller.Max] + jbe .vmaxok + mov eax, [esi+TFreshEdit._VScroller.Max] +.vmaxok: + mov [esi+TFreshEdit._VScroller.Pos], eax + jmp .refresh + +.track: +; mov [esi+TFreshEdit._VScroller.Pos], ecx + jmp .refresh + +.xscroll: + jmp .refresh + + +.refresh: + mov [esi+TFreshEdit._fShadowValid], 0 + execute esi, TWindow.Refresh + clc + popad + return + + +;.............................................................................................. + +oncase seMoveResize + + stdcall TScrollWindow.SysEventHandler, esi, [.pEvent] + + cmp [esi+TFreshEdit._pShadow], 0 + je @f + stdcall DestroyBackBuffer, [esi+TFreshEdit._pShadow] +@@: + stdcall Get, esi, TScrollWindow.FreeArea ; compute the free area. + mov ecx, [eax+TBounds.width] + mov edx, [eax+TBounds.height] + + stdcall CreateBackBuffer, [esi+TFreshEdit.handle], ecx, edx + mov [esi+TFreshEdit._pShadow], eax + mov [esi+TFreshEdit._fShadowValid], 0 + + stdcall TFreshEdit.__UpdateScrollbars + + clc + popad + return + +enddp + + + + + + + + + +proc TFreshEdit.__UpdateScrollbars +begin + push eax ebx ecx edx + +; vertical + + mov ebx, [esi+TFreshEdit._pLines] + mov ecx, [ebx+TArray.count] + test ecx, ecx + jz .yok + + dec ecx + mov eax, [ebx+TArray.array+4*ecx] + + mov ecx, [eax+TEditorLine.LineY] + add ecx, [eax+TEditorLine.LineH] + +.yok: + mov edx, [esi+TFreshEdit._pShadow] + mov edx, [edx+TBackBuffer.height] + sub ecx, edx + jns .yok2 + xor ecx, ecx +.yok2: + + mov [esi+TFreshEdit._VScroller.Max], ecx + mov [esi+TFreshEdit._VScroller.Page], edx + cmp [esi+TFreshEdit._VScroller.Pos], ecx + jbe .pos_ok + mov [esi+TFreshEdit._VScroller.Pos], ecx + mov [esi+TFreshEdit._fShadowValid], 0 +.pos_ok: + +; horizontal + + mov ebx, [esi+TFreshEdit._pLengths] + mov eax, [ebx+TArray.count] + mov edx, [esi+TFreshEdit._pShadow] + mov edx, [edx+TBackBuffer.width] + sub edx, [esi+TFreshEdit.__LeftMargin] + sub eax, edx + + mov eax, 1000 ; TEST ONLY!!! + + + mov [esi+TFreshEdit._HScroller.Max], eax + mov [esi+TFreshEdit._HScroller.Page], edx + cmp [esi+TFreshEdit._HScroller.Pos], eax + jbe @f + mov [esi+TFreshEdit._HScroller.Pos], eax + mov [esi+TFreshEdit._fShadowValid], 0 +@@: + pop edx ecx ebx eax + return +endp + + + + + + + + + + +; Computes the wrap positions for the given line of text and returns (possibly reallocated) +; array with the line wrap positions. If the line does not need wrapping - returns 0 and +; frees passed in [.pSublines] array. +; +; Arguments: +; .Data - the string with the line text. +; .pSublines - previously created dword array with wrap positions. +; the subroutine tries to use it and it is not possible, resize it accordingly. +; .RigthMargin - width of the sublines. +; + +proc __CreateSublines, .hText, .pSublines, .RightMargin +begin + pushad + + stdcall StrPtr, [.hText] + mov esi, eax + + xor edi, edi ; count of the lines... + +.outer_loop: + xor ebx, ebx ; the last wrap position. + xor ecx, ecx ; current x position. + +.loop: + stdcall DecodeUtf8, [esi] + inc ecx + test eax, eax + jz .end_string + + cmp eax, ' ' + jne .not_space + + lea ebx, [esi+edx] +.next: + add esi, edx + jmp .loop + +.not_space: + cmp ecx, [.RightMargin] + jbe .next + + test ebx, ebx + jnz .wraphere + + mov ebx, esi + +.wraphere: + push ebx + mov esi, ebx + inc edi + jmp .outer_loop + +.end_string: + mov esi, [.pSublines] + test edi, edi + jnz .fill_sublines + + test esi, esi + jz .exit_empty + + stdcall FreeMem, esi + +.exit_empty: + popad + xor eax, eax + return ; there is no need for pSublines + + +.fill_sublines: + test esi, esi + jz .allocate + + cmp edi, [esi] + jbe .array_ok + + stdcall FreeMem, esi + +.allocate: + lea eax, [4*edi+4] + stdcall GetMem, eax + mov esi, eax + +.array_ok: + mov [esi], edi + + stdcall StrPtr, [.hText] + +.fill: + popd [esi+4*edi] + sub [esi+4*edi], eax + dec edi + jnz .fill + + mov [esp+4*regEAX], esi + popad + return +endp + + + + + +proc __SearchLine, .pLines, .y +begin + pushad + + mov esi, [.pLines] + xor ecx, ecx + mov edx, [esi+TArray.count] + dec edx + +.loop: + cmp ecx, edx + jg .not_found + + lea ebx, [ecx+edx] + shr ebx, 1 + + mov edi, [esi+TArray.array+4*ebx] + mov eax, [edi+TEditorLine.LineY] + + cmp [.y], eax + jl .less + + add eax, [edi+TEditorLine.LineH] + cmp [.y], eax + jge .more + +.found: + mov eax, [.y] + sub eax, [edi+TEditorLine.LineY] + mov [esp+4*regECX], ebx ; index of the line. + mov [esp+4*regEDX], eax ; offset of the line. + clc + popad + return + +.less: + lea edx, [ebx-1] + jmp .loop + +.more: + lea ecx, [ebx+1] + jmp .loop + +.not_found: + stc + popad + return +endp + + + + + ADDED freshlib/FreshEdit/FreshEditTest.asm Index: freshlib/FreshEdit/FreshEditTest.asm ================================================================== --- /dev/null +++ freshlib/FreshEdit/FreshEditTest.asm @@ -0,0 +1,404 @@ +include "%lib%/freshlib.inc" + +@BinaryType GUI + +options.DebugMode = 0 + +include '%lib%/freshlib.asm' + +include 'FreshEdit2.asm' +include "fasm_syntax.asm" + +iglobal +frmMainForm: + ObjTemplate tfParent or tfEnd, Form, frmMain, \ + x, 100, \ + y, 50, \ + width, 640, \ + height, 480, \ + borderKind, borderFull, \ + Visible, TRUE, \ + Caption, 'FreshEdit test application.' + + ObjTemplate tfParent, Form, Toolbar, \ + x, 0, y, 0, \ + width, 100, height, 20, \ + Align, waBottom, \ + borderKind, borderNone, \ + Visible, TRUE + + ObjTemplate tfChild, Button, btnOpen, \ + x, 112, y, 2, \ + width, 64, height, 21, \ + Align, waLeft, \ + Caption, 'Open', \ + TextAlign, dtfAlignCenter or dtfAlignMiddle, \ + OnClick, OnOpenFile, \ + Visible, TRUE + + ObjTemplate tfChild, Button, btnSave, \ + x, 180, y, 2, \ + width, 64, height, 21, \ + Align, waLeft, \ + Caption, 'Save', \ + TextAlign, dtfAlignCenter or dtfAlignMiddle, \ + OnClick, OnSaveFile, \ + Visible, TRUE + + ObjTemplate tfChild, Button, btnNumbers, \ + x, 180, y, 2, \ + width, 21, height, 21, \ + Align, waLeft, \ + Caption, '#', \ + TextAlign, dtfAlignCenter or dtfAlignMiddle, \ + OnClick, OnNumbers, \ + Visible, TRUE + + ObjTemplate tfChild, Button, btnZebra, \ + x, 180, y, 2, \ + width, 21, height, 21, \ + Align, waLeft, \ + Caption, 'Z', \ + TextAlign, dtfAlignCenter or dtfAlignMiddle, \ + OnClick, OnZebra, \ + Visible, TRUE + + ObjTemplate tfChild, Button, btnTheme, \ + x, 180, y, 2, \ + width, 21, height, 21, \ + Align, waLeft, \ + Caption, 'T', \ + TextAlign, dtfAlignCenter or dtfAlignMiddle, \ + OnClick, OnTheme, \ + Visible, TRUE + + ObjTemplate tfEnd, Edit, FilenameEdit, \ + x, 2, y, 2, \ + width, 100, height, 21, \ + Align, waClient, \ + Visible, TRUE + + ObjTemplate tfEnd, FreshEdit, Editor, \ + Visible, TRUE, \ + x, 8, y, 8, \ + width, 624, height, 464, \ + Align, waClient + + SampleText file 'unicode_test.txt' + dd 0 + +endg + + +;-------------------------------------------------------------------------- + +start: + InitializeAll + +; TEST CODE - to be removed later --------------------------------------- + stdcall Output, '00000000001111111111222222222233333333334444444444555555555566666666667777777777' + stdcall Output, <'01234567890123456789012345678901234567890123456789012345678901234567890123456789',13, 10> + + stdcall PrintWrappedLine, cTestString, 25 + stdcall PrintWrappedLine, cTestString2, 25 + stdcall PrintWrappedLine, cTestString2, 60 + +; END OF THE TEST CODE --------------------------------------------------- + + + stdcall Create, CApplication + jc .start_error + mov [pApplication], ebx + + stdcall [lprTextLine.Initialize] + + stdcall CreateFromTemplate, frmMainForm, 0 + mov ecx, [pApplication] + mov [ecx+TApplication.MainWindow], frmMain + + execute [Editor], TFreshEdit.LoadFromFile, 'unicode_test.txt' + + execute [Editor], TFreshEdit.AppendLine, 'This is Test line' + execute [Editor], TFreshEdit.AppendLine, 'This is Test line number 2' + execute [Editor], TFreshEdit.AppendLine, 'This is the third test line.' + + stdcall Set, [Editor], TFreshEdit._procSyntax, SyntaxFASM +; stdcall Set, [Editor], TFreshEdit.OnControlKey, procKeyPress +; stdcall Set, [Editor], TFreshEdit.Text, SampleText + + +; TEST CODE - to be removed later --------------------------------------- + stdcall SaveTheme, 'test.cfg', FreshEditTheme, pThemePath1 + stdcall TFETheme.SetDefaultThemeClassic, FreshEditTheme + stdcall SaveTheme, 'test.cfg', FreshEditTheme, pThemePath2 + +iglobal + pThemePath1 dd 'EThm', 'tWin', 0 + pThemePath2 dd 'EThm', 'tCls', 0 +endg +; END OF THE TEST CODE --------------------------------------------------- + + + stdcall Run + +.terminate: + stdcall [lprTextLine.Finalize] + + FinalizeAll + stdcall Terminate, 0 + +.start_error: + DebugMsg "Can't create application object." + jmp .terminate + + + +var FreshEditSetTheme = TFETheme.SetDefaultThemeWindows + + +proc OnTheme, .self, .mousebtn +begin + xor [FreshEditSetTheme], TFETheme.SetDefaultThemeWindows xor TFETheme.SetDefaultThemeClassic + stdcall [FreshEditSetTheme], FreshEditTheme + xor [SynTheme], fasm_colors_classic xor fasm_colors_windows + execute [Editor], TFreshEdit.Refresh + return +endp + + +proc OnZebra, .self, .mousebtn +begin + xor [FreshEditTheme.Options], eoStripedBackground + execute [Editor], TFreshEdit.Refresh + return +endp + + +proc OnNumbers, .self, .mousebtn +begin + xor [FreshEditTheme.Options], eoLineNumbers + execute [Editor], TFreshEdit.Refresh + return +endp + + +cErrorTitleOpen text "Error open file." +cErrorTitleSave text "Error save file." + +proc OnSaveFile, .self, .mousebtn +begin + pushad + +; stdcall Get, [FilenameEdit], TEdit.Text +; push eax +; stdcall StrPtr, eax +; mov edi, eax +; +; stdcall Get, [Editor], TFreshEdit.Text +; jc .finish +; +; push eax +; stdcall StrPtr, eax +; +; stdcall SaveBinaryFile, edi, eax, [eax+string.len] +; jnc .end_save +; +; stdcall GetErrorString, eax +; mov esi, eax +; stdcall ShowMessage, [frmMain], smiError, cErrorTitleSave, esi, smbOK +; stdcall FreeErrorString, esi +; +;.end_save: +; stdcall StrDel ; from the stack +;.finish: +; stdcall StrDel ; from the stack + popad + return +endp + + +proc OnOpenFile, .self, .mousebtn +begin + pushad +; Load test file +; stdcall Get, [FilenameEdit], TEdit.Text +; push eax +; +; stdcall StrPtr, eax +; stdcall LoadBinaryFile, eax +; jnc .loaded +; +; stdcall GetErrorString, eax +; mov esi, eax +; stdcall ShowMessage, [frmMain], smiError, cErrorTitleOpen, esi, smbOK +; stdcall FreeErrorString, esi +; jmp .exit +; +;.loaded: +; push eax +; stdcall Set, [Editor], TFreshEdit.Text, eax +; stdcall FreeMem ; from the stack +; +;.exit: +; stdcall StrDel ; from the stack +; +; mov eax, [Editor] +; mov [eax+TFreshEdit._xCaret], 0 +; mov [eax+TFreshEdit._yCaret], 0 +; mov [eax+TFreshEdit._xSelection], 0 +; mov [eax+TFreshEdit._ySelection], 0 +; +;; stdcall ParseFolding, [eax+TFreshEdit._pLines] +; +; execute [Editor], TFreshEdit.Refresh +; execute [Editor], TFreshEdit.Focus + popad + return +endp + + + + +proc procKeyPress, .self, .keyevent +begin + + return +; mov ebx, [.keyevent] +; +; mov eax, [ebx+TKeyboardEvent.key] +; +; cmp eax, $03 ; ctrl+C +; je .copy +; cmp eax, $16 ; ctrl+V +; je .paste +; cmp eax, 12 ; ctrl+L +; je .length_list +; cmp eax, 18 ; ctrl+R +; je .clipright +; cmp eax, 19 ; ctrl+S == save +; je .save +; cmp eax, 20 ; ctrl+T +; je .test_something +; +; cmp [ebx+TKeyboardEvent.scancode], keyF2 +; je .toggle_breakpoint +; +;.finish: +; mov eax, chgfNoClearSelection +;.exit: +; return +; +;.copy: +; stdcall Get, [.self], TFreshEdit.Selection +; test eax, eax +; jz .end_copy +; stdcall ClipboardWrite, eax +; stdcall StrDel, eax +;.end_copy: +; mov eax, chgfNoClearSelection +; return +; +;.paste: +; stdcall ClipboardRead +; test eax, eax +; jz .end_paste +; +; stdcall Set, [.self], TFreshEdit.Selection, eax +; stdcall StrDel, eax +; +; mov eax, chgfNeedRefresh +;.end_paste: +; return +; +; +;.save: +; stdcall OnSaveFile, [.self], 0 +; xor eax, eax +; return +; +;.length_list: +; xor eax, eax +; return +; +;.clipright: +; stdcall Get, esi, TFreshEdit.CurrentLine +; jc .finish +; stdcall StrClipSpacesR, [eax+TEditorLine.Data] +; mov eax, chgfNeedRefresh +; return +; +;.test_something: +; mov eax, chgfNeedRefresh +; return +; +; +;.toggle_breakpoint: +; cmp [esi+TFreshEdit._fReadOnly], froReadWrite +; jne .finish +; +; stdcall Get, esi, TFreshEdit.CurrentLine +; jc .finish +; +; xor [eax+TEditorLine.flags], lfBreakpoint +; mov eax, chgfNeedRefresh or chgfNoClearSelection +; return +; +; +;. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . + +endp + + + + + +proc PrintWrappedLine, .hString, .width +begin + pushad + + stdcall StrPtr, [.hString] + mov ebx, eax + + stdcall __CreateSublines, ebx, 0, [.width] + mov edi, eax + push eax + + xor esi, esi + mov ecx, [edi] + add edi, 4 + +.loop1: + mov eax, [edi] + sub eax, esi + lea edx, [esi+ebx] + stdcall FileWrite, [STDOUT], edx, eax + stdcall FileWrite, [STDOUT], cCRLF, 2 + mov esi, [edi] + add edi, 4 + dec ecx + jnz .loop1 + + lea edx, [esi+ebx] + stdcall StrLen, edx + stdcall FileWrite, [STDOUT], edx, eax + stdcall FileWrite, [STDOUT], cCRLF, 2 + stdcall FileWrite, [STDOUT], cCRLF, 2 + + stdcall FreeMem ; from the stack + + popad + return +endp + + +cTestString text 'This is test string that has to be word wrapped on some position as a test ', \ + 'for the word wrap formatting procedure. This procedure creates an array ', \ + 'with offsets to the begining of the sublines where the string has to be wrap.' +cTestString2 text 'This_is_test_string_that_has_to_be_word_wrapped_on_some_position_as_a_test_', \ + 'for_the_word_wrap_formatting_procedure._This_procedure_creates_an_array_', \ + 'with_offsets_to_the_begining_of_the_sublines_where_the_string_has_to_be_wrap.' +cCRLF text 13, 10 + + +@AllImportSection +@AllDataSection ADDED freshlib/FreshEdit/FreshEditTest.fpr Index: freshlib/FreshEdit/FreshEditTest.fpr ================================================================== --- /dev/null +++ freshlib/FreshEdit/FreshEditTest.fpr cannot compute difference between binary files Index: freshlib/FreshEdit/FreshEditThemes.asm ================================================================== --- freshlib/FreshEdit/FreshEditThemes.asm +++ freshlib/FreshEdit/FreshEditThemes.asm @@ -20,18 +20,34 @@ .scancode dd ? .kbdStatus dd ? .maskStatus dd ? ; what bits from the kbdStatus to be compared ends - macro Shortcut .key, .scancode, .kbdstatus, .maskstatus { dd .key dd .scancode dd .kbdstatus dd .maskstatus } + +ffBold = 1 +ffItalic = 2 +ffUnderlined = 4 +ffStrikeOut = 8 + + +struct TThemeFont + .ptrFace dd ? ; pointer to the font face string. + .size db ? ; in pixels height. + .flags db ? ; flag - normal, bold, italic, etc. + .family db ? ; fixed, proportional + .reserved db ? + + .handle dd ? ; created on the first use. +ends + eoAutoIndents = 1 eoSaveWithTabs = 2 eoVerticalCaret = 4 eoStripedBackground = 8 @@ -39,31 +55,35 @@ eoLineNumbers = 32 struct TFETheme ; colors - .clBackground dd ? ; background color of the editor field. - .clAltBack dd ? ; althernative background (when eoStripedBackground is true) - .clSimpleText dd ? ; The default color of the text, when no syntax highlighter is attached. - .clProtectedText dd ? ; the color of the protected line text. - - .clSelBack dd ? ; - .clSelMode dd ? ; - - .clLeftMargin dd ? ; the color of the left margin field. - .clLeftMarginBorder dd ? ; left margin border color. - .clLeftMarginText dd ? - .clLeftMarginTree dd ? - - .clBookmarkBack dd ? ; background of the left margin when the bookmark is set. - .clWrapColumn dd ? ; color of the line that marks word wrap column. + .clAfterBackground dd ? ; the background after the end of the text. + .clBackground dd ? ; background color of the editor field. + .clAltBack dd ? ; althernative background (when eoStripedBackground is true) + + .clSelBack dd ? ; background color for selections + .clSelAltBack dd ? ; althernative background for selections (when eoStripedBackground is true) + + .clLeftMargin dd ? ; the color of the left margin field. + .clLeftMarginBorder dd ? ; left margin border color. + .clLeftMarginText dd ? + .clLeftMarginTree dd ? + + .clBookmarkBack dd ? ; background of the left margin when the bookmark is set. + .clWrapColumn dd ? ; color of the line that marks word wrap column. + + .clSyntax rd 32 ; 32 syntax colors - more than needed, but... + + .FontsSyntax TThemeFont ; 32 syntax fonts - more than needed, but... (640K are enough for everyone) + rb 31*sizeof.TThemeFont ; options and behavior - .Options dd ? ; flags eoLineSeparator, eoAutoIndents, eoSaveWithTabs, eoVerticalCaret - .MouseWheel dd ? ; the count of the lines, one mouse wheel event scrolls. - .WrapPos dd ? ; word wrap position for the lines that have lfWordWrap flag set. - .UndoLevels dd ? ; how many levels of undo/redo to be remembered. + .Options dd ? ; flags eoXXXXX (see above). + .MouseWheel dd ? ; the count of the pixels, one mouse wheel event scrolls. + .WrapPos dd ? ; word wrap position for the lines that have lfWordWrap flag set. + .UndoLevels dd ? ; how many levels of undo/redo to be remembered. ; keyboard shortcuts: ; navigation .shortcuts: @@ -96,59 +116,141 @@ .ToggleSelMode TShortcut .shortcuts.count = ($ - .shortcuts)/sizeof.TShortcut ends +struct TCfgInfo + .key dd ? + .offset dw ? + .type dw ? +ends + + +macro cfginfo offset, key, type { + dd key + dw offset + dw type +} + +cfgInteger = 0 +cfgFont = 1 +cfgShortcut = 2 + iglobal if used FreshEditThemeKeys FreshEditThemeKeys: ; colors - dd TFETheme.clBackground, 'cBKG' - dd TFETheme.clAltBack, 'cABK' - dd TFETheme.clSimpleText, 'cTXT' - dd TFETheme.clProtectedText, 'cPRT' - dd TFETheme.clSelBack, 'cSBK' - dd TFETheme.clSelMode, 'cSMD' - dd TFETheme.clLeftMargin, 'cMrg' - dd TFETheme.clLeftMarginBorder, 'cMBr' - dd TFETheme.clLeftMarginText, 'cMTx' - dd TFETheme.clLeftMarginTree, 'cMTr' - dd TFETheme.clBookmarkBack, 'cBMB' - dd TFETheme.clWrapColumn, 'cWrC' - - dd TFETheme.Options, 'Opts' - dd TFETheme.MouseWheel 'nWhl' - dd TFETheme.WrapPos, 'WrPs' - dd TFETheme.UndoLevels, 'UdLv' + cfginfo TFETheme.clAfterBackground, 'cAFB', cfgInteger + cfginfo TFETheme.clBackground, 'cBKG', cfgInteger + cfginfo TFETheme.clAltBack, 'cABK', cfgInteger + cfginfo TFETheme.clSelBack, 'cSBK', cfgInteger + cfginfo TFETheme.clSelAltBack, 'cSAB', cfgInteger + cfginfo TFETheme.clLeftMargin, 'cMrg', cfgInteger + cfginfo TFETheme.clLeftMarginBorder, 'cMBr', cfgInteger + cfginfo TFETheme.clLeftMarginText, 'cMTx', cfgInteger + cfginfo TFETheme.clLeftMarginTree, 'cMTr', cfgInteger + cfginfo TFETheme.clBookmarkBack, 'cBMB', cfgInteger + cfginfo TFETheme.clWrapColumn, 'cWrC', cfgInteger + + cfginfo TFETheme.clSyntax, 'cS00', cfgInteger + cfginfo TFETheme.clSyntax+4, 'cS01', cfgInteger + cfginfo TFETheme.clSyntax+8, 'cS02', cfgInteger + cfginfo TFETheme.clSyntax+12, 'cS03', cfgInteger + cfginfo TFETheme.clSyntax+16, 'cS04', cfgInteger + cfginfo TFETheme.clSyntax+20, 'cS05', cfgInteger + cfginfo TFETheme.clSyntax+24, 'cS06', cfgInteger + cfginfo TFETheme.clSyntax+28, 'cS07', cfgInteger + cfginfo TFETheme.clSyntax+32, 'cS08', cfgInteger + cfginfo TFETheme.clSyntax+36, 'cS09', cfgInteger + cfginfo TFETheme.clSyntax+40, 'cS10', cfgInteger + cfginfo TFETheme.clSyntax+44, 'cS11', cfgInteger + cfginfo TFETheme.clSyntax+48, 'cS12', cfgInteger + cfginfo TFETheme.clSyntax+52, 'cS13', cfgInteger + cfginfo TFETheme.clSyntax+56, 'cS14', cfgInteger + cfginfo TFETheme.clSyntax+60, 'cS15', cfgInteger + cfginfo TFETheme.clSyntax+64, 'cS16', cfgInteger + cfginfo TFETheme.clSyntax+68, 'cS17', cfgInteger + cfginfo TFETheme.clSyntax+72, 'cS18', cfgInteger + cfginfo TFETheme.clSyntax+76, 'cS19', cfgInteger + cfginfo TFETheme.clSyntax+80, 'cS20', cfgInteger + cfginfo TFETheme.clSyntax+84, 'cS21', cfgInteger + cfginfo TFETheme.clSyntax+88, 'cS22', cfgInteger + cfginfo TFETheme.clSyntax+92, 'cS23', cfgInteger + cfginfo TFETheme.clSyntax+96, 'cS24', cfgInteger + cfginfo TFETheme.clSyntax+100, 'cS25', cfgInteger + cfginfo TFETheme.clSyntax+104, 'cS26', cfgInteger + cfginfo TFETheme.clSyntax+108, 'cS27', cfgInteger + cfginfo TFETheme.clSyntax+112, 'cS28', cfgInteger + cfginfo TFETheme.clSyntax+116, 'cS29', cfgInteger + cfginfo TFETheme.clSyntax+120, 'cS30', cfgInteger + cfginfo TFETheme.clSyntax+124, 'cS31', cfgInteger + + cfginfo TFETheme.FontsSyntax+0*sizeof.TThemeFont, 'fS00', cfgFont + cfginfo TFETheme.FontsSyntax+1*sizeof.TThemeFont, 'fS01', cfgFont + cfginfo TFETheme.FontsSyntax+2*sizeof.TThemeFont, 'fS02', cfgFont + cfginfo TFETheme.FontsSyntax+3*sizeof.TThemeFont, 'fS03', cfgFont + cfginfo TFETheme.FontsSyntax+4*sizeof.TThemeFont, 'fS04', cfgFont + cfginfo TFETheme.FontsSyntax+5*sizeof.TThemeFont, 'fS05', cfgFont + cfginfo TFETheme.FontsSyntax+6*sizeof.TThemeFont, 'fS06', cfgFont + cfginfo TFETheme.FontsSyntax+7*sizeof.TThemeFont, 'fS07', cfgFont + cfginfo TFETheme.FontsSyntax+8*sizeof.TThemeFont, 'fS08', cfgFont + cfginfo TFETheme.FontsSyntax+9*sizeof.TThemeFont, 'fS09', cfgFont + cfginfo TFETheme.FontsSyntax+10*sizeof.TThemeFont, 'fS10', cfgFont + cfginfo TFETheme.FontsSyntax+11*sizeof.TThemeFont, 'fS11', cfgFont + cfginfo TFETheme.FontsSyntax+12*sizeof.TThemeFont, 'fS12', cfgFont + cfginfo TFETheme.FontsSyntax+13*sizeof.TThemeFont, 'fS13', cfgFont + cfginfo TFETheme.FontsSyntax+14*sizeof.TThemeFont, 'fS14', cfgFont + cfginfo TFETheme.FontsSyntax+15*sizeof.TThemeFont, 'fS15', cfgFont + cfginfo TFETheme.FontsSyntax+16*sizeof.TThemeFont, 'fS16', cfgFont + cfginfo TFETheme.FontsSyntax+17*sizeof.TThemeFont, 'fS17', cfgFont + cfginfo TFETheme.FontsSyntax+18*sizeof.TThemeFont, 'fS18', cfgFont + cfginfo TFETheme.FontsSyntax+19*sizeof.TThemeFont, 'fS19', cfgFont + cfginfo TFETheme.FontsSyntax+20*sizeof.TThemeFont, 'fS20', cfgFont + cfginfo TFETheme.FontsSyntax+21*sizeof.TThemeFont, 'fS21', cfgFont + cfginfo TFETheme.FontsSyntax+22*sizeof.TThemeFont, 'fS22', cfgFont + cfginfo TFETheme.FontsSyntax+23*sizeof.TThemeFont, 'fS23', cfgFont + cfginfo TFETheme.FontsSyntax+24*sizeof.TThemeFont, 'fS24', cfgFont + cfginfo TFETheme.FontsSyntax+25*sizeof.TThemeFont, 'fS25', cfgFont + cfginfo TFETheme.FontsSyntax+26*sizeof.TThemeFont, 'fS26', cfgFont + cfginfo TFETheme.FontsSyntax+27*sizeof.TThemeFont, 'fS27', cfgFont + cfginfo TFETheme.FontsSyntax+28*sizeof.TThemeFont, 'fS28', cfgFont + cfginfo TFETheme.FontsSyntax+29*sizeof.TThemeFont, 'fS29', cfgFont + cfginfo TFETheme.FontsSyntax+30*sizeof.TThemeFont, 'fS30', cfgFont + cfginfo TFETheme.FontsSyntax+31*sizeof.TThemeFont, 'fS31', cfgFont + + cfginfo TFETheme.Options, 'Opts', cfgInteger + cfginfo TFETheme.MouseWheel, 'nWhl', cfgInteger + cfginfo TFETheme.WrapPos, 'WrPs', cfgInteger + cfginfo TFETheme.UndoLevels, 'UdLv', cfgInteger ; keyboard shortcuts: ; navigation - dd TFETheme.keyUp, 'kkUp' - dd TFETheme.keyDown, 'kkDn' - dd TFETheme.keyLeft, 'kLft' - dd TFETheme.keyRight, 'kRgt' - dd TFETheme.keyPgUp, 'kPUp' - dd TFETheme.keyPgDn, 'kPDn' - dd TFETheme.keyHome, 'kHom' - dd TFETheme.keyEnd, 'kEnd' - dd TFETheme.keyPageBegin, 'kPgB' - dd TFETheme.keyPageEnd, 'kPgE' - dd TFETheme.keyTextBegin, 'kTxB' - dd TFETheme.keyTextEnd, 'kTxE' - dd TFETheme.keyWordLeft, 'kWdL' - dd TFETheme.keyWordRight, 'kWdR' + cfginfo TFETheme.keyUp, 'kkUp', cfgShortcut + cfginfo TFETheme.keyDown, 'kkDn', cfgShortcut + cfginfo TFETheme.keyLeft, 'kLft', cfgShortcut + cfginfo TFETheme.keyRight, 'kRgt', cfgShortcut + cfginfo TFETheme.keyPgUp, 'kPUp', cfgShortcut + cfginfo TFETheme.keyPgDn, 'kPDn', cfgShortcut + cfginfo TFETheme.keyHome, 'kHom', cfgShortcut + cfginfo TFETheme.keyEnd, 'kEnd', cfgShortcut + cfginfo TFETheme.keyPageBegin, 'kPgB', cfgShortcut + cfginfo TFETheme.keyPageEnd, 'kPgE', cfgShortcut + cfginfo TFETheme.keyTextBegin, 'kTxB', cfgShortcut + cfginfo TFETheme.keyTextEnd, 'kTxE', cfgShortcut + cfginfo TFETheme.keyWordLeft, 'kWdL', cfgShortcut + cfginfo TFETheme.keyWordRight, 'kWdR', cfgShortcut ; Edit - dd TFETheme.Delete, 'kDel' - dd TFETheme.DelLine, 'kDLn' - dd TFETheme.Backspace, 'kBkS' + cfginfo TFETheme.Delete, 'kDel', cfgShortcut + cfginfo TFETheme.DelLine, 'kDLn', cfgShortcut + cfginfo TFETheme.Backspace, 'kBkS', cfgShortcut ; Formating - dd TFETheme.ToggleWordWrap, 'kWWr' - dd TFETheme.ToggleBookmark, 'kBkm' - dd TFETheme.ToggleInsMode, 'kIMd' - dd TFETheme.ToggleSelMode, 'kSMd' + cfginfo TFETheme.ToggleWordWrap, 'kWWr', cfgShortcut + cfginfo TFETheme.ToggleBookmark, 'kBkm', cfgShortcut + cfginfo TFETheme.ToggleInsMode, 'kIMd', cfgShortcut + cfginfo TFETheme.ToggleSelMode, 'kSMd', cfgShortcut dd 0 end if endg @@ -198,30 +300,32 @@ begin push ebx ecx esi edi mov ebx, [.ptrTheme] ; colors + + mov [ebx+TFETheme.clAfterBackground], $d0d0d0 mov [ebx+TFETheme.clBackground], $ffffff mov [ebx+TFETheme.clAltBack], $e8e8e8 - mov [ebx+TFETheme.clSimpleText], $000000 - mov [ebx+TFETheme.clProtectedText], $a0a000 - - mov [ebx+TFETheme.clSelBack], $ffff7f - mov [ebx+TFETheme.clSelMode], cmXor + mov [ebx+TFETheme.clSelBack], $000080 + mov [ebx+TFETheme.clSelAltBack], $000090 mov [ebx+TFETheme.clLeftMargin], $d0d0d8 mov [ebx+TFETheme.clLeftMarginBorder], $606060 mov [ebx+TFETheme.clLeftMarginText], $000000 mov [ebx+TFETheme.clLeftMarginTree], $9000ff mov [ebx+TFETheme.clBookmarkBack], $ffd000 + mov [ebx+TFETheme.clSyntax], $000000 + mov [ebx+TFETheme.clSyntax+4], $808080 + mov [ebx+TFETheme.clWrapColumn], $c0c0ff - mov [ebx+TFETheme.Options], eoLeftMargin or eoLineNumbers + mov [ebx+TFETheme.Options], eoLineNumbers or eoLeftMargin mov [ebx+TFETheme.WrapPos], 70 - mov [ebx+TFETheme.MouseWheel], 3 + mov [ebx+TFETheme.MouseWheel], 16 mov esi, TFETheme.DefaultShortcuts lea edi, [ebx+TFETheme.shortcuts] mov ecx, TFETheme.DefaultShortcuts.size rep movsd @@ -237,30 +341,31 @@ begin push ebx ecx esi edi mov ebx, [.ptrTheme] ; colors + mov [ebx+TFETheme.clAfterBackground], $000040 mov [ebx+TFETheme.clBackground], $000080 mov [ebx+TFETheme.clAltBack], $000090 - mov [ebx+TFETheme.clSimpleText], $ffffff - mov [ebx+TFETheme.clProtectedText], $a0a000 - - mov [ebx+TFETheme.clSelBack], $0000ff - mov [ebx+TFETheme.clSelMode], cmOr + mov [ebx+TFETheme.clSelBack], $c0c0c0 + mov [ebx+TFETheme.clSelAltBack], $a0a0a0 mov [ebx+TFETheme.clLeftMargin], $c0c0c0 mov [ebx+TFETheme.clLeftMarginBorder], $ffffff mov [ebx+TFETheme.clLeftMarginText], $000000 mov [ebx+TFETheme.clLeftMarginTree], $ff0000 mov [ebx+TFETheme.clBookmarkBack], $ffd000 + mov [ebx+TFETheme.clSyntax], $ffffff + mov [ebx+TFETheme.clSyntax+4], $a0a000 + mov [ebx+TFETheme.clWrapColumn], $0000ff - mov [ebx+TFETheme.Options], eoLeftMargin or eoLineNumbers + mov [ebx+TFETheme.Options], eoLineNumbers or eoLeftMargin mov [ebx+TFETheme.WrapPos], 70 - mov [ebx+TFETheme.MouseWheel], 3 + mov [ebx+TFETheme.MouseWheel], 16 mov esi, TFETheme.DefaultShortcuts lea edi, [ebx+TFETheme.shortcuts] mov ecx, TFETheme.DefaultShortcuts.size rep movsd @@ -269,8 +374,162 @@ return endp + +proc SaveTheme, .ptrConfigFile, .ptrTheme, .ptrPath +.ptrDB dd ? +.newpath dd ? +begin + pushad + + xor esi, esi + mov ebx, 'THTM' + + stdcall LoadBinaryFile, [.ptrConfigFile] + jc .file_ok + + mov esi, eax + mov ebx, -1 + +.file_ok: + stdcall LoadConfigDB, esi, ebx + mov [.ptrDB], eax + + test esi, esi + jz @f + stdcall FreeMem, esi +@@: + + mov esi, [.ptrTheme] + mov ebx, FreshEditThemeKeys + +.loop: + cmp [ebx+TCfgInfo.key], 0 + je .end_of_keys + + cmp [ebx+TCfgInfo.type], cfgFont + je .save_font + + cmp [ebx+TCfgInfo.type], cfgShortcut + je .save_shortcut + +; save integer + + lea eax, [.ptrDB] + movzx ecx, [ebx+TCfgInfo.offset] + stdcall SetConfigParam, eax, [.ptrPath], [ebx+TCfgInfo.key], cdtInteger, [esi+ecx], 4 + +.next: + add ebx, sizeof.TCfgInfo + jmp .loop + +.save_font: + lea eax, [.ptrDB] + movzx ecx, [ebx+TCfgInfo.offset] + stdcall SetConfigParam, eax, [.ptrPath], [ebx+TCfgInfo.key], cdtConfig, eax, eax + + stdcall __CreateNewPath, [.ptrPath], [ebx+TCfgInfo.key] + mov [.newpath], eax + + lea eax, [.ptrDB] + mov edx, [esi+ecx+TThemeFont.ptrFace] + test edx, edx + jnz @f + mov edx, cDefaultEditorFont +@@: + stdcall SetConfigParam, eax, [.newpath], 'face', cdtString, edx, 0 + + movzx edx, [esi+ecx+TThemeFont.size] + stdcall SetConfigParam, eax, [.newpath], 'size', cdtInteger, edx, 0 + + movzx edx, [esi+ecx+TThemeFont.flags] + stdcall SetConfigParam, eax, [.newpath], 'flgs', cdtInteger, edx, 0 + + movzx edx, [esi+ecx+TThemeFont.family] + stdcall SetConfigParam, eax, [.newpath], 'fmly', cdtInteger, edx, 0 + + stdcall FreeMem, [.newpath] + jmp .next + +.save_shortcut: + lea eax, [.ptrDB] + movzx ecx, [ebx+TCfgInfo.offset] + stdcall SetConfigParam, eax, [.ptrPath], [ebx+TCfgInfo.key], cdtConfig, eax, eax + + stdcall __CreateNewPath, [.ptrPath], [ebx+TCfgInfo.key] + mov edx, eax + + lea eax, [.ptrDB] + stdcall SetConfigParam, eax, edx, 'ckey', cdtInteger, [esi+ecx+TShortcut.key], 0 + stdcall SetConfigParam, eax, edx, 'scan', cdtInteger, [esi+ecx+TShortcut.scancode], 0 + stdcall SetConfigParam, eax, edx, 'stat', cdtInteger, [esi+ecx+TShortcut.kbdStatus], 0 + stdcall SetConfigParam, eax, edx, 'mask', cdtInteger, [esi+ecx+TShortcut.maskStatus], 0 + + stdcall FreeMem, edx + jmp .next + + +.end_of_keys: + mov eax, [.ptrDB] + stdcall SaveConfigFile, [.ptrDB], [eax+TArray.lparam] + mov esi, eax + + mov ecx, [esi+TArray.count] + lea eax, [esi+TArray.array] + shl ecx, 2 + stdcall SaveBinaryFile, [.ptrConfigFile], eax, ecx + + stdcall FreeMem, esi + stdcall FreeConfigDB, [.ptrDB] + popad + return +endp + + + +proc __CreateNewPath, .ptrPath, .newdir +begin + pushad + mov esi, [.ptrPath] + xor ecx, ecx + test esi, esi + jz .end_found + +.loop: + cmp dword [esi], 0 + je .end_found + add esi, 4 + jmp .loop + +.end_found: + sub esi, [.ptrPath] + mov ecx, esi + lea eax, [ecx+8] + + stdcall GetMem, eax + mov edi, eax + mov ebx, eax + + shr ecx, 2 + + mov esi, [.ptrPath] + test esi, esi + jz .root_ok + + rep movsd + +.root_ok: + mov eax, [.newdir] + stosd + xor eax, eax + stosd + + mov [esp+4*regEAX], ebx + popad + return +endp + endmodule ADDED freshlib/FreshEdit/LineProcessors.asm Index: freshlib/FreshEdit/LineProcessors.asm ================================================================== --- /dev/null +++ freshlib/FreshEdit/LineProcessors.asm @@ -0,0 +1,42 @@ + +; the fields of this structure point to a set of procedures that +; handles one type of editor line. It can be text line or other type of line. +; The editor itself will call this procedures when some processing of the line is needed. + +; some of these procedures can be NULL when not needed. + +struc TLineProcessor [arg] { +common + local offs, start + offs = 0 + start = $ + + .__Create dd ? ; creates line from given text. + .__Free dd ? ; frees all allocated in the file resources. + + .Draw dd ? ; draws the line on the shadow buffer. + .KeyEvent dd ? ; process keyboard events when the caret is in the line. + .MouseEvent dd ? ; process mouse events on the line. + + .ToText dd ? ; Converts the line to cannonical type. The editing is disabled if not possible. + .FromText dd ? ; Converts the line to internal representation suitable for editing. + + .Format dd ? ; prepares the row for painting and computes needed data structures and indexes. + + .Initialize dd ? ; should be called once in order to initialize this line type. + .Finalize dd ? ; should be called once in order to finalize this line type. +forward + if ~arg eq + store dword arg at start+offs + offs = offs + 4 + end if +} + +virtual at 0 + TLineProcessor TLineProcessor +end virtual + + + + +include "TextLineProcessor.asm" ADDED freshlib/FreshEdit/TextLineProcessor.asm Index: freshlib/FreshEdit/TextLineProcessor.asm ================================================================== --- /dev/null +++ freshlib/FreshEdit/TextLineProcessor.asm @@ -0,0 +1,232 @@ +lprTextLine TLineProcessor textLineCreate, \ + textLineFree, \ + textLineDraw, \ + textLineKeyEvent, \ + textLineMouseEvent, \ + textLineToText, \ + textLineFromText, \ + textLineFormat, \ + textLineInit, \ + textLineFinish + + +; Rendering character information for .pRenderInfo array. +struct TCharInfo + .x dd ? ; x coordinate relative to the upper left edge of the line. + .y dd ? ; y coordinate relative to the upper left edge of the line. + .w dw ? ; width of the character. + .h dw ? ; height of the character. + .b dw ? ; base offset of the character. + .c db ? ; color of the character as an index in the syntax colors. + .f db ? ; font of the character as an index in the syntax fonts. +ends + + + +cDefaultEditorFont text 'Fixedsys Excelsior 3.01' +;cDefaultEditorFont text 'Droid sans mono' + + + +proc textLineCreate, .pLine, .hString +begin + push eax esi + + mov esi, [.pLine] + stdcall StrDup, [.hString] + mov [esi+TEditorLine.pData], eax + + pop esi eax + return +endp + + + +proc textLineFree, .pLine +begin + push eax + mov eax, [.pLine] + stdcall StrDel, [eax+TEditorLine.pData] + mov [eax+TEditorLine.pData], 0 + pop eax + return +endp + + + +proc textLineDraw, .context, .pEditor, .pLine, .x, .y +begin + pushad + + add [.y], 12 ; font base line; + + mov esi, [.pLine] + + test [esi+TEditorLine.flags], lfFormatted + jnz .so_draw_it + + stdcall textLineFormat, [.context], [.pEditor], esi + +.so_draw_it: + stdcall StrLen, [esi+TEditorLine.pData] + mov ecx, eax + stdcall StrPtr, [esi+TEditorLine.pData] + mov edi, eax + mov ebx, [esi+TEditorLine.pRenderInfo] ; pointer to TArray of TCharInfo + lea ebx, [ebx+TArray.array] + +.draw_loop: + stdcall DecodeUtf8, [edi] + add edi, edx + + test eax, eax + jz .end_of_string + + movzx eax, [ebx+TCharInfo.c] + movzx ecx, [ebx+TCharInfo.f] + mov eax, [FreshEditTheme.clSyntax+4*eax] + mov ecx, [FreshEditTheme.FontsSyntax+4*ecx] + + push eax ecx ; color and font + + mov eax, [.x] + mov ecx, [.y] + add eax, [ebx+TCharInfo.x] + add ecx, [ebx+TCharInfo.y] + + stdcall DrawString, [.context], edi, edx, eax, ecx ; remaining from the stack. + + add ebx, sizeof.TCharInfo + jmp .draw_loop + +.end_of_string: + popad + return +endp + + + +proc textLineKeyEvent, .pLine, .pEvent +begin + + return +endp + + +proc textLineMouseEvent,.pLine, .pEvent +begin + return +endp + + + +proc textLineToText, .pLine +begin + return +endp + + + +proc textLineFromText, .pLine +begin + return +endp + + + +proc textLineFormat, .context, .pEditor, .pLine + .x dd ? ; current X coordinate. + .y dd ? ; current Y coordinate. + .maxh dd ? ; maximal height of the subline. + + .wrap dd ? +begin + pushad + + mov ebx, [.pLine] + cmp [ebx+TEditorLine.pRenderInfo], 0 + je .info_ok + stdcall FreeMem, [ebx+TEditorLine.pRenderInfo] + +.info_ok: + stdcall CreateArray, sizeof.TCharInfo + mov [ebx+TEditorLine.pRenderInfo], eax + + stdcall StrLenUtf8, [ebx+TEditorLine.pData] + mov ecx, eax + + stdcall AddArrayItems, [ebx+TEditorLine.pRenderInfo], ecx + mov [ebx+TEditorLine.pRenderInfo], edx + + mov eax, [.pEditor] + stdcall [eax+TFreshEdit._procSyntax], [ebx+TEditorLine.pData], edx, [ebx+TEditorLine.syn_context] + mov [ebx+TEditorLine.syn_context], eax + + stdcall StrPtr, [ebx+TEditorLine.pData] + mov esi, eax + mov edi, [ebx+TEditorLine.pRenderInfo] + lea edi, [edi+TArray.array] + +.render_loop: + stdcall DecodeUtf8, [esi] + add esi, edx + + test eax, eax + jz .end_of_string + + mov eax, [.x] + mov edx, [.y] + mov [edi+TCharInfo.x], eax + mov [edi+TCharInfo.y], edx + + movzx eax, [edi+TCharInfo.f] + stdcall GetTextBounds, [.context], esi, edx, [FreshEditTheme.FontsSyntax+4*eax] + + mov [edi+TCharInfo.w], ax + mov [edi+TCharInfo.h], dx + + cmp [.maxh], edx + jae @f + mov [.maxh], edx +@@: + add eax, [.x] + test [ebx+TEditorLine.flags], lfWordWrap + jz .wrap_ok + + cmp eax, [.wrap] + jb .wrap_ok + + mov eax, [.maxh] + add [.y], eax + xor eax, eax + mov [.maxh], eax + +.wrap_ok: + mov [.x], eax + + + jmp .render_loop + +.end_of_string: + popad + return +endp + + + +proc textLineInit +begin +; Main Font settings. +; stdcall FontCreate, cDefaultEditorFont, 0, 0, ffMonospaced +; mov [hTextFont], eax + return +endp + + + +proc textLineFinish +begin +; stdcall FontDestroy, [hTextFont] +; mov [hTextFont], 0 + return +endp Index: freshlib/FreshEdit/fasm_syntax.asm ================================================================== --- freshlib/FreshEdit/fasm_syntax.asm +++ freshlib/FreshEdit/fasm_syntax.asm @@ -16,11 +16,11 @@ ttText = 0 ttRem = 1 ttStr = 2 ttNum = 3 ttChar = 4 - +ttNewLine = $80000000 iglobal var SynTheme = fasm_colors_windows @@ -69,10 +69,17 @@ ; proc SyntaxFASM, .hString, .pAttr, .SynContext .Quo rb 4 .start dd ? begin + pushad + + test [.SynContext], ttNewLine + jz @f + mov [.SynContext], ttText +@@: + and dword [.SynContext], ttNewLine-1 mov edi, [.pAttr] mov ebx, [SynTheme] stdcall StrPtr, [.hString] @@ -160,11 +167,13 @@ inc esi stdcall ScanForwardUtf8 jmp .loop .end_of_line: - mov eax, ttText + popad +; mov eax, ttText + mov eax, [.SynContext] return endp .CharInSymbols: DELETED freshlib/FreshEdit/forth_link.asm Index: freshlib/FreshEdit/forth_link.asm ================================================================== --- freshlib/FreshEdit/forth_link.asm +++ /dev/null @@ -1,525 +0,0 @@ -iglobal -FreshEditKeyScript file 'keyboard.forth' - dd 0 -endg - - - -ForthBlock __FreshEditForthWords - - -forthword 'Left' -begin - call TFreshEdit.__FitCaretInWindow - jz @f - - stc - return - -@@: - push ecx - - mov ecx, [esi+TFreshEdit._xCaret] - jecxz .exit - - dec ecx - mov [esi+TFreshEdit._xCaret], ecx - - mov ecx, [esi+TFreshEdit._LeftColumn] - cmp [esi+TFreshEdit._xCaret], ecx - ja .exit - - mov ecx, [esi+TFreshEdit._cols] - shr ecx, 2 - test ecx, ecx - jnz @f - inc ecx -@@: - sub [esi+TFreshEdit._LeftColumn], ecx - jns @f - - mov [esi+TFreshEdit._LeftColumn], 0 -@@: - -.exit: - clc - pop ecx - return -endfw - - - -forthword 'Right' -begin - call TFreshEdit.__FitCaretInWindow - jz @f - - stc - return - -@@: - push ecx edx - - mov ecx, [esi+TFreshEdit._xCaret] - inc ecx - mov [esi+TFreshEdit._xCaret], ecx - - mov edx, [esi+TFreshEdit._cols] - add edx, [esi+TFreshEdit._LeftColumn] - cmp ecx, edx - jae .scroll_left - -.finish: - clc - pop edx ecx - return - -.scroll_left: - mov ecx, [esi+TFreshEdit._cols] - shr ecx, 2 - test ecx, ecx - jnz @f - inc ecx -@@: - add [esi+TFreshEdit._LeftColumn], ecx - jmp .finish -endfw - - - -forthword 'Up' -begin - call TFreshEdit.__FitCaretInWindow - jz @f - - stc - return - -@@: - push ecx - - cmp [esi+TFreshEdit._yCaret], 0 - je .exit - - dec [esi+TFreshEdit._yCaret] - - mov ecx, [esi+TFreshEdit._TopLine] - cmp [esi+TFreshEdit._yCaret], ecx - jl .scrollup - -.exit: - clc - pop ecx - return - -.scrollup: - mov ecx, [esi+TFreshEdit._TopLine] - jecxz .exit - dec [esi+TFreshEdit._TopLine] - jmp .exit -endfw - - - -TFreshEdit.__CommandScrollLockUp: -forthword 'ScrLockUp' -begin - call TFreshEdit.__FitCaretInWindow - jz @f - - stc - return - -@@: - push ecx - - cmp [esi+TFreshEdit._yCaret], 0 - je .exit - - dec [esi+TFreshEdit._yCaret] - - mov ecx, [esi+TFreshEdit._TopLine] - jecxz .exit - - dec [esi+TFreshEdit._TopLine] - -.exit: - clc - pop ecx - return -endfw - - - -forthword 'ScrollUp' -begin - push ecx - cmp [esi+TFreshEdit._TopLine], 0 - je .finish - dec [esi+TFreshEdit._TopLine] -.finish: - clc - pop ecx - return -endfw - - - - -TFreshEdit.__CommandDown: -forthword 'Down' -begin - call TFreshEdit.__FitCaretInWindow - jz @f - - stc - return - -@@: - push ecx edx - - mov edx, [esi+TFreshEdit._pIndex] - - mov ecx, [esi+TFreshEdit._yCaret] - inc ecx - cmp ecx, [edx+TArray.count] - jae .exit - - mov [esi+TFreshEdit._yCaret], ecx - - mov ecx, [esi+TFreshEdit._TopLine] - add ecx, [esi+TFreshEdit._rows] - cmp [esi+TFreshEdit._yCaret], ecx - jae .scrolldn - -.exit: - clc - pop edx ecx - return - -.scrolldn: - mov ecx, [esi+TFreshEdit._TopLine] - inc ecx - cmp ecx, [edx+TArray.count] - jae .exit - - mov [esi+TFreshEdit._TopLine], ecx - jmp .exit -endfw - - - - -TFreshEdit.__CommandScrollLockDown: -forthword 'ScrLockDown' -begin - call TFreshEdit.__FitCaretInWindow - jz @f - - stc - return - -@@: - push ecx edx - - mov edx, [esi+TFreshEdit._pIndex] - - mov ecx, [esi+TFreshEdit._yCaret] - inc ecx - cmp ecx, [edx+TArray.count] - jae .exit - - mov [esi+TFreshEdit._yCaret], ecx - - mov ecx, [esi+TFreshEdit._TopLine] - inc ecx - add ecx, [esi+TFreshEdit._rows] - cmp ecx, [edx+TArray.count] - ja .exit - - inc [esi+TFreshEdit._TopLine] - -.exit: - clc - pop edx ecx - return - -endfw - - - -forthword 'ScrollDown' -begin - push ecx edx - mov edx, [esi+TFreshEdit._pIndex] - - mov ecx, [esi+TFreshEdit._TopLine] - inc ecx - add ecx, [esi+TFreshEdit._rows] - cmp ecx, [edx+TArray.count] - ja .finish - - inc [esi+TFreshEdit._TopLine] - -.finish: - clc - pop edx ecx - return - -endfw - - - - - -forthword 'PgDown' -begin - push ecx - mov ecx, [esi+TFreshEdit._rows] - -@@: - call TFreshEdit.__CommandScrollLockDown - jc .finish - loop @b - -.finish: - pop ecx - return -endfw - - - -forthword 'PgUp' -begin - push ecx - mov ecx, [esi+TFreshEdit._rows] -@@: - call TFreshEdit.__CommandScrollLockUp - jc .finish - loop @b - -.finish: - pop ecx - return -endfw - - - - -forthword 'LineBegin' -begin - call TFreshEdit.__FitCaretInWindow - jz @f - - stc - return - -@@: - cmp [esi+TFreshEdit._xCaret], 0 - je .end - - mov [esi+TFreshEdit._xCaret], 0 - - cmp [esi+TFreshEdit._LeftColumn], 0 - je .end - - mov [esi+TFreshEdit._LeftColumn], 0 - -.end: - clc - return -endfw - - - - - -forthword 'LineEnd' -begin - call TFreshEdit.__FitCaretInWindow - jz @f - - stc - return - -@@: - push ebx ecx - - mov ecx, [esi+TFreshEdit._yCaret] - mov ebx, [esi+TFreshEdit._pIndex] - - cmp ecx, [ebx+TArray.count] - jae .end - - mov ecx, [ebx+TArray.array+4*ecx] - - shl ecx, TEditorLine.shift - add ecx, [esi+TFreshEdit._pLines] - add ecx, TArray.array - - stdcall StrLenUtf8, [ecx+TEditorLine.Data], -1 - - cmp [esi+TFreshEdit._xCaret], eax - je .end - - mov [esi+TFreshEdit._xCaret], eax - - mov ecx, [esi+TFreshEdit._cols] - lea ecx, [ecx*3] - shr ecx, 2 - - cmp eax, [esi+TFreshEdit._LeftColumn] - jg .leftok - - sub eax, ecx - jns @f - xor eax, eax -@@: - mov [esi+TFreshEdit._LeftColumn], eax - jmp .end - -.leftok: - add ecx, [esi+TFreshEdit._LeftColumn] - sub ecx, [esi+TFreshEdit._xCaret] - jge .end - - sub [esi+TFreshEdit._LeftColumn], ecx - -.end: - clc - pop ecx ebx - return -endfw - - - -TFreshEdit.__CommandBeginOfScreen: -forthword 'ScreenBegin' -begin - call TFreshEdit.__FitCaretInWindow - jz @f - - stc - return - -@@: - mov eax, [esi+TFreshEdit._TopLine] - cmp eax, [esi+TFreshEdit._yCaret] - je .end - - mov [esi+TFreshEdit._yCaret], eax -.end: - return -endfw - - -forthword 'ScreenEnd' -begin - call TFreshEdit.__FitCaretInWindow - jz @f - - stc - return - -@@: - call TFreshEdit.__CommandBeginOfScreen - - mov ecx, [esi+TFreshEdit._rows] - jecxz .end - dec ecx - jecxz .end - -@@: - call TFreshEdit.__CommandDown - jc .end - loop @b - -.end: - return -endfw - - -forthword 'FileBegin' -begin - - return -endfw - - -forthword 'FileEnd' -begin - - return -endfw - - -forthword 'WordPrev' -begin - - return -endfw - - -forthword 'WordNext' -begin - - return -endfw - - - -forthword 'GetSelMode' -begin - - return -endfw - - - -forthword 'SetSelMode' -begin - - return -endfw - - - -forthword 'GetInsMode' -begin - - return -endfw - - -forthword 'SetInsMode' -begin - - return -endfw - - -forthword 'GetRowCount' -begin - - return -endfw - - - -forthword 'ToggleSelMode' -begin - mov eax, [esi+TFreshEdit._SelMode] - inc eax - cmp eax, 2 - jbe @f - xor eax, eax -@@: - mov [esi+TFreshEdit._SelMode], eax - return -endfw - - - -EndForthBlock - -;_________________________________________________________________________________________ DELETED freshlib/FreshEdit/keyboard.forth Index: freshlib/FreshEdit/keyboard.forth ================================================================== --- freshlib/FreshEdit/keyboard.forth +++ /dev/null @@ -1,32 +0,0 @@ -( This file contains ForthScript definitions for navigation and control keys in FreshEdit. - The name of the words is actually the name of the pressed key, as returned by CreateKeyName procedure - defined in the library SysEvents.asm - The words can return a value through the stack top value. It is - 1 - means the -) - -: keyUp Up 0 ; -: keyShift+Up Up 1 ; - -: keyDown Down 0 ; -: keyShift+Down Down 1 ; - -: keyLeft Left 0 ; -: keyShift+Left Left 1 ; - -: keyRight Right 0 ; -: keyShift+Right Right 1 ; - -: keyPgUp PgUp 0 ; -: keyShift+PgUp PgUp 1 ; - -: keyPgDn PgDown 0 ; -: keyShift+PgDn PgDown 1 ; - -: keyHome LineBegin 0 ; -: keyShift+Home LineBegin 1 ; - -: keyEnd LineEnd 0 ; -: keyShift+End LineEnd 1 ; - -: keyCtrl+Alt+Ins ToggleSelMode 1 ; ADDED freshlib/FreshEdit/notes.txt Index: freshlib/FreshEdit/notes.txt ================================================================== --- /dev/null +++ freshlib/FreshEdit/notes.txt @@ -0,0 +1,49 @@ +FreshEdit target features: + +#. Unicode text encoding - UTF-8 based. + +#. Very big files - only memory limited - without decreasing the performance of the editor. + +#. Display of line numbers. + +#. Temporal highlighting part of the text with any color (until the user press any key) It is + for pointing errors. + +#. Read-only files (works like a browser) and read-only lines (for example, autogenerated by + the IDE lines). + +#. Bookmarks, saveable to the file. + +#. Word wrap for some of the lines (user selectable and saveable to the file) + +#. Additional information attached to the text lines - for example debug information. + +#. Multilevel code folding - user selectable and automatic. + +#. Two modes of selections - char and block selections and cut/copy/paste operations. + +#. Context depending syntax highlighting. (for syntaxes that are not line based - for example + for HTML, C++, etc.) + +#. Unlimited UNDO/REDO operations possible. + + + + + +Coordinate systems: + +1. [A] LineNumber, CharNumber + 1.1. LineNumber, ByteNumber + +Needed for text editing purposes - insert text, delete text, selections replace, etc. + +2. [B] LineNumber, SublineNumber, X coordinate + +Needed for text display purposes. + + +3. [C] Y coordinate, X coordinate + +Needed for mouse operations - mouse clicks to other types of coordinates. + ADDED freshlib/FreshEdit/unicode_test.txt Index: freshlib/FreshEdit/unicode_test.txt ================================================================== --- /dev/null +++ freshlib/FreshEdit/unicode_test.txt @@ -0,0 +1,53 @@ +;This is example text, aimed simply to show the features of the FreshEdit control. ;w:F#; + +;1. Word-wrap feature. It works only for the lines formated with word-wrap format. You can set/remove word-wrap format by Ctrl+W key.;w:F#; + +;2. FreshEdit can save the format into the source file. The formating is transparent for FASM compiler, so you can compile the files without removing formating.;w:F#; + +;3. FreshEdit uses UTF-8 encoding - see following samples: + +;Russian: Я могу есть стекло, оно мне не вредит. +;Yoruba: Mo lè je̩ dígí, kò ní pa mí lára. +;Greek: Μπορώ να φάω σπασμένα γυαλιά χωρίς να πάθω τίποτα. +;Québécois: J'peux manger d'la vitre, ça m'fa pas mal. +;Ukrainian: Я можу їсти скло, і воно мені не зашкодить. +;English: I can eat glass and it doesn't hurt me. + +;5. The bookmarks are saved with the text as well. Use Ctrl+B to set/remove a bookmark.;bw:F#; + +;6. Also FreshEdit, has code folding feature. +proc SomeTestProcedure +begin + nop + mov eax, 1234 + return +endp + +;7. also, there are line numbers and breakpoint icons on the left margin of the editor. You can set/remove breakpoint with F2 key.;w:F#; + + nop + nop + int3 + +; 8. Color themes: Click on "T" button to switch the color theme for the editor.;w:F#; + +; 9. Zebra background - if you like such eye-candy things. Click on "Z" button in order to switch it on/off.;w:F#; + +proc AnotherTestProcedure +begin + xor eax, eax + +locals ; We have of course several folding levels. + .x dd ? + .y dd ? + .rect TBounds +endl + + mov ecx, 'ABCD' + return +endp + +; 10. Click "#" to turn on/off the line numbers. +; 11. Ctrl-T will switch ON/OFF the whole left margin field. +; 12. Alt+Ins will switch the type of selection - line, char and block are supported for now.;w:F#; + DELETED freshlib/License.txt Index: freshlib/License.txt ================================================================== --- freshlib/License.txt +++ /dev/null @@ -1,117 +0,0 @@ -The Fresh Artistic License - -Preamble - -The intent of this document is to state the conditions under which a -Package may be copied, such that the Copyright Holder maintains some -semblance of artistic control over the development of the package, -while giving the users of the package the right to use and distribute -the Package in a more-or-less customary fashion, plus the right to make -reasonable modifications. - -Definitions: - - * "Package" refers to the collection of files distributed by the - Copyright Holder, and derivatives of that collection of files - created through textual modification. - * "Standard Version" refers to such a Package if it has not been - modified, or has been modified in accordance with the wishes of - the Copyright Holder. - * "Copyright Holder" is whoever is named in the copyright or - copyrights for the package. - * "You" is you, if you're thinking about copying or distributing - this Package. - * "Reasonable copying fee" is whatever you can justify on the basis - of media cost, duplication charges, time of people involved, and - so on. (You will not be required to justify it to the Copyright - Holder, but only to the computing community at large as a market - that must bear the fee.) - * "Freely Available" means that no fee is charged for the item - itself, though there may be fees involved in handling the item. - It also means that recipients of the item may redistribute it - under the same conditions they received it. - -IMPORTANT NOTE: - FASM compiler itself, which is integral part of this package is - distributed under different license. All source files of FASM - compiler are separated in "source\fasm\" directory. Please read and - apply "source\fasm\license.txt" for FASM license. - -1. You may make and give away verbatim copies of the source form of the - Standard Version of this Package without restriction, provided that - you duplicate all of the original copyright notices and associated - disclaimers. - -2. You may apply bug fixes, portability fixes and other modifications - from the Copyright Holder or those derived from the Public Domain - and approved by the Copyright Holder. A Package modified in such a - way shall still be considered the Standard Version. - -3. You may otherwise modify your copy of this Package in any way, - provided that you insert a prominent notice in each changed file - stating how and when you changed that file, and provided that you do - at least ONE of the following: - - a) place your modifications in the Public Domain or otherwise make - them Freely Available, such as by posting said modifications to - Usenet or an equivalent medium, or placing the modifications on - a major archive site such as ftp.uu.net, or by allowing the - Copyright Holder to include your modifications in the Standard - Version of the Package. - - b) use the modified Package only within your corporation or - organization. - - c) rename any non-standard executables so the names do not conflict - with standard executables, which must also be provided, and - provide a separate manual page for each non-standard executable - that clearly documents how it differs from the Standard Version. - - d) make other distribution arrangements with the Copyright Holder. - -4. You may distribute the programs of this Package in object code or - executable form, provided that you do at least ONE of the following: - - a) distribute a Standard Version of the executables and library - files, together with instructions ( in the manual page or - equivalent) on where to get the Standard Version. - - b) accompany the distribution with the machine-readable source of - the Package with your modifications. - - c) accompany any non-standard executables with their corresponding - Standard Version executables, giving the non-standard - executables non-standard names, and clearly documenting the - differences in manual pages (or equivalent), together with - instructions on where to get the Standard Version. - - d) make other distribution arrangements with the Copyright Holder. - -5. You may charge a reasonable copying fee for any distribution of this - Package. You may charge any fee you choose for support of this - Package. You may not charge a fee for this Package itself. However, - you may distribute this Package in aggregate with other (possibly - commercial) programs as part of a larger (possibly commercial) - software distribution provided that you do not advertise this - Package as a product of your own. - -6. The executable and library files supplied as input to or produced as - output from the programs of this Package do not automatically fall - under the copyright of this Package, but belong to whomever - generated them, and may be sold commercially, and may be aggregated - with this Package. - -7. You may not use this package, nor files created as output from this - package, nor products derived from this package for producing, - distrubuting or in any way contribute to the creation or - distribution of "unwanted advertisement" (known as SPAM). - -8. The name of the Copyright Holder may not be used to endorse or - promote products derived from this software without specific prior - written permission. - -9. THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED - WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF - MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. - -The End DELETED freshlib/TestFreshLib.fpr Index: freshlib/TestFreshLib.fpr ================================================================== --- freshlib/TestFreshLib.fpr +++ /dev/null cannot compute difference between binary files DELETED freshlib/_doc/FreshLibRefMan.odt Index: freshlib/_doc/FreshLibRefMan.odt ================================================================== --- freshlib/_doc/FreshLibRefMan.odt +++ /dev/null cannot compute difference between binary files DELETED freshlib/_doc/Fresh_IDE.wiki Index: freshlib/_doc/Fresh_IDE.wiki ================================================================== --- freshlib/_doc/Fresh_IDE.wiki +++ /dev/null @@ -1,39 +0,0 @@ -
-Index -[http://fresh.flatassembler.net | Fresh home] -[FreshLib reference | FreshLib reference] -[Fresh user guide | Fresh tips&tricks] - |
fossil clone http://chiselapp.com/user/johnfound/repository/FreshIDE/ Fresh.fossil- -In order to use more functionality in this site, please [/login|login] as "anonimous" user. -Particularly you will be able to follow the links in the source tree, to download code and to fill bug reports and feature requests. - -If you want to contribute to the project, please contact me (johnfound) on [http://board.flatassembler.net|FASM message board] - -In order to download compiled FreshIDE, visit [http://fresh.flatassembler.net|Fresh IDE home page.] - -You can report bugs, or make some feature requests here, in the [/reportlist|Tickets system] DELETED freshlib/_doc/Fresh_and_Linux.wiki Index: freshlib/_doc/Fresh_and_Linux.wiki ================================================================== --- freshlib/_doc/Fresh_and_Linux.wiki +++ /dev/null @@ -1,93 +0,0 @@ -
GUI library defines many data structures and procedures that together form -something that conditionally can be called "OOP". It is object oriented, as -long as it deals with GUI "objects" - forms, controls, menus etc. -All these objects are in fact structures of data. For every created object, -the library allocates some memory and fills this memory with object parameters -data.
- -There are two types of data structures that describe GUI objects - classes -and instances.
- -The class is a structure that contains data commonly used by all objects of given type - for example all buttons use one class structure CButton.
- -The instance is data structure that describes the properties and behavior of particular GUI object - for example button with icon "open file" that opens a file when the user click on it.
- -"Class" in FreshLib is a data structure, that have the following definition:
- --struct TObjectClass - .ptrParent dd 0 - .dataSize dd 0 - .procCreate dd 0 - .procDestroy dd 0 - .procGetParam dd 0 - .procSetParam dd 0 - .procExecCmd dd 0 - .procSysEventHandler dd 0 -ends -- -
.ptrParent is a pointer to other TObjectClass structure, that appears as a parent class for the given class.
-.dataSize contains the size of the object instance structure.
- -The following fields are the pointers to procedures that provides the "work" of the object. All of these pointers as a rule can be NULL, if there is no need for such processing.
- -.procCreate is a procedure that creates instance object of the given class. This -field can be NULL. It has the following definition:
--proc Create, .obj --
This procedure sets needed values in the object instance data structure.
- -.procDestroy is a procedure that destroys an instance of the given class.
--proc Destroy, .obj --
Destroys the object passed in [.obj] and frees all memory allocated for this object.
- -.procGetParam is a pointer to the procedure that retrieves and returns the properties of the object.
--proc GetParam, .obj, .paramID --
Returns the value of the object [.obj] parameter with ID=[.paramID]
- -.procSetParam is a pointer to the procedure that set the properties of the object.
--proc Set, .obj, .paramID, .value --
For object [.obj], set the value of the parameter with ID=[.paramID]
- -.procExecCmd is a pointer to the procedure that executes object method.
--proc ExecCmd, .obj, .method --
For the object [.obj] this procedure executes the method with method ID in [.method].
-The methods can have arbitrary number of arguments, that are defined in the "object" definition (see below). -When the method is executed, the procedure [.procExecCmd] accepts pointer to the arguments array in [ebx]
-The user is supposed to call methods of the object with the macro "execute" -The macro is defined following way:
--macro execute obj*, meth*, [arg] -- - -
.procSysEventHandler is a pointer to the procedure that process the system events that are send to the object, i.e. mouse events, keyboard events etc.
--proc SysEventHandler, .obj, .pEvent --
Process one system event for object [.obj]. [.pEvent] contains pointer to the system event.
- -All of these procedures are called internally and should not be used by the user of the library. -How these procedure are called will be described later.
- -TObjectClass structure is defined statically in memory in compile time, only once for every object class. Its definition is located in the library for the respective GUI element. For example CButton class structure is defined in the file TButton.asm that contains the code and data of the object class Button.
- -In order to make construction of such structures easy, macro with name ObjectClass is defined in objects.asm
- --macro ObjectClass name*, parent*, procCreate*, procDestroy*, procGetParam*, procSetParam*, procExecCmd*, procSysEvents* -- -
Every defined ObjectClass have a label that points to the begin of the structure. The name of this label is the name of the class, prefixed with "C".
- -One example of ObjectClass definition is the definition of Window object class:
--ObjectClass Window, \ - Object, \ - TWindow.Create, \ - TWindow.Destroy, \ - TWindow.Get, \ - TWindow.Set, \ - TWindow.ExecCmd, \ - TWindow.SysEventHandler -- -
This definition creates following data structure:
--CWindow: - dd CObject - dd sizeof.TWindow - dd TWindow.Create - dd TWindow.Destroy - dd TWindow.Get - dd TWindow.Set, - dd TWindow.ExecCmd - dd TWindow.SysEventHandler -- - - -
Object instance is data structure that contains different fields. By that it is very similar to the normal FASM structures. As structures, the object is only description of the data but not the data itself.
-Objects can inherit field definitions by its parent objects. -The memory instance of the object is allocated dynamically in runtime, when the object is created by call to the respective FreshLib functions.
-The definition of the object looks like following:
- --object TObject - .ptrClass dd ? - - .OnCreate dd ? - .OnDestroy dd ? - - method .AddChild, .objchild -endobj - - -object TWindow, TObject - .handle dd ? - .Fcaption dd ? - .Fcursor dd ? - - param .x - param .y - param .width - param .height - param .visible - param .caption - param .parent - param .cursor - - method .Refresh -endobj - - -object TButton, TWindow - .state dd ? - .Ficon dd ? - .FiconAlign dd ? - .Ftextalign dd ? - - .OnClick dd ? - - param .TextAlign - param .Icon - param .IconPosition -endobj -- -
By convention the names of the objects begin with "T".
-You can see that the object TWindow contains data fields, parameters and methods. -The parameters defined by "param" macro are compile time constants which values are assigned automatically. -There constants are local labels for the object structure. They are also inherited from the parent structure.
-The methods are very similar to parameters, in that they are constants, defined in compile time. -But besides the constant, the method also have list of arguments, passed to the method, when executed.
- - -In the above example, TButton.width parameter is inherited from TWindow and have the same value as TWindow.width parameter.
-Also, TWindow have all fields of TObject defined as well.
-If we have to translate TWindow definition in plain FASM syntax it will looks like this:
- --struc TWindow { - .ptrClass dd ? - - .OnCreate dd ? - .OnDestroy dd ? - - .handle dd ? - .Fcaption dd ? - .Fcursor dd ? - - .x = $80000000 - .y = $80000001 - .width = $80000002 - .height = $80000003 - .visible = $80000004 - .caption = $80000005 - .parent = $80000006 - .cursor = $80000007 -} -virtual at 0 - TWindow TWindow - sizeof.TWindow = $ -end virtual -- -
This directory contains the libraries providing portable GUI for assembly programming.
-Note that this libraries are in very early stage of development, so the description in this chapter is preliminary and probably will be changed in one or another way in the near future.
-Later in this text, the whole GUI subsystem of FreshLib will be called FreshGUI
- -The main idea behind the FreshGUI is to make one small OS dependent layer of functions, that to serve as an interface between the OS and the OS independent layer of the library.
-The first will translate OS events, such as mouse, keyboard, timers etc to one common standard of OS independent event handlers of the user interface objects – windows, buttons and other widgets.
-The biggest advantage of this approach is that the portability of the library is very easy – most of the code is OS independent and only little part of it have to be write in order to port the whole library to a new OS.
-The biggest drawback of this approach is the bigger size of the library, because, with this architecture, all controls in the library have to be created from scratch. It is impossible to use graphic controls that the OS provides – particularly Win32 controls - buttons, simple text editors, labels, combo boxes list and tree view controls etc.
-FreshGUI is not aimed to use all complex GUI system of the target OS. At first time, the goal of FreshGUI is to provide minimal but decent functionality that will do the job – writing portable applications in assembly language.
-The graphics library provides procedures that draw graphics images and text on the screen. The library is OS dependent and is placed in the directory "graphics" in the root directory of FreshLib. The main conception of this library is ".raster" - represented by handle, object where the drawing happens. The exact meaning for this object is different for the different OS – in Win32 it is named "device context", in Linux it is "drawable" - window or pixmap.
- -This library contains event codes and data structures for FreshGUI OS independent events. For now only several events are defined:
--seMouseMove -seMouseEnter -seMouseLeave -seMouseBtnPress -seMouseBtnRelease -seMouseBtnClick -seMouseBtnDblClick - -seTimer - -seKbdKeyPress -seKbdKeyRelease -seKbdStatusChanged -seKbdChar - -sePaint --
These events cover mouse, keyboard, timers and paint events.
-Every event have some arguments that have to be sent to the recipient event handler. The event code and the event arguments are contained in data structure, defined for every kind of events.
-The first dword of the event structure is the field .event that contains the event code.
-Here are the structures defined in sysevents.asm
--struct TSysEvent - .event dd ? -ends --
The base event structure.
- --struct TMouseMoveEvent - . TSysEvent - .x dd ? - .y dd ? -ends --
The event is generated when the mouse cursor moves over some window or control. .x and .y contains the coordinates of the mouse cursor relative to the control this message is sent to.
- -- struct TMouseButtonEvent - . TSysEvent - .Button dd ? - .kbdStatus dd ? -ends --
This event is generated when some of the mouse buttons changes its state. The button that changes its state is specified in the field .Button
-This field can accept following values:
-mbLeft | = 0 |
mbMiddle | = 1 |
mbRight | = 2 |
The field .kbdStatus contains the status of remaining mouse buttons and keyboard modifying buttons. These buttons are represented by bits in the field:
-maskBtnLeft | = $01 |
maskBtnMiddle | = $02 |
maskBtnRight | = $04 |
maskCtrl | = $08 |
maskShift | = $10 |
-struct TMouseEnterEvent - . TSysEvent -ends --
This event is generated when the mouse cursor enters or leaves some control. There is no additional parameters besides the event code.
- --struct TKeyboardEvent - . TSysEvent - .key dd ? - .kbdStatus dd ? -ends --
This event is generated on keyboard button press/release. The field .key contains the code of the pressed button. .kbdStatus have the same meaning and the same values as in TMouseButtonEvent.
- --struct TTimerEvent - . TSysEvent -ends --
TTimerEvent is generated on timer events. :)
- --struct TPaintEvent - . TSysEvent - .raster dd ? ; ID of the raster where you should paint. - .rect RECT -ends --
TPaintEvent is generated when given control have to be repainted. The field .raster contains the handle to the graphic surface where the program have to draw. This handle have different meanings in the different target OS, but it simply need to be understandable by the graphics procedures from the OS dependent library graphics.asm.
-The field .rect is the rectangle of the control that needs to be repainted.
- -This procedure is the main program loop of the GUI application.
-The procedure Run process all pending system events, then calls once the OnIdle event handler of the application object and then sleeps until new events are sent by the OS.
-When the OS terminates the application – the procedure returns an exit code.
-The user uses this procedure following way:
-- stdcall Run - jmp ExitApplication -- -
This procedure process the events generated by the OS. If there are waiting events in the queue, the procedure reads them, translates them to FreshGUI event data structures and calls the event handlers of the respective controls.
-If there is no pending events in the queue, ProcessSystemEvents ends with CF=0
-The second task this procedure serves is to detect the end of the application. In this case it ends with CF=1.
-This procedure is call from the main event loop of the application. Also, the user can periodically call this procedure in order to not allow hanging of the user interface during long processing of some data.
- -This procedure waits until some system message is posted to the application event queue. Then it exits. During the wait, very low CPU power is consumed by the application.
- -It provides all finalization tasks and ends the application. The exit code is provided in EAX.
- -The template engine provides creation of complex window structures with tree layout from memory data structure, called template. The templates makes creation of dialog windows containing children windows and non visual objects.
-Templates can be visually created and edited. The template format used by FreshLib is flexible and allows all parameters and fields of the objects to be set to needed values during creation of the window.
-The template engine is located in the file ObjTemplates.asm
- -The template is consisted from one or more data structures of type TObjTemplate, defined following way:
--struct TObjTemplate - .flags dd ? - .class dd ? - .ptrVar dd ? - .paramsize dd ? - .params: -ends --
.flags – controls what is the place of the object in the whole tree structure.
-Can accept one or both of the following values, combined with OR:
-tfChild | =0 | means the object is child of the last object with tfParent set. |
tfParent | =1 | means the given object is parent and there will be next TObjTemplate structure that will be a child object. |
tfEnd | =2 | means the given object is the last child of its parent. Note, that one object can be parent and child in the same time. If the current template is at root level – the processing of template stops, after creating the current element and all its children. |
.class – pointer to TObjectClass data structure for the created object.
-.ptrVar – pointer to dword variable that to accept the pointer to the created object.
-.paramsize – the size of the additional data to the end of the template. Note, that TObjTemplate is variable length structure, not fixed. sizeof.TObjTemplate contains the size of the header part of the structure.
-.params: after the header fields there can be arbitrary count of dword pairs: (paramID, Value) that to be set the the object during creation. This sequence ends with dword $FFFFFF (-1) value for paramID.
- -Easy creation of templates is provided with macro ObjTemplate:
--macro ObjTemplate flags, class, name, [id, param] --
This macro allows use of string values for params and computes automatically the values for TObjTemplate.paramsize
-flags – set of (tfParent, tfEnd) constants.
-class – the base name of the object class (without prefix C) – i.e. Form, Window, Button, etc.
-name – label of the variable to receive the pointer to the created object.
-id – parameter ID or offset in the object structure.
-param – value of the parameter. Can be dword number or string constant. In the case the parameter value is string, it will be automatically created in the memory and the pointer to this string will be placed as a param value.
-One simple example of template structure:
--ObjTemplate tfParent or tfEnd, Form, frmMain, \ - visible, TRUE, \ - x, 100, \ - y, 50, \ - width, 640, \ - height, 480, \ - caption, 'Fresh portable Win32/Linux application test.' - - ObjTemplate tfChild, Button, btnChild1, \ - visible, TRUE, \ - x, 64, \ - y, 48, \ - width, 64, \ - height, 24, \ - caption, 'Button1', \ - OnClick, Button1Click - - ObjTemplate tfChild or tfEnd, Button, btnChild2, \ - x, 136, \ - y, 48, \ - width, 64, \ - height, 24, \ - caption, 'Button2' ,\ - visible, TRUE -- -
Actually the procedure is one:
--proc CreateFromTemplate, .ptrTemplate, .parent -- -
This procedure creates all objects from the template, pointed by [.ptrTemplate] as a parent of [.parent] argument.
-.ptrTemplate points to TObjTemplate structure.
-.parent points to TObject descendant structure. In most cases it will be actually descendant of TWindow or NULL if the created object is not a child of any window.
-Returns: EBX contains a pointer to the topmost of the created object (it is first of the created objects)
-All pointers of the objects are stored in the specified in the template variables ( i.e. [TObjTemplate.ptrVar])
-This directory contains only one macro library: "executable.inc"
-This library defines the macros that are going to be used for creating the main structure of the program. These macros are OS dependent as long as the type of the executable file is OS dependent: PE for Win32 and ELF for Linux.
-Every one of the macros from this library should be used only once in the program.
- -This macro library contains:
-macro _BinaryType type-
This macro sets the type of the executable. The argument type can accept one of the following values: GUI, console or DLL.
-This macro defines also the entry label of the program. This label is fixed to start:
-For example, following code will tell the compiler to compile the program as a GUI application:
--include 'compiler/executable.inc' -_BinaryType GUI -- -
macro _CodeSection-
This macro defines the section where the code of the program to be placed.
-Actually this section is the main section of the project. Here should be included all used libraries and other project files.
- -macro _DataSection- -
This macro defines the section where the data of the program to be placed. The common way to use this section is to use inside the macro IncludeAllGlobals that will allow you to use data defining macros from every place inside the source and leave the compiler to order this data properly for you.
-For details on using global data definition macros see: _globals.inc
- -macro _ImportSection-
This macro defines the section where to be inserted the list with functions dynamically imported from external libraries.
-Usually you only have to include here the library "allimports.asm" and the compiler will import for you only those functions that are used in the project.
-
- FreshLib:Data: - Arrays - Strings - |
This directory contains data handling routines and useful data structures. Actually it contains two abstract data structures: Arrays and Strings.
-Current implementation is fully portable: it does not contain any OS dependent code.
-The FreshLib Arrays data structure handles dynamic arrays that contain elements of arbitrary size.
-The following structure represents the header of the array. The actual array will have arbitrary size, depending on the element count and size.
--struct TArray - .count dd ? - .capacity dd ? - .itemsize dd ? - .lparam dd ? - label .array dword -ends -- -
The first element of the array begins on offset TArray.array from the begining of the memory block.
-The field TArray.count contains the current element count of the array.
-The field TArray.capacity contains the current capacity of the array. It is because the library usually allocates more memory than is needed for the array element count. This approach reduces memory allocations and reallocations and thus increases the speed of inserting and deleting elements in the array. How many memory will be allocated depends on the user setting of the variable ResizeIt (defined in memory.asm). This variable contains a pointer to the procedure that simply increases the value of ECX to the next suitable value.
-The field TArray.itemsize contains the size in bytes of one array element. Changing of this value is not recommended.
-The field TArray.lparam is for user defined parameter, associated with the array.
- --proc CreateArray, .itemSize --
This procedure creates new array with item size [.ItemSize]
-The procedure returns CF=0 if the array is properly created and pointer to the array is placed in EAX.
-In case the memory cannot be allocated, the procedure returns CF=1.
-The array must be freed after use. There is no special procedure for array free. Use FreeMem procedure to free array memory after use.
- --proc AddArrayItems, .ptrArray, .count --
This procedure adds new array items at the end of the array pointed by [.ptrArray]
-The procedure returns two values:
-EAX contains pointer to the first of the new appended elements.
-EDX contains pointer to the array (in the process of appending of the new element, it is possible the whole array to be moved to the new address in memory, so the programmer should store the value of EDX for the future reference to the array.
-In case, the new memory can not be allocated, the procedure returns CF=1 and EDX contains the proper pointer to the original array.
- --proc InsertArrayItems, .ptrArray, .iElement, .count --
This procedure inserts [.count] new elements at the [.iElement] position of the array pointed by [.ptrArray]
-If [.iElement] is larger or equal to [TArray.count] the elements are appended at the end of the array. (Just like AddArrayItems) Otherwise, all elements are moved to make room for the new elements.
-The procedure returns exactly the same results as AddArrayItems procedure EDX points to the array and EAX points to the first of the new inserted elements.
-CF is error flag.
- --proc DeleteArrayItems, .ptrArray, .iElement, .count --
This procedure deletes [.count] items with begin index [.iElement] the [.ptrArray] dynamic array. If the capacity of the array is bigger than the recommended for the new count, then the array is resized. The recommended size is calculated using ResizeIt procedure from memory library.
-Returns EDX - pointer to the TArray. In the most cases this pointer will not be changed, but this also depends on the current OS memory allocation API, so it is safer to store the pointer for future use, instead of one passed to the procedure.
-This procedure can not fail, because deleting element is always possible. In some rare cases it can fail to reallocate smaller memory block, but this is not a problem for the array consistency.
- --proc VacuumArray, .ptrArray --
This procedure removes the reserved memory from the array in order to make it as small as possible. This operation should be executed only if there will be no more inserts in the array. The memory economized this way depends on reallocation strategy and can be from 25 to 100% in some cases.
- --proc ListIndexOf, .ptrList, .Item --
The list is a special case of array with item size equal to 4 bytes (dword). This procedure searches the list [.ptrList] for item equal to [.Item] and returns the index of the element in EAX. In case of error CF=1.
- --proc ListFree, .ptrList, .FreeProc --
Frees all elements of the list [.ptrList], calling [.FreeProc] for every element of the list.
-FreeProc callback procedure have one argument of type dword that is the value of the current list element. The definition of the callback procedure is similar to following:
--proc FreeMyListItem, .ptrItem -begin - ;do something with the item being freed - return -endp -- -
Using strings in assembler was often problematic for programmers - static strings can't be resized, so they had to reserve as many bytes as they thought user could need, and it still could be not enough. Thus we created StrLib - a library that operates on dynamic strings, that are automatically resized when needed. Also, StrLib contains many functions that perform string comparison, inserting one string into another, and more. And most of this functions can operate on static strings too. StrLib uses "memory.asm" library for memory allocations and does not contains any OS dependent code.
-FreshLib Strings uses FreshLib Arrays to handle the list with pointers to allocated string memory.
- -The strings used in StrLib are implemented using a specific structure, compatible but not equal to AsciiZ, used by Windows API. The string structure is defined in the following way:
--struc string { - .capacity dd ? - .len dd ? - label .data byte -} - -virtual at -(sizeof.string) - string string - sizeof.string = $-string -end virtual -- -
The string data is placed on offset 0 to the pointer of the string. Its label is "string.data". The string data always is terminated by at least one zero byte and the length of the memory buffer is always dword aligned. -It is safe to process the string data by dword instructions.
-On offset [string-4] is located a dword field, that contains the length of the string data, not including the terminating zero bytes.
-On offset [string-8] is located a dword with the capacity of the memory allocated for the string.
-These fields are accessible by its symbolic names: string.len and string.capacity; This fields are for internal use only it is not safe for the user to change the values of these fields.
-Using special field that to keep the length of the string makes some of the string operations extremely fast, because searching for the terminating zero is very slow operation.
-All procedures in StrLib compute the proper value for [.len] field and never search for the terminating zeros, except for the AsciiZ strings that are external towards StrLib those returned from the OS API functions or by string constants in memory.
- -The string in StrLib is identified not with its pointer, but by a handle. While the pointer can be changed when the string memory is reallocated, the handle is always a constant for the whole life cycle of the string.
-There is a procedure that extracts the current pointer of the string by its handle.
-Because handle values never collides with memory addresses, almost all StrLib procedures can work with handles and with memory pointers at the same time.
-For the strings passed to the procedures with memory pointer, StrLib assumes they are static strings from memory, or returned from the OS.
-Because of this assumption, StrLib process these strings safely and slowly scans the string to determine the length, assumes it is byte aligned etc. In other words it process it as a standard AsciiZ string.
- -proc StrNew-
Creates new string and returns handle in EAX.
- -proc StrPtr, .hString-
Returns the current pointer to the string with handle [.hString].
-If [.hString] looks like a valid handle, but it is not found in the strings table, the procedure returns CF=1.
- -proc StrDel, .hString-
Deletes the string with handle [.hString] and frees all allocated memory. If [.hString] is a pointer, it tries to search the strings table for the given handle and deletes it.
-If a string is not found, the procedure does not return an error.
- -proc StrDup, .hSource-
Creates a duplicate of the string .hSource. Returns a handle to the new created string in EAX.
- -proc StrLen, .hString-
Returns the length of the string [.hString]. If the handle is valid, it returns the value of the field [string.len]. If [.hString] is a pointer, it computes the length by scanning the string up to the zero terminator.
- -proc StrFixLen, .hString-
This procedure scans the length of zero terminated string and "fixes" [string.len] field. StrFixLen should be call when the content of the string is created by an external call, for example a Win32 API function.
- -proc StrSetCapacity, .hString, .capacity-
If the capacity of [.hString] is larger than the requested capacity it does nothing.
-If the capacity of [.hString] is smaller than the requested capacity, it sets the capacity of the string to the requested value.
-Returns a pointer to the string after reallocation in EAX.
-.hString is a handle to the string that have to be resized. Pointers are not acceptable here.
-.capacity contains requested capacity for the string.
-If returns CF=1 the reallocation failed. EAX still contains the pointer to the string, but the string was not resized.
- -proc StrCopy, .dest, .source-
Copies the content of [.source] string to [.destination] string.
- -proc StrCompCase, .str1, .str2-
Compares the content of two strings [.str1] and [.str2] case sensitive.
-Returns:
-CF=1 if the strings are EQUAL.
-CF=0 if the strings are NOT equal.
- -proc StrCompNoCase, .str1, .str2-
Compares the content of two strings [.str1] and [.str2] case NOT sensitive.
-Returns:
-CF=1 if the strings are EQUAL
-CF=0 if the strings are NOT equal.
- -proc SetString, .ptrHString, .ptrSource-
Creates string and assigns it to variable. If the variable already contains string handle, the old string will be reused. Copies the content of [.ptrSource] to the string variable.
-Arguments:
-.ptrHString pointer to the variable that contains string handle.
-.ptrSource pointer to the source for string.
- -proc StrCat, .dest, .source-
Concatenates two strings. The operation is: destination = destination + source.
-The destination string [.dest] can be only handle. [.source] can be handle or pointer.
- -proc StrCharPos, .hString, .char-
StrCharPos returns a pointer to the first occurrence of a given char in specified string.
-Arguments:
-.hString - string to search
-.char - char to look for
-Returns:
-A pointer to the char in source, or NULL if char doesn't occur in the given string.
- -proc StrPos, .hString, .hPattern-
StrPos returns a pointer to the first occurrence of a .hPattern string in .hString. -
Arguments:
-hPattern - 'pattern' string
-hString - string to search
-Returns:
-Pointer to the pattern string in source, or NULL if pattern string doesn't occur in the string to search.
- -proc StrCopyPart, .dest, .source, .pos, .len-
Copies part of the source string to the destination string.
-Arguments:
-.dest handle to destination string.
-.source handle or pointer to the source string.
-.pos Source part start position.
-.len length of the copied part.
-Returns nothing.
- -proc StrExtract, .string, .pos, .len-
The same as StrCopyPart, but creates and returns new string with extracted part of the source [.string]
-Returns the new created string in EAX.
- -proc StrSplit, .hString, .pos-
Splits the string on two strings, at position [.pos]
-Arguments: -
.hString handle of the string to be split.
-.pos - position where to split the string.
-Returns: -
EAX - handle to the new created string with second part of the string. The original string does not reallocate memory and it's capacity and the pointer will remains the same.
- -proc StrInsert, .dest, .source, .pos-
Inserts the string [.source] into the string [.dest] at position [.pos]
- -proc StrLCase, .hString-
Converts [.hString] to lower case.
- - -proc StrUCase, .hString-
Converts [.hString] to upper case.
- -proc NumToStr, .num, .flags-
Converts the given number to a string representing it.
-[.flags] controls how the number to be converted.
-The procedure returns a handle to the string in EAX and direct pointer to the string in EAX.
-The [.flags] is a dword with following format:
-The LSB contains the number of digits, the number must have, if ntsFixedWidth flag is specified.
-Second byte of [.flags] contains the radix that to be used for conversion.
-The third and the fourth bytes are reserved for bit flags.
-Following constants are predefined in StrLib in order to set the value for [.flags]:
-ntsSigned | converts number in signed format. | $00000 |
ntsUnsigned | converts number in unsigned format. | $10000 |
ntsFixedWidth | the count of the digits is fixed. | $20000 |
ntsBin | for binary number | $0200 |
ntsQuad | for quad number | $0400 |
ntsOct | for octal number | $0800 |
ntsDec | for decimal number | $0a00 |
ntsHex | for hexadecimal number | $1000 |
Example:
-stdcall NumToStr,EAX, ntsDec or ntsFixedWidth or 8
-This example will convert the number in EAX to a signed decimal number with exactly 8 digits. If EAX contains $00000080, the result string will be '00000128'.
- -proc StrCharCat, .hString, .char-
This procedure appends up to 4 characters at the end of the string [.hString]. The characters are contained in the dword argument [.char]
- -proc StrCharInsert, .hString, .char, .pos-
Inserts up to 4 characters [.char] at position [.pos] in the string [.hString]
- -proc StrHash, .hString-
Computes 32 bit hash value from the string [.hString]. This procedure implements the hash algorithm FNV-1b. Returns the result in EAX.
-This directory contains the equates library "allequates.inc". This library defines all constants and structures needed for OS dependent parts of FreshLib.
-The user should never use these constants and structures in the portable program.
-
- Home:FreshLib: - compiler - data - equates - graphics - GUI - imports - macros - simpledebug - system - |
FreshLib is an assembly library aimed to ease the development of rapid assembly language applications, freely portable between different platforms, such as Win32 or Linux.
-The library is coded in flat assembler syntax (fasm) and is intended to be easily used within Fresh IDE although it could be used for plain fasm development.
- -The library consists of two layers: one that is OS dependent and a second one that is OS independent. The OS dependent layer is very small, in order to help porting it for different OS. This layer only makes interface to the core OS functions, such as memory allocations, file access, drawing functions, simple window management etc.
- -The OS independent layer is responsible for the main application functionality allowing creation of different kind of windows and controls, user interaction with the program and interaction between particular windows and other GUI elements.
-FreshLib is mainly intended for developing GUI applications, as they are the most challenging to be ported across different platforms. FreshLib is also created with visual programming in mind, so it contains a flexible, event driven and OS independent template engine allowing visual creation of application user interfaces.
-FreshLib is in early development stage and probably will be changed many times in order to reach their objectives: to be small, fast and easy to use.
- -The main intention is to keep the bloat off the library, but containing all necessary accessories for comfortable programming of a very wide range of applications.
- -The architecture of FreshLib is open and it can be freely expanded with other libraries without increasing the size of applications. In other words, only those parts of the library that are effectively used will be compiled on the final executable.
- -This manual is a "work in progress". Any part of it can be changed at any time.
-Of course, some of the libraries described in this document are more stable and finished like the macro, system and data libraries. Therefore, the chapters about these libraries are less likely to be changed. Other libraries (like graphics and GUI), will be heavily modified so the manual will be changed accordingly.
- -FreshLib contains many code and macros libraries, structured hierarchically and depending on each other. Here is the directory tree of the library:
- -The library is structured to support different platforms transparently. The platform dependient code is contained in a subdirectory of each library component. For example, "system" subdirectory contains libraries for accessing system resources such as memory, files, etc. Inside "system" there several subdirectories that contain OS dependent code these directories are named after the platform they serve.
-Currently, only Win32 and Linux platforms are supported.
-FreshLib main scope is to provide a fast and easy framework to start programming multiplatform assembly applications. Now, what is needed to start writing applications?
-Another directory that contains only OS dependent definitions is "imports" with a library file to be included in the project: "allimports.asm"
-This file have to be included in the _IncludeSection of the application. Then it will generate the proper import section, depending on the target platform and functions used by the OS dependent parts of FreshLib.
-The user should never call directly imported functions from inside the portable application.
-
- Index |
Fresh is a visual assembly language IDE with built-in FASM assembler. -
- -The main goal of Fresh is to make programming in assembly as fast and -efficient as in other visual languages, without sacrificing the small -application size and the raw power of assembly language. -
- -Because Fresh is the logical continuation of the FASM project in the -area of visual programming, it is perfectly compatible with FASM and you -can use all your knowledge about FASM to program in Fresh. -
- -Of course, you can use Fresh not only for Windows programming, but also -to create programs for any OS that FASM supports - DOS, Linux, FreeBSD, -BeOS, MenuetOS - the same way as you do this in FASM. -
- -This site is fossil repository of Fresh sources. -You can clone the repository with following fossil command: -
fossil clone http://chiselapp.com/user/johnfound/repository/FreshIDE/ Fresh.fossil- - -
In order to use more functionality in this site, please login as "anonimous" user. -Particularly you will be able to follow the links in the source tree, to download code and to fill bug reports and feature requests. -
- -If you want to contribute to the project, please contact me (johnfound) on FASM message board -
- -In order to download compiled FreshIDE, visit Fresh IDE home page. -
- -You can report bugs, or make some feature requests here, in the Tickets system -
-
- FreshLib:Macros: - _stdcall.inc - _globals.inc - _struct.inc - _display.inc - |
This directory contains several libraries that provides common convenience functions to be used with big assembly projects. All libraries can be included in the project at once from the file "allmacros.inc".
-There is no overhead at including all those libraries because there is no code to be generated, just macros. There is a little delay in compile time but thanks to fasm's speed, it is barely noticeable.
-Lets examine each one of these libraries.
-In general this library provides ways of definition and invoking of the procedures with argument passing through the stack. It supports STDCALL and CCALL calling conventions.
--macro proc name, [arg] -macro begin -macro endp -macro return -macro cret -macro locals -macro endl --
These macros define a procedure, creates a stack frame for the local variables and defines symbolic names for the arguments. The macro "proc" defines the global label "name" as a name for the procedure. All arguments and local variables are defined as a local labels with regard to the name of the procedure. That is why all arguments and local variables must have names beginning with dot.
-Between the line with "proc" and "begin", any number of local variables can be defined. The macro "begin" marks the begining of the procedural code.
-The macro "endp" marks the end of the procedural code.
-The return from procedure instruction is provided by macros "return" or "cret" depending on the calling convention we want to use: "return" clears the arguments from the stack and "cret" do not.
-Inside the procedure, a secondary stack frame can be allocated with the pair "locals" and "endl". All data definitions, enclosed between these macros will define a secondary stack frame that is a continuation of the stack frame defined between "proc" and "begin".
- -Any number of "locals" and "endl" pairs can be used, but all of these secondary stack frames will overlap between each other. This feature is specially intended to provide savings of stack space and at the same time, to provide talking variable names for the different parts of more complex procedures.
-For example (in Win32) if we have complex window procedure that have to process multiple messages: One of the message handlers may need one variable .rect. Another message handler may need two variables called .point1 and .point2. But the procedure as a whole is never going to need all those variables at the same time, because it process only one message at a time. On the other hand it may need the variable .ctrldata for every message processed. The optimal solution is to define the variables in the following way:
--proc CtrlWinProc,.hwnd,.wmsg,.wparam,.lparam -.ctrldata dd ? -begin - invoke GetWindowLong, [.hwnd], GWL_USERDATA - mov [.ctrldata], eax - - cmp [.wmsg], WM_MESSAGE1 - je .message1 - cmp [.wmsg], WM_MESSAGE2 - je .message2 - return - -.message1: -locals - .rect RECT -endl - return - -.message2: -locals - .point1 POINT - .point2 POINT -endl - return -endp --
In the above example, .ctrldata is defined on [EBP-4]; .rect is defined on [EBP-20]; .point1 is also defined on [EBP-20] and .point2 is defined on [EBP-12].
-
[EBP-04] | .ctrldata | |
[EBP-08] | .rect.bottom | .point2.y |
[EBP-12] | .rect.right | .point2.x |
[EBP-16] | .rect.top | .point1.y |
[EBP-20] | .rect.left | .point1.x |
As you can see, .rect occupies the same memory as .point1 and .point2, but .ctrldata is never overlapped and exists independently.
-
As a general rule, you have to use the definitions between "proc" and "begin" for local variables that are used in every call of the procedure and separate locals/endl definitions for variables needed for the particular branches inside the procedure.
-
This approach will always provide the optimal size for the locals stack frame.
- --macro initialize -macro finalize --
The macros "initialize" and "finalize" defines one special type of procedures that during compilation are registered in a two separate lists - one for "initialize" and one for "finalize" procedures.
-After that using the macros "InitializeAll" and "FinalizeAll", all these procedures can be call at once. "initialize" procedures are call in the order of their definition and "finalize" procedures in reverse order.
-These macros provides standard and consistent way to process the initialization and the finalization of the libraries and modules of the application.
-Procedures defined with "initialize" and "finalize" must have no any arguments.
-FreshLib uses this mechanism and the user is free to use it also. -
-macro stdcall proc, [arg] -macro ccall proc, [arg] -macro invoke proc, [arg] -macro cinvoke proc, [arg] --
This macros call the procedures with STDCALL and CCALL calling convention.
-"stdcall" macro pushes the arguments to the stack in reverse order and then call the procedure with label "proc". As long as the macro "stdcall" does not provide any stack cleanup (this duty is assigned to the procedure) the arguments can be pushed in free manner using, for example, separate push instructions for part of the arguments and arguments in the stdcall line for the remaining arguments. This can be very convenient in some cases. For example see the following source:
-- stdcall CreateSomeObject - push eax - stdcall DoSomething - stdcall DeleteSomeObject --
Here, the procedure DoSomething changes the value of eax, so the handle is saved in the stack. The procedure DeleteSomeObject needs one argument - a handle of the object. But as long as the proper value is already in the stack, it is mindless to pop the value and then to push it again. So the source calls DeleteSomeObject without any arguments. The procedure knows the proper number of arguments (one in this example) and clean the stack properly.
-The standard (and wrong) approach is to pop the argument from the stack and then to pass it to the procedure explicitly is the stdcall statement:
-- stdcall CreateSomeObject - push eax ; save the handle. - stdcall DoSomething - pop eax ; ??? Why ??? - stdcall DeleteSomeObject, eax --
This source will generate the meaningless instructions sequence:
-- pop eax - push eax --
"invoke" macro is the same as "stdcall" with the only difference - it calls the procedure indirectly (call [proc] instead of call proc).
-This mechanism is used to call the functions imported from external dynamic linked libraries.
-"ccall" macro calls a procedure with CCALL convention. This means that the procedure returns with simple "retn", without cleaning the parameters from the stack. Then "ccall" macro provides instructions that remove the arguments from the stack.
-Because ccall have to know the exact count of passed arguments, all arguments have to be passed explicitly as a values in the ccall statement.
-Tricks as described above will not work properly and leads to stack not properly cleaned after the call.
-"cinvoke" is the same as ccall, but using indirect call. The reason is the same as with "invoke" macro.
-About the calling conventions: While all Win32 dynamic linked libraries uses STDCALL convention, most (if not all) of Linux libraries uses CCALL convention.
-All code libraries of Fresh use STDCALL calling convention and it is platform independient.
This library defines several macros intended to deal with data definitions.
-Usually all data definitions have to be placed in special section of the executable file. This is not very convenient, because the code that process this data and the data definitions must reside in separate places of the source code, and in most cases even in different files.
-The idea of globals.inc macro library is to allow the data definition to be described anywhere in the source code, but these definitions to be defined at once, at the place the programmer wants - usually in the data section of the program.
--macro uglobal -macro iglobal -macro endg -macro IncludeAllGlobals --
"uglobal" begins block for undefined data definition. The block ends with "endg" macro. Between "uglobal" and "endg" macro any count of data definitions can be inserted.
-Note that because uglobal block defines undefined data, it is only the labels and the size of data that have meaning inside this block. Any data defined with data definition directive will not be included in the binary file.
-The undefined data will be defined later at the place where "IncludeAllGlobals" macro resides.
-The undefined data is always placed at the end of all data definitions, so it will never increase the size of the executable file.
- -"iglobal" macro, again combined with "endg" defines initialized data. The data defined in the block will be created at "IncludeAllGlobals" statement.
-This block increases the size of the executable file, because it contains sensible data, that have to be included in the file.
-Actually, neither uglobal, nor iglobal blocks defines any data immediately.
-Instead, the data definitions are stored in a list. The real definition occurs later, when IncludeAllGlobals macro is invoked.
-For this reason, IncludeAllGlobals must be placed in the source after all used global data blocks.
- -struc text [val]- -
The macro "text" is actually a structure. It needs to be preceded by some label name.
-This macro defines a zero terminated string constant, and also a local label for this string in the "sizeof" global label.
-The "text" macro, similar to iglobal and uglobal simply stores string data for defer definition.
-This definition, as for all global data macros, occur in IncludeAllGlobals invocation.
-Why to define separate macro for the strings and not to use the normal iglobal block? The thing is that the macro "text" was planned to check the strings and to not define any string more than once. In the case of repetitive strings, this macro should return the pointer to the already defined string constant.
-In that case, it would be very convenient and harmless to use string constants in the function calling macros - stdcall, ccall etc.
-Unfortunately, regardless of the power of fasm macro language, this functionality cannot be implemented. Or, more precisely, it can be implemented, but the implementation is too slow for any real project use.
-This ineffective implementation is still leaved inside the file _globals.inc - commented block that defines macro with name "InitStringList". If someone have ideas about fixing this problem, please send it to me!
This library contains only one simple macro:
- --macro struct name -ends --
This macro is aimed to provide easy creation of data structures. The "struc" directive in FASM is known to not create actual labels, but only the template for the label definitions. So, we need to create an instance of the data structure in order to have addresses and offsets of its fields.
-But very often we don't have static data structure of the given type, but data structure, pointed by some of the registers. In this case in order to use offsets to the fields of the data structure, we need to define at least one virtual instance of the structure at address 0. Then we can use the values of the fields as an offsets in the instructions - for example: mov eax, [esi+RECT.right].
-So, this is exactly what "struct" macro does. Besides it defines the "struc" structure with the given fields, it creates a single virtual instance of this structure, in order to be used later for register addressing. In all remaining functionality it behaves exactly as the struc directive.
-The syntax of struct macro is the following:
--struct StructureName - .field1 dd ? - .field2 RECT - .fieldN: -ends --
The definition begins with "struct" followed by the structure name. The definition ends with "ends" directive. Between both, any local label definition becomes a member of the structure.
- -This library contains macros that enhance the functionality of standard FASM "display" directive.
- -macro disp [arg]-
The macro "disp" displays the strings given in the arguments, just as "display" FASM directive does
-disp <number, radix>-
The macro here is used to display numbers in any radix.
- -macro DispSize Text, Sz-
"DispSize" macro is very specialized macro, that displays the text and number in the following form:
- -Size of [Text] is: Sz bytes- -
The size number is automatically scaled to bytes or kbytes, depending on the value of Sz.
-This macro allows easy display and control of the sizes of particular areas of the program - data structures, subroutines etc.
- -There are some specifics in Fresh, concerning message displaying. The "display" directive in Fresh works in a different way than original FASM directive. It outputs text in Fresh message window. Each message can have one of six icons, or it can have no icon at all. And because message window is implemented as a TreeView control, you can organize your messages into groups (directories). Implementation is a bit "tricky" - when you display a character whose code is less than 16, it is interpreted in a special way. Characters from 1 to 6 set an icon of current message. It sounds complicated, but it is quite simple. Try:
-- display 2, "some message" --
It will display "some message" with an error icon. Another codes are used for controlling directory structure. Try to type following lines and see what would happen:
-- display 3, "message at root", 0x09 - display 3, "child message1", 0x0a - display 3, "child message2", 0x0d - display 3, "again at root", 0x0a --
Of course you don't have to put each message in separate display directive, you can, with the same result write:
--display 3, "at root",$09,3,"child1",$0a,3,"child2", $0d,3,"again at root",$0a --
Here is the complete list of all special characters and their meanings:
-$01 | set current icon to "warning" |
$02 | set current icon to "error" |
$03 | set current icon to "info" |
$04 | set current icon to "find" |
$05 | set current icon to "none" |
$06 | set current icon to "debug" |
$08 | end current row and set one level back. |
$09 | end current row and set it as new directory. |
$0a | end current row and keep current level |
$0d | end current row and set current level to root level |
This directory contains debugging utilities.
-The first thing to do is to download fasm in your platform of choice. - Fasm does not require installation nor do you need special administrative privileges or a root account in order to start using it.
-The second thing is to get a copy of FreshLib. FreshLib is just fasm source code, simply save it in a directory of choice.
-FreshLib needs an environment variable called TargetOS -in order to know the target platform of the generated application. - Currently, the allowed values are: Win32 and Linux.
-A second environment variable is suggested called lib having the full path to FreshLib. The library does not need this, but it will make your own sources more portable.
-From Linux:
--export TargetOS=Linux -export lib=/home/test/freshlib --
From Windows:
--set TargetOS=Win32 -set lib=c:\projects\freshlib -- -
That's all. Now it is time to produce the first FreshLib application using just Fasm.
- --include '%lib%/compiler/executable.inc' -include '%lib%/macros/allmacros.inc' -include '%lib%/equates/allequates.inc' - -_BinaryType console - -include '%lib%/system/process.asm' -include '%lib%/simpledebug/debug.asm' - -_CodeSection - -start: - - InitializeAll - - DebugMsg 'Hello world!' - - FinalizeAll - call Terminate - -_ImportSection - -include '%lib%/imports/allimports.asm' - -_DataSection - -IncludeAllGlobals -- -
The most important thing to note is that regardless the platform you have chosen, the code is exactly the same. -In other words, if you change the value of your environment variable TargetOS, -the same code will produce a different executable file targeting that platform. -This is the main characteristic of the FreshLib and this is the first design criteria that you will -want to follow to have a truly platform independent application.
- -This is a highly portable development environment, perhaps the most portable -among non interpreted languages. The entire development process could run from removable media -and the same set of source code files could be used from Win32 and Linux to produce binaries for either of them.
- --include '%lib%/compiler/executable.inc' -include '%lib%/macros/allmacros.inc' -include '%lib%/equates/allequates.inc' - -_BinaryType console - -include '%lib%/simpledebug/debug.asm' -include '%lib%/system/files.asm' -include '%lib%/system/process.asm' - -_CodeSection - -start: - - InitializeAll - - DebugMsg 'FreshLib Tutorials - Module: Files' - -iglobal - filename db './tut01.txt',0 - sizeof.filename = $-filename -endg - -uglobal - hFile dd ? -endg - - stdcall FileCreate, filename - jc .error - mov [hFile], eax - DebugMsg "A new file was created:" - stdcall OutputNumber, [hFile], 16, 2 - DebugMsg " is the handle of the file" - - stdcall FileWrite, [hFile], filename, sizeof.filename - jc .error - stdcall OutputNumber, eax, 10, 2 - DebugMsg " bytes were written into the file" - - stdcall FileClose, [hFile] - jc .error - DebugMsg "The file was properly closed" - - stdcall FileDelete, filename - jc .error - DebugMsg "The file was finally deleted" - jmp .exit - -.error: - DebugMsg "Sorry, an error occurred" - -.exit: - FinalizeAll - stdcall Terminate, 0 - -_ImportSection - -include '%lib%/imports/allimports.asm' - -_DataSection - -IncludeAllGlobals -- -
-- -
-- -
This directory contains two libraries: "memory.asm" and "files.asm". They constitute the interface to the overlaying system for the rest of the FreshLib modules.
-This library contains simple but pretty complete functions for dynamic memory allocation, reallocation and release.
-The Win32 implementation of the library uses the process heap, returned by GetProcessHeap to manage the memory allocations. Linux implementation uses libc functions: "malloc", "free" and "realloc".
- --proc GetMem, .size --
This procedure allocates dynamic memory block with size in bytes in the argument [.size]
-If there is no error the procedure returns CF=0 and pointer to the requested memory in EAX. If the memory cannot be allocated, the procedure returns CF=1
- --proc FreeMem, .ptr --
This procedure frees the memory block pointed by [.ptr] argument.
- --proc ResizeMem, .ptr, .newsize --
This procedure tries to resize the memory block pointed by [.ptr] to the new size, given by [.newsize] argument.
- - -This library provides simple file access procedures.
- --proc FileOpen, .filename --
This procedure opens the file with a filename in the string pointed by [.filename] argument.
-On success (CF=0) FileOpen returns a handle of the open file. On error (CF=1) returns error code.
- --proc FileCreate, .filename --
This procedure creates new empty file with a filename in the string pointed by [.filename] argument.
-On success (CF=0) FileCreate returns a handle of the open file. On error (CF=1) returns error code in EAX.
- --proc FileClose, .handle --
This procedure closes the open file with a handle in [.handle] argument.
-On success (CF=0) does not return any value and preserves EAX.
-On error (CF=1) returns error code in EAX.
- --proc FileRead, .handle, .buffer, .count --
This procedure reads [.count] bytes from the file [.handle] in the buffer pointed by [.buffer] arguments.
-On success (CF=0) returns the count of actually read bytes in EAX.
-On error (CF=1) returns error code in EAX.
- --proc FileWrite, .handle, .buffer, .count --
This procedure writes [.count] bytes from the buffer pointed by [.buffer] argument to the file [.handle] that have to be open for write.
-On success (CF=0) returns the count of actually read bytes in EAX.
-On error (CF=1) returns error code in EAX.
- --proc FileSeek, .handle, .dist, .direction --
This procedure moves the file pointer to the some position. The handle of the file is in [.handle], the target position is in [.dist] and the direction of the move is in [.direction] arguments.
-[.direction] accept one of the following values: fsFromBegin, fsFromEnd and fsFromCurrent.
-The exact values of these constants may vary between different OSes, so the programmer have to use the symbolic names, predefined in "files.asm" library.
-On success (CF=0) returns the new position of the file in EAX.
-On error (CF=1) returns error code in EAX.
- --proc FileDelete, .filename --
This procedure deletes a file with name in pointed by [.filename] argument.
-On success (CF=0) no value.
-On error (CF=1) returns error code in EAX.
- --proc GetErrorString, .code --
This procedure returns in EAX a pointer to a human readable error string for the error code passed in [.code]. The string is dynamically allocated by the OS and should be released after use with the procedure FreeErrorString.
- --proc FreeErrorString, .ptrString --
This procedure frees the memory allocated for error string from the procedure GetErrorString.
- --proc LoadBinaryFile, .ptrFileName --
This procedure allocates needed memory and loads the whole file with filename pointed by [.ptrFileName] to the allocated buffer.
-The memory is allocated with the library memory.asm, so the user have to free the memory after use with the procedure FreeMem. -
On success (CF=0) the procedure returns a pointer to the allocated memory in EAX and the count of bytes read in ECX.
-On error (CF=1) the procedure returns nothing.
- --proc SaveBinaryFile, .ptrFileName, .aptr, .size --
This procedure creates new file with the name pointed by [.ptrFileName] and saves [.size] bytes from the buffer pointed by [.aptr].
-The procedure returns error flag in CF.
- --proc FileExists, .ptrFileName --
This procedure checks whether the file with name pointed by [.ptrFileName] exists on disk.
-The procedure returns CF=0 if the file exists, otherwise it returnsCF=1.
-' - lea edi, [edi+1] - jmp .process_char - -.process_inline_code: - mov ecx, fstateInlineSource - mov ebx, 'code' - jmp .ProcessTag - -.process_bold: - mov ecx, fstateBold - mov ebx, 'b' - jmp .ProcessTag - - -.process_italic: - mov ecx, fstateItalic - mov ebx, 'i' - jmp .ProcessTag - -.process_underline: - mov ecx, fstateUnderline - mov ebx, 'u' - jmp .ProcessTag - -.process_strikeout: - mov ecx, fstateStrikeout - mov ebx, 's' - -; ecx = state mask -; ebx = html tag -.ProcessTag: - mov dl, al - - test [.state], ecx - jz .start_tag - -; close tag - not ecx - and [.state], ecx - - mov word [edi], '' - lea edi, [edi+2] - jmp .finish_tag - -.start_tag: - test [.state], fstateWhite - jz .normal_char - cmp byte [esi], $20 - je .normal_char - cmp byte [esi], $09 - je .normal_char - cmp byte [esi], $0d - je .normal_char - cmp byte [esi], $0a - je .normal_char - - or [.state], ecx - -; open tag - mov byte [edi], '<' - lea edi, [edi+1] - -.finish_tag: - mov [edi], ebx - -.taglen: - lea edi, [edi+1] - shr ebx, 8 - jnz .taglen - - mov byte [edi], '>' - lea edi, [edi+1] - - jmp .scan_line2 - - -.white_space: - test [.state], fstateWhite - jnz .scan_line2 - - or [.state], fstateWhite - mov [edi], al - lea edi, [edi+1] - jmp .scan_line2 - -; end of line and end of file processing -.end_of_line: - test al, al - jz @f - - xor al, $0d xor $0a - cmp [esi], al - jne @f - inc esi -@@: - or [.state], fstateWhite - - test [.state], fstateTextNow - jnz .para_ok - - call .close_paragraph - -.para_ok: - test [.state], fstateHeader - jz .crlf - -; insert back link - cmp [.fBacklinks], 0 - je .backlink_ok - - mov dword [edi], '' - mov dword [edi+2], '' - lea edi, [edi+6] - -.backlink_ok: - mov byte [edi], '<' - lea edi, [edi+1] - - mov ecx, [.last_header] - add ecx, '/h0>' - mov [edi], ecx - lea edi, [edi+4] - - and [.state], not (fstateHeader or fstateTextNow) ; For the paragraph flow, the header loops like empty line. - -.crlf: - test [.state], fstateTextPrev or fstateTextNow - jz @f - mov word [edi], $0a0d - lea edi, [edi+2] -@@: - test al, al - jnz .line_start2 - -.finish: - mov dword [edi], 0 - stdcall StrCat, [.result], [.pHTML] - retn - - -.is_link_begin: - test [.state], fstateWhite - jz .normal_char - -.searchID: - dec esi - -;.SearchLink: - push edi - push esi - -; first compute the hash for the link label - mov edx, $811C9DC5 ; 2166136261 ; FNV offset basis - -.hashloop: - mov al, [esi] - lea esi, [esi+1] - - cmp al, $20 - je .hashloop - cmp al, $09 - je .hashloop - - cmp al, $0d - je .not_a_link - cmp al, $0a - je .not_a_link - test al, al - je .not_a_link - - xor dl, al - imul edx, $01000193 ; 16777619 ; FNV prime - cmp al, ']' - jne .hashloop - -; fold the hash to 16 bit value... - mov [.linkID_end], esi - - mov ebx, edx - shr ebx, 16 - xor ebx, edx - dec ebx - -.hash_table_loop: - lea ebx, [ebx+1] - and ebx, $ffff - - mov eax, [.pHashTable] - mov edi, [eax+4*ebx] - mov esi, [esp] - - test edi, edi - jnz .cmp_labels - -.inline_link: ; the linkID was not found in the hash table. So, it should be inline link address. - lea edi, [esi+1] ; the address of the link is in esi - mov esi, [.linkID_end] ; the address of the end of the linkID. - jmp .create_link - -.not_a_link: - pop esi edi - mov al, [esi] - lea esi, [esi+1] - jmp .normal_char ; the link address was not found, so it is not link at all. - -.cmp_labels: - mov al, [esi] - lea esi, [esi+1] - - cmp al, ' ' - je .cmp_labels - cmp al, $09 - je .cmp_labels - -.target: - mov ah, [edi] - lea edi, [edi+1] - - cmp ah, ' ' - je .target - cmp ah, $09 - je .target - - cmp al, ah - jne .hash_table_loop ; it is not the same label - try again. - - cmp ah, ']' - jne .cmp_labels - -; the labels are equal, so search the address. - -.create_link: - or [.state], fstateLink - mov edx, [esp] ; the start of the linkID. - cmp byte [esi], '[' ; is the link has separate ID and text? - jne @f - mov [esp], esi ; replace the source address. -@@: - inc edx - cmp byte [edx], '#' ; is it internal link? - je .internal_link_address - - cmp byte [edx], '?' ; is it inline image? - jne .maybe_block_image - - xor [.state], fstateInlineImage or fstateLink - jmp .firstnw - -.maybe_block_image: - cmp byte [edx], '!' ; is it an image? - jne .firstnw - xor [.state], fstateImage or fstateLink - -.firstnw: - mov al, [edi] - lea edi, [edi+1] - cmp al, ' ' - je .firstnw - cmp al, $09 - je .firstnw - - dec edi - mov edx, edi - -.internal_link_address: - pop esi edi - - test [.state], fstateLink - jnz .it_is_link - -; it is image. - mov dword [edi], '' - lea edi, [edi+2] - -.go_link_text: - and [.state], not fstateWhite - inc esi - jmp .scan_line2 - -.finalize_image: - mov dword [edi], '" al' - mov dword [edi+4], 't="' - lea edi, [edi+7] - and [.state], not fstateWhite - jmp .go_link_text - -;.................................................................... - -.is_link_end: - test [.state], fstateLink - jnz .close_link_tag - - test [.state], fstateImage or fstateInlineImage - jz .normal_char - -; close the image tag - mov dword [edi], '" />' - lea edi, [edi+4] - - and [.state], not (fstateImage or fstateInlineImage) - jmp .scan_line2 - -.close_link_tag: - mov dword [edi], '' - lea edi, [edi+4] - - and [.state], not fstateLink - jmp .scan_line2 - -;.................................................................... -; Processing of block source code -.copy_source: - -.source_line: - - cmp edi, [.limit] - jb @f - mov dword [edi], 0 - stdcall StrCat, [.result], [.pHTML] - mov edi, [.pHTML] -@@: - - cmp dword [esi], ';end' - je .end_source_block - -.copy_source_line: - mov al, [esi] - lea esi, [esi+1] - - call .store_char - - test al, al - jz .end_source_block2 - - cmp al, $0d - je .end_source_line - cmp al, $0a - jne .copy_source_line - -.end_source_line: - xor al, $0d xor $0a - cmp [esi], al - jne .source_line - - inc esi - mov [edi], al - lea edi, [edi+1] - jmp .source_line - -.end_source_block2: - dec esi - -.end_source_block: - mov dword [edi], '' - lea edi, [edi+8] - - and [.state], not fstateBlockSource - jmp .skip2 - -;.................................................................... - -.close_paragraph: - test [.state], fstatePara - jz .close_para_ok - - test [.state], fstateTable - jnz .close_td - - mov dword [edi], '
' - lea edi, [edi+4] - jmp .close_para_ok - -.close_td: - mov dword [edi], ''
- lea edi, [edi+3]
- or [.state], fstatePara or fstateTextNow
-
- mov dword [edi], ''
- lea edi, [edi+2]
-
- mov dword [edi], ''
- lea edi, [edi+4]
-
- mov al, [esi]
- jmp .normal_char
-
-.copy_id:
- mov al, [esi]
- lea esi, [esi+1]
- cmp al, ']'
- je .cpid_ok
- cmp al, $0d
- je .cpid_ok
- cmp al, $0a
- je .cpid_ok
- test al, al
- jz .cpid_ok
-
- mov [edi], al
- lea edi, [edi+1]
- jmp .copy_id
-
-.cpid_ok:
- retn
-
-;....................................................................
-
-; processing header items and building of the table of contents.
-
-.header2:
- xor ecx, ecx
-
-.scan_level2:
- inc ecx
-.scan_space2:
- lea esi, [esi+1]
- mov al, [esi]
- cmp al, '#'
- je .scan_level2
- cmp al, ' '
- je .scan_space2
- cmp al, $09
- je .scan_space2
-
- cmp al, $0d
- je .end_of_line
- cmp al, $0a
- je .end_of_line
-
- cmp ecx, 6
- jbe @f
- mov ecx, 6
-@@:
-
-; create ID
- call .BuildID
-
- shl ecx, 16
- mov [.last_header], ecx
-
- add ecx, ';
-; [3] output the string for
to the charstream;
-; [4]
;
-; [5]
<- next code in codestream;
-; [6] does
exist in the string table?
-; (yes: output the string for
to the charstream; (A)
-; [...] <- translation for
; (C)
-; add [...]K to the string table; (D)
-;
; ) (E)
-; (no: [...] <- translation for
(I)
-; )
-; [7] go to [5];
-
-.mainloop:
- mov eax, [.NrCodesToOutput]
- cmp eax, [esi+TGifInfo.PixelCounter]
- je .endloop
-
- stdcall _GetNextCode, esi ; [1] and [5]
- mov ebx, eax
- cmp ebx, [esi+TGifInfo.dwLZWClear] ; Check for clearcode
- jne .noclear
-
- stdcall _DECResetLZW, esi ; Reset LZW
- jmp .mainloop
-
-.noclear:
- cmp [esi+TGifInfo.IsFirstCode], 1 ; Checks if steps [1]-[4] have to be done
- jne .notfirst
-
- dec [esi+TGifInfo.IsFirstCode] ;[2]
- stdcall _DECOutputString, esi, ebx ;[3]
- mov [.FirstCharOfOldCode], al ; saved for (G)
- mov [.OldCode], ebx ;[4]
- jmp .mainloop
-
-.notfirst:
- cmp [esi+TGifInfo.dwLZWTableCount], ebx ; [6] ; DECIsCodeInTable replacement
- jbe .notintable
-
- stdcall _DECOutputString, esi, ebx ;(B)
- mov [.FirstCharOfCode], al ;(C)
- mov [.FirstCharOfOldCode], al ; saved for (G)
- stdcall _DECAddToTable, esi, [.OldCode], eax ;(D)
- mov [.OldCode], ebx
- jmp .mainloop
-
-.notintable: ;(F)-(I)
- mov al, [.FirstCharOfOldCode] ; (G)
- stdcall _DECAddToTable, esi, [.OldCode], eax ;(H)
- stdcall _DECOutputString, esi, ebx ;(H)
- mov [.FirstCharOfOldCode], al ; saved for (G)
- mov [.OldCode], ebx
- jmp .mainloop
-
-.endloop:
- xor eax, eax
- inc eax
- pop ebx edi esi
- return
-endp
-
-
-;===============================================================================
-; DECAddToTable
-;===============================================================================
-; Adds an entry to the LZW Table
-; The enry consists of a prefix and a suffix (size is calculated automatically)
-; returns the code for the new entry
-proc _DECAddToTable, .lpGifInfo, .dwPrefix, .dbSuffix
-begin
- push esi edi ebx
-
- mov esi, [.lpGifInfo]
-
- ; --- Check if enough space in the table left
- mov ecx, [esi+TGifInfo.dwLZWTableSize]
- mov ebx, [esi+TGifInfo.dwLZWTableCount]
-
- push ebx
- shl ebx, 2
-
- ; --- If no space left, make the table bigger:
- cmp ebx, ecx
- jne .sizeok
-
- shl ecx, 1 ;Table size doubles
- mov [esi+TGifInfo.dwLZWTableSize], ecx
-
- ; --- Reallocate memory ---
- stdcall ResizeMem, [esi+TGifInfo.lpLZWTable], ecx
- mov [esi+TGifInfo.lpLZWTable], eax
-
-.sizeok:
- ; --- Create pointer to first free entry ---
- add ebx, [esi+TGifInfo.lpLZWTable]
-
- ; --- Find out the size of the string ---
- mov eax, [.dwPrefix]
- shl eax, 2
- add eax, [esi+TGifInfo.lpLZWTable]
- mov eax, [eax]
- shr eax, 8
- and eax, 0FFFh ;eax now holds the size of the prefix string
- inc eax
-
- ; --- Create the entry DWORD ---
- ; (see DECResetLZW for the format)
- mov ecx, [.dwPrefix]
- shl ecx, 20
- shl eax, 8
- or ecx, eax
- mov eax, [.dbSuffix]
- and eax, 0ffh
- or ecx, eax
-
- ; --- Store entry ---
- mov [ebx], ecx
-
- inc [esi+TGifInfo.dwLZWTableCount]
-
- pop ebx ;get saved code of new entry
-
- mov cl, [esi+TGifInfo.dbCurBitSize]
- xor eax, eax
- inc eax
- shl eax, cl
- dec eax
- cmp eax, ebx
- jne @f
-
- ;bitsize should be increased
- inc [esi+TGifInfo.dbCurBitSize] ;increase bitsize
-
-@@:
- mov eax, ebx
- pop ebx edi esi
- return
-endp
-
-
-;===============================================================================
-; DECOutputString
-;===============================================================================
-; Writes the string of dwCode to the output stream
-; returns the first character of the string in al
-;
-proc _DECOutputString, .lpGifInfo, .dwCode
-.LastChar db ?
-begin
- push esi edi ebx
-
- mov esi, [.lpGifInfo]
- mov edi, [esi+TGifInfo.lpLZWTable] ; --- Set basepointer ---
-
- mov eax, [.dwCode] ; --- Get entry ---
-
- mov ebx, [edi+4*eax] ; --- Get size of string ---
- shr ebx, 8 ; See the description of LZW table below.
- and ebx, $0fff
-
-; --- Output all codes backwards ---
- mov edx, [esi+TGifInfo.PixelCounter]
- shl edx, 2
- add edx, [esi+TGifInfo.lpImageData] ; edx is base pointer in the image data.
-
- add [esi+TGifInfo.PixelCounter], ebx ; update the pixel counter.
- dec ebx ; ebx is the counter and index in image data.
-
- mov esi, [esi+TGifInfo.lpColorTable] ; We don't need TGifInfo anymore.
-
-.outloop:
- mov eax, [edi+4*eax]
- mov [.LastChar], al
-
-; Get the color from the color table - esi points to 3 byte palette array.
- movzx ecx, al
- lea ecx, [ecx+2*ecx] ; = 3*ecx
- mov ecx, [esi+ecx]
- bswap ecx
- shr ecx, 8
-
-; Draw the pixel.
- mov [edx+4*ebx], ecx
-
- shr eax, 20 ; Get the prefix index in the LZW table.
- and eax, $0fff
-
- dec ebx
- jns .outloop
-
- mov al, [.LastChar]
- pop ebx edi esi
- return
-endp
-
-
-
-;===============================================================================
-; GetNextCode
-;===============================================================================
-; retrieves the next code from the compressed data stream and loads new bits
-; if needed.
-proc _GetNextCode, .lpGifInfo
-begin
- push esi edi ebx
-
- mov esi, [.lpGifInfo]
- mov ebx, [esi+TGifInfo.CurrentBits]
-
- ; --- Create bitmask for current nr of bits ---
- mov cl, [esi+TGifInfo.dbCurBitSize]
- xor eax, eax
- inc eax
- shl eax, cl
- dec eax
-
- ; --- AND ebx with bitmask ---
- and ebx, eax
-
- ; --- Shift used bits ---
- mov cl, [esi+TGifInfo.dbCurBitSize]
- shr [esi+TGifInfo.CurrentBits], cl
-
- ; --- Decrease # of bits available ---
- sub [esi+TGifInfo.dbBitsAvailable], cl
-
- ; --- Load as many bits as possible ---
-.while:
- cmp [esi+TGifInfo.dbBitsAvailable], 24
- ja .endwhile
- stdcall _LoadNextByte, esi
- jmp .while
-
-.endwhile:
- ; --- Return bits ---
- mov eax, ebx
- pop ebx edi esi
- return
-endp
-
-
-;===============================================================================
-; LoadNextByte
-;===============================================================================
-; Loads the currentbits entry with new bits
-;
-proc _LoadNextByte, .lpGifInfo
-begin
- push esi edi ebx
- mov esi, [.lpGifInfo]
-
- ; --- Get next byte from datastream ---
- mov edi, [esi+TGifInfo.lpCurrentByte]
- cmp edi, -1
- jne .notend
-
-;end of data already reached
- xor al, al ;return 0 as padding
- jmp .gotbyte
-
-;End of subblock reached?
-.notend:
- cmp edi, [esi+TGifInfo.lpLastEOSB]
- jne .noteosb
-
- xor eax, eax
- mov al, [edi] ; new subblock size
- test al,al
- jnz .sizeok
-
- ; if size=0, end of data
- mov [esi+TGifInfo.lpCurrentByte], -1 ;EOF indicator
- jmp .gotbyte
-
-.sizeok:
- inc edi ; new subblock with size al
- add eax, edi
- mov [esi+TGifInfo.lpLastEOSB], eax ;set new end of subblock
- add [esi+TGifInfo.lpCurrentByte], 2
- mov al, [edi]
- jmp .gotbyte
-
-.noteosb:
- mov al, [edi] ;get next byte
- inc [esi+TGifInfo.lpCurrentByte] ;increase for next read
-
- ; --- Got the new byte from the datasteam ---
-.gotbyte:
- mov cl, [esi+TGifInfo.dbBitsAvailable] ;Get nr of bits available
- mov edx, [esi+TGifInfo.CurrentBits] ;Get current bits
- and eax, 0ffh ;eax = al
- shl eax, cl ;Shift bits to right position
- or edx, eax ;OR new bits with current bits
- mov [esi+TGifInfo.CurrentBits], edx ;Save bits
- add [esi+TGifInfo.dbBitsAvailable], 8 ;Set new bits avaialble
-
- pop ebx edi esi
- return
-endp
-
-
-;===============================================================================
-; DECInitialize
-;===============================================================================
-; Initializes the decoder (table for LZW etc)
-;
-proc _DECInitialize, .lpGifInfo
-begin
- push esi edi
-
- mov esi, [.lpGifInfo]
- mov edi, [esi+TGifInfo.lpGIFImage]
-
- ; --- Get initial LZW code size ---
- mov cl, [edi]
- inc cl
- mov [esi+TGifInfo.dbInitBitSize], cl
-
- ; --- Set current bit size to initial bitsize ---
- mov [esi+TGifInfo.dbCurBitSize], cl
-
- ; --- Set size of LZW table ---
-
- cmp cl, 8
- jae @f ;if initial code size is less than 8-bits,
- mov cl, 8 ;set to 8-bits, if higher, don't change it
-@@:
- ; Calculate size of codetable:
- xor eax, eax
- inc eax
- add cl, 2 ; bitsize + 2
- shl eax, cl ; eax = 2 ^ (bitsize + 2) = 4 * (2^bitsize)
- mov [esi+TGifInfo.dwLZWTableSize], eax
-
- ; --- Allocate memory for LZW Table and store pointer ---
- stdcall GetMem, eax
- mov [esi+TGifInfo.lpLZWTable], eax
-
- ; --- Reset LZW ---
- stdcall _DECResetLZW, esi
-
- xor eax, eax
- inc eax
- pop edi esi
- return
-endp
-
-
-
-;===============================================================================
-; DECResetLZW
-;===============================================================================
-; Resets the LZW Table and variables (this is the proper action for a clear
-; code (CC) in data
-proc _DECResetLZW, .lpGifInfo
-begin
- push esi edi ebx
- mov esi, [.lpGifInfo]
-
-; The LZW table has the following format:
-; An array of DWORDS represents an array of string entries
-; One entry consists of a prefix code (which is an index to
-; another entry that should prefix the entry), a string length,
-; and the suffix byte (this byte should be added to the prefix
-; to get the full string).
-; DWORD:
-; | AAAA AAAA | AAAA BBBB | BBBB BBBB | CCCC CCCC |
-; ^ ^
-; MSB LSB
-; AAAAAAAAAAAA: 12-bit index in the LZW Table that indicates the prefix
-; BBBBBBBBBBBB: 12-bit length of the string
-; CCCCCCCC : 8-bit suffix byte
-
- ; --- reset LZW Table ---
- ; Reset bit size:
-
- mov cl, [esi+TGifInfo.dbInitBitSize]
- mov [esi+TGifInfo.dbCurBitSize], cl
-
- ; Get initial nr of entries
- ;mov eax, [esi].ColorCount
- ;NOTE: THE LINE ABOVE WAS PREVIOUSLY USED TO GET THE NR OF ROOT ENTRIES
- ; THIS DIDN'T WORK BECAUSE 1-BIT GIF'S ARE FOR AN UNKNOWN REASON CODED
- ; AS 2-BIT GIFS, SO THE NR OF ROOT ENTRIES HAS TO BE DETERMINED FROM THE
- ; INITIAL BITSIZE
- dec cl
- xor eax, eax
- inc eax
- shl eax, cl ; 2**codesize
- add eax, 2
- mov [esi+TGifInfo.dwLZWTableCount], eax
- mov edx, [esi+TGifInfo.lpLZWTable]
- ; Fill first {2**codcesize+2} entries
- shl eax, 2
- add eax, edx
- xor ecx, ecx
- inc ch ;size of sting is set to 1
-
-.fill:
- mov [edx], ecx
- inc cl
- add edx, 4
- cmp edx, eax
- jb .fill
-
- ; --- set clear code ---
- mov eax, [esi+TGifInfo.dwLZWTableCount]
- sub eax, 2
- mov [esi+TGifInfo.dwLZWClear], eax
- mov [esi+TGifInfo.IsFirstCode], 1
-
- ;lpLZWTable dd ? ; Pointer to LZW Table
- ;dwLZWTableSize dd ? ; Current maximum size of table
- ;dwLZWTableCount dd ? ; Current nr of entries in the LZW table
- ;dbCurBitSize db ? ; Current LZW code size
- ;dbInitBitSize db ? ; Initial LZW code size
- ;dwLZWClear dd ? ; Value of LZW Clear code (CC)
-
- xor eax, eax
- inc eax
- pop ebx edi esi
- return
-endp
-
-
-
-;===============================================================================
-; GIFLoadHeader
-;===============================================================================
-; Loads header and logical screen descriptor
-;
-proc _GIFLoadHeader, .lpGifInfo
-begin
- push esi edi ebx
- mov esi, [.lpGifInfo]
-
- ; --- EDI points to GIF Data, EBX is size of data ---
- mov edi, [esi+TGifInfo.lpGIFData]
- mov ebx, [esi+TGifInfo.dwGIFDataSize]
-
- cmp ebx, 11
- jb .failed ; ebx smaller than header & Logical screen descr. -> invalid GIF
-
- ; --- Check first 3 bytes ("GIF" signature) ---
- mov eax, [edi]
- and eax, $00ffffff
- cmp eax, 'GIF'
- jne .failed
-
- ; --- Copy version number ---
- lea ecx, [esi+TGifInfo.GIFVersion]
- mov ax, [edi+3]
- mov [ecx], ax
- mov al, [edi+5]
- mov [ecx+2], al
-
- ; --- Copy logical screen sizes ---
- xor eax, eax
- mov ax, [edi+6] ;Get Logical screen width
- mov [esi+TGifInfo.dwLSWidth], eax
- mov ax, [edi+8] ;Get Logical screen width
- mov [esi+TGifInfo.dwLSHeight], eax
-
- ; --- Set global color table flag and size ---
- mov cl, [edi+10]
- mov al, cl
- rol al, 1
- and al, 1
- mov [esi+TGifInfo.fGlobalCTable], al
- and cl, 111b
- mov [esi+TGifInfo.dbGCTableSize], cl
-
- xor eax, eax
- inc eax
- pop ebx edi esi
- return
-
-.failed:
- xor eax, eax
- pop ebx edi esi
- return
-endp
-
-
-
-;===============================================================================
-; GIFInitalizeDecoder
-;===============================================================================
-; Initializes decoder
-;
-proc _GIFInitalizeDecoder, .lpGifInfo
-begin
- push esi edi ebx
- mov esi, [.lpGifInfo]
-
- ; --- EDI points to GIF Data, EBX to end of data ---
- mov edi, [esi+TGifInfo.lpGIFData]
- mov ebx, [esi+TGifInfo.dwGIFDataSize]
- add ebx, edi
-
- add edi, 13 ; skip header and local screen descriptor
-
- ; --- Get global color tablesize in bytes ---
- mov cl, [esi+TGifInfo.dbGCTableSize]
- inc cl
- xor eax, eax
- inc eax
- shl eax, cl
- mov ecx, eax
- shl ecx, 1 ;--+--> ecx * 3
- add ecx, eax ;--+
-
- ; --- Skip global color table if available ---
- cmp [esi+TGifInfo.fGlobalCTable], 0
- je @f
- add edi, ecx
-@@:
- cmp edi, ebx
- jae .failed
-
- ; --- Search through the GIF blocks for the first graphic block ---
-.scanloop:
- cmp edi, ebx
- jae .failed
-
- mov al, [edi]
- cmp al, EXTENSIONBLOCK
- jne .maybe
-
- stdcall _SkipExtension, edi, ebx
- mov edi, eax
- jmp .scanloop
-
-.maybe:
- cmp al, IMAGEDESCRIPTOR
- jne .scanloop ; BUG: loop forever on some circumstances...
-
- stdcall _ProcessImageDescriptor, [.lpGifInfo], edi, ebx
- add edi, 11
- stdcall _SkipSubBlocks, edi
-
- xor eax, eax
- inc eax
-.quit:
- pop ebx edi esi
- return
-
-.failed:
- xor eax, eax
- jmp .quit
-endp
-
-
-
-;===============================================================================
-; ProcessImageDescriptor
-;===============================================================================
-; Processes an image desriptor block
-proc _ProcessImageDescriptor, .lpGifInfo, .lpStart, .lpEOF
-begin
- push esi edi
- mov esi, [.lpGifInfo]
-
- mov edx, [.lpStart]
- xor eax, eax
-
- ; --- copy image width & height ---
- mov ax, [edx+5]
- mov [esi+TGifInfo.dwImageWidth], eax
- mov ax, [edx+7]
- mov [esi+TGifInfo.dwImageHeight], eax
-
- ; --- look for local color table ---
- mov cl, [edx+9]
- mov al, cl
- rol cl, 1
- and cl, 1
- mov [esi+TGifInfo.fLocalCTable], cl
- and al, 111b
- mov [esi+TGifInfo.dbLCTableSize], al
-
- ; --- Find out which color table to use ---
- cmp cl, 1
- jne .setglobal
-
- ;local color table available
- ; --- Set color count ---
- mov cl, [esi+TGifInfo.dbLCTableSize]
- inc cl
- xor eax, eax
- inc eax
- shl eax, cl
- mov [esi+TGifInfo.ColorCount], eax
- ; --- Set color table pointer ---
- mov eax, edx
- add eax, 10 ;move to the local color table
- mov [esi+TGifInfo.lpColorTable], eax
- jmp .ctableok
-
-.setglobal:
- ;no local color table, use global color table
- ; --- Set color count ---
- mov cl, [esi+TGifInfo.dbGCTableSize]
- inc cl
- xor eax, eax
- inc eax
- shl eax, cl
- mov [esi+TGifInfo.ColorCount], eax
- ; --- Set color table pointer ---
- mov eax, [esi+TGifInfo.lpGIFData]
- add eax, 13 ;move to the global color table (at offset 13 in file)
- mov [esi+TGifInfo.lpColorTable], eax
-
-.ctableok:
- ; --- Set pointer to real image data (table based image data)
- mov eax, edx
- add eax, 10 ;Skip image descriptor
-
- cmp [esi+TGifInfo.fLocalCTable], 0
- je .setptr
-
- mov ecx, [esi+TGifInfo.ColorCount] ;-+
- add eax, ecx ; + add size of colortable
- shl ecx, 1 ; + (colorcount * 3)
- add eax, ecx ;-+
-
-.setptr:
- mov [esi+TGifInfo.lpGIFImage], eax
-
- ; --- Set some pointers to initialize the decompressor
- inc eax
- mov [esi+TGifInfo.lpLastEOSB], eax
- mov [esi+TGifInfo.lpCurrentByte], eax
-
- xor eax, eax
- inc eax
- pop edi esi
- return
-endp
-
-
-
-;=====================================================================
-; Skips an extension block that starts at lpStart. EOF is at lpEnd.
-; returns pointer to the end of block + 1
-; or 0 if failed
-; esi points at TGifInfo structure.
-proc _SkipExtension, .lpStart, .lpEnd
-begin
- ; --- Get type of extension ---
- mov edx, [.lpStart]
- mov al, [edx+1]
-
- ; --- Skip each type seperately ---
- cmp al, GRAPHICCONTROLEXTENSTION
- jne @f
-
- ; Get transparent color and flag.
- movzx eax, byte [edx+3]
- and eax, 1
- mov [esi+TGifInfo.fTransparent], eax
- mov al, [edx+6]
- mov [esi+TGifInfo.iTrasparentColor], eax
-
- ; Graphic control extension, has a fixed size of 8 bytes
- add edx, 8
- mov eax, edx
- jmp .endext
-
-@@:
- cmp al, COMMENTEXTENSION
- jne @f
-
- ; Comment extension, consists of subblocks of text
- add edx, 2 ;move to first subblock
- stdcall _SkipSubBlocks, edx
- jmp .endext
-
-@@:
- cmp al, PLAINTEXTEXTENSION
- jne @f
-
- ; Plain text extension, 15 header bytes and subblocks follow
- add edx, 15
- stdcall _SkipSubBlocks, edx
- jmp .endext
-
-@@:
- cmp al, APPLICATIONEXTENSION
- jne .endext
-
- ; Application extension, 14 header bytes and subblocks follow
- add edx, 14
- stdcall _SkipSubBlocks, edx
-.endext:
- return
-endp
-
-
-;===============================================================================
-; SkipSubBlocks
-;===============================================================================
-; Skips a sequence of subblocks until a block-terminator is found.
-; returns a pointer to the end of the block + 1.
-; lpStart points to the start of the subblocks
-;
-proc _SkipSubBlocks, .lpStart
-begin
- mov eax, [.lpStart]
- xor ecx, ecx
-.skiploop:
- mov cl, [eax] ; get size of subblock
- test cl, cl
- jz .endloop ; size=0 means terminator
- inc eax
- add eax, ecx ; add size to pointer
- jmp .skiploop
-
-.endloop:
- inc eax
- return
-endp
-
-
-endmodule
DELETED freshlib/graphics/images.asm
Index: freshlib/graphics/images.asm
==================================================================
--- freshlib/graphics/images.asm
+++ /dev/null
@@ -1,37 +0,0 @@
-; _______________________________________________________________________________________
-;| |
-;| ..::FreshLib::.. Free, open source. Licensed under "Fresh artistic license." |
-;|_______________________________________________________________________________________|
-;
-; Description: Memory based images manipulation library.
-;
-; Target OS: Any
-;
-; Dependencies:
-;
-; Notes: Include respective OS dependent files.
-;_________________________________________________________________________________________
-module "Images library"
-
-struct TImage
- .width dd ? ; width in pixels.
- .height dd ? ; height in pixels.
- .bpp dd ? ; bits per pixel.
- .pData dd ? ; pointer to memory buffer with scanlines. all scanlines are aligned on dword.
- .raster dd ? ; OS handle to be used with procedures from other graphics libraries.
-ends
-
-
-proc DrawMaskedImage, .context, .mask, .image, .x, .y
-begin
- stdcall SetDrawMode, [.context], cmAnd
- stdcall DrawImage, [.context], [.mask], [.x], [.y]
- stdcall SetDrawMode, [.context], cmXor
- stdcall DrawImage, [.context], [.image], [.x], [.y]
- return
-endp
-
-
-include '%TargetOS%/images.asm'
-
-endmodule
DELETED freshlib/graphics/text.asm
Index: freshlib/graphics/text.asm
==================================================================
--- freshlib/graphics/text.asm
+++ /dev/null
@@ -1,476 +0,0 @@
-; _______________________________________________________________________________________
-;| |
-;| ..::FreshLib::.. Free, open source. Licensed under "Fresh artistic license." |
-;|_______________________________________________________________________________________|
-;
-; Description: Text drawing library.
-;
-; Target OS: Any
-;
-; Dependencies: StrLib
-;
-; Notes: This file contains OS independent part of the library and includes respective
-; OS dependent files.
-;_________________________________________________________________________________________
-module "Text library"
-
-include "%TargetOS%/text.asm"
-
-
-macro min a, b, use {
- sub b, a
- sbb use, use
- and use, b
- add a, use
-}
-
-macro max a, b, use {
- sub b, a
- sbb use, use
- not use
- and use, b
- add a, use
-}
-
-
-struct TTextExtent
- .width dd ?
- .height dd ?
- .OffsX dd ?
- .OffsY dd ?
-ends
-
-
-struct TCharAttr
- .font dd ?
- .color dd ?
- .background dd ?
- .flags dd ? ; for free use of the client.
-ends
-
-
-; dtfXXX means "draw text flag"
-
-; horizontal align
-dtfAlignLeft = 0
-dtfAlignRight = 1
-dtfAlignCenter = 2
-dtfAlignJustify = 3
-
-; vertical align
-dtfAlignTop = 0 shl 2
-dtfAlignBottom = 1 shl 2
-dtfAlignMiddle = 2 shl 2
-
-; Text layout
-dtfCRLF = $0100
-dtfWordWrap = $0200
-dtfTableTabs = $0400
-
-
-struct _TTextChunk
- .y dd ?
- .width dd ?
- .height dd ?
- .len dd ?
- .ptr dd ?
-ends
-
-__HeightProbeString text '18ilj.Xygl[_|"`g'
-__NumberProbeString text '8888888888888888'
-
-; returns: eax - mean width
-; returns: edx - height
-; returns: ecx - descent
-proc FontGetCharSize, .raster, .font, .probe
-begin
- push ebx
-
- stdcall AllocateContext, [.raster]
- mov ebx, eax
-
- stdcall GetTextOffset, ebx, [.probe], 16, [.font]
- mov ecx, edx
-
-; DebugMsg "Text offset y:"
-; OutputRegister regECX, 10
-
- stdcall GetTextBounds, ebx, [.probe], 16, [.font]
- stdcall ReleaseContext, ebx
-
- sub ecx, edx
- shr eax, 4
- neg ecx
- pop ebx
- return
-endp
-
-
-
-
-proc AdjustCountUtf8
-begin
- push esi
- lea esi, [esi+ebx]
- stdcall ScanBackUtf8
- mov ebx, esi
- pop esi
- sub ebx, esi
- return
-endp
-
-
-proc DrawTextBox, .context, .text, .bounds, .flags, .font, .color
-.len dd ?
-.count dd ?
-.height dd ?
-.y dd ?
-
-.low dd ?
-.high dd ?
-
-.linew dd ?
-.lineh dd ?
-
-.DrawProc dd ?
-begin
- pushad
-
- mov ecx, DrawString
-
- mov eax, [.flags]
- and eax, $03
- cmp eax, dtfAlignJustify
- jne @f
- mov ecx, DrawStringJustified
-@@:
- mov [.DrawProc], ecx
-
- stdcall StrLen, [.text]
- mov [.len], eax
-
- stdcall StrPtr, [.text]
- mov esi, eax
-
- mov edi, [.bounds]
- mov eax, [edi+TBounds.height]
-; mov ecx, [edi+TBounds.y]
- mov [.height], eax
- mov [.y], 0 ;ecx
-
-; slice the string on chunks, depending on flags, rectangle width and the string content.
-; push _TTextChunk for every chunk in stack.
- mov [.count], 0
-.slice:
- mov ecx, [.len]
-
- test [.flags], dtfCRLF
- jz .cropit
-
- xor ecx, ecx
-
-.scanCRLF:
- cmp ecx, [.len]
- jae .cropit
-
- mov al, [esi+ecx]
-
- cmp al, $0d
- je .cropit
- cmp al, $0a
- je .cropit
- inc ecx
- jmp .scanCRLF
-
-.cropit:
- mov ebx, ecx ; high limit
-
- stdcall AdjustCountUtf8
- stdcall GetTextBounds, [.context], esi, ebx, [.font]
-
- cmp edx, [.height]
- jg .drawchunks
-
- mov [.lineh], edx
-
- cmp eax, [edi+TBounds.width]
- jle .itfits
-
- mov [.high], ebx
- mov [.low], 0
-
-.croploop:
- mov ebx, [.low]
- add ebx, [.high]
- shr ebx, 1
-
- stdcall AdjustCountUtf8
- stdcall GetTextBounds, [.context], esi, ebx, [.font]
- cmp eax, [edi+TBounds.width]
- je .itfits
-
- jg .above
-
- cmp ebx, [.low]
- je .itfits
-
- mov [.low], ebx
- jmp .croploop
-
-.above:
- mov [.high], ebx
- jmp .croploop
-
-.itfits: ; here ebx contains the len of string that fits in the rectangle.
- mov ecx, ebx
- mov [.linew], eax
-
- test [.flags], dtfWordWrap
- jz .pushit
-
-; search the last space or tab that separates words:
- mov edx, ecx
- cmp byte [esi+edx], $0d
- je .found
- cmp byte [esi+edx], $0a
- je .found
-
-.searchword:
- cmp byte [esi+edx], 0
- je .found
- cmp byte [esi+edx], ' '
- je .found
- cmp byte [esi+edx], $09
- je .found
- cmp byte [esi+edx], $0d
- je .found
- cmp byte [esi+edx], $0a
- je .found
-
- dec edx
- jnz .searchword
-
- mov edx, ecx
-
-.found:
- push ebx
- mov ebx, edx
- stdcall AdjustCountUtf8
- stdcall GetTextBounds, [.context], esi, ebx, [.font]
- mov [.linew], eax
- mov [.lineh], edx
- mov ecx, ebx
- pop ebx
-
-.pushit:
- push esi ; pointer to the string.
- push ecx ; length of the string.
- push [.lineh] ; height of the line.
- push [.linew] ; width of the line.
- push [.y] ;
-
- inc [.count]
-
- mov eax, [.lineh]
- add [.y], eax
- sub [.height], eax
-
- lea esi, [esi+ecx]
- sub [.len], ecx
- jz .drawchunks
-
- xor ecx, ecx
-
-; search for the whitespace that have to be skip
-.skiploop:
- mov al, [esi]
- cmp al, $0d
- je .skipcrlf
- cmp al, $0a
- je .skipcrlf
- cmp al, $20
- je .skipspace
- cmp al, $09
- je .skipspace
-
- jmp .slice
-
-.skipspace:
- inc esi
- dec [.len]
- jnz .skiploop
- jmp .drawchunks
-
-.skipcrlf:
- inc esi
- dec [.len]
- xor al, $0d xor $0a
- cmp [esi], al
- jne .slice
- inc esi
- dec [.len]
- jnz .slice
-
-; pop the _TTextChunk structures and draw, depending on flags.
-.drawchunks:
- mov ebx, esp
- stdcall GetTextOffset, [.context], [ebx+_TTextChunk.ptr], [ebx+_TTextChunk.len], [.font]
- mov eax, [ebx+_TTextChunk.height]
- sub eax, edx ; it should be the line y descent
- test [.flags], dtfAlignBottom
- jnz @f
- sub [.y], eax
-@@:
- mov edx, [.flags]
- and edx, dtfAlignBottom or dtfAlignMiddle
-
- mov ecx, [edi+TBounds.height]
- sub ecx, [.y]
-
- cmp edx, dtfAlignBottom
- je .yalignok
-
- sar ecx, 1
- cmp edx, dtfAlignMiddle
- je .yalignok
-
- xor ecx, ecx
-
-.yalignok:
-.drawloop:
- cmp [.count], 0
- je .finish
-
- mov ebx, esp
-
- mov eax, [edi+TBounds.width]
- sub eax, [ebx+_TTextChunk.width]
-
- mov edx, [.flags]
- and edx, $03
-
- cmp edx, dtfAlignRight
- je .hready
-
- shr eax, 1
- cmp edx, dtfAlignCenter
- je .hready
-
- xor eax, eax
-
-.hready:
- add eax, [edi+TBounds.x]
-
- push eax
- stdcall GetTextOffset, [.context], [ebx+_TTextChunk.ptr], [ebx+_TTextChunk.len], [.font]
- add edx, ecx
- add edx, [ebx+_TTextChunk.y]
- add edx, [edi+TBounds.y]
- pop eax
-
- stdcall [.DrawProc], [.context], [ebx+_TTextChunk.ptr], [ebx+_TTextChunk.len], eax, edx, [.font], [.color]
-
-; draws lines on every row of text. For debug purposes.
-iglobal
- if used __UnderlineStyle
- __UnderlineStyle LineStyle 0, $808080
- end if
-endg
-
-if defined options.DebugMode & options.DebugMode
- stdcall SetLineStyle, [.context], __UnderlineStyle
- stdcall DrawLine, [.context], [edi+TBounds.x], edx, [edi+TBounds.width], edx
-end if
-; end debug code
-
-
- add esp, sizeof._TTextChunk
- dec [.count]
- jmp .drawloop
-
-.finish:
- popad
- return
-endp
-
-
-
-
-proc DrawStringJustified, .raster, .ptrString, .len, .x, .y, .font, .color
-.XX dd ?
-.rem dd ?
-.crem dd ?
-.endptr dd ?
-begin
- pushad
-
- mov esi, [.ptrString]
- mov eax, [.len]
- add eax, esi
- mov [.endptr], eax
-
- stdcall StrLenUtf8, esi, [.len]
- mov ecx, eax
- dec ecx
- jg @f
- mov ecx, 1
-@@:
-
- stdcall GetTextBounds, [.raster], esi, [.len], [.font]
-
- sub eax, [edi+TBounds.width]
- neg eax
-
- cdq
- div ecx
-
- cmp eax, 4
- jge .cantjustify ; the needed space is too big for justify, so just draw it left aligned
-
- mov ecx, eax
- mov [.rem], edx
- mov [.crem], edx
-
- mov ebx, [.len]
- push [.x]
- pop [.XX]
-
-.drawloop:
- cmp esi, [.endptr]
- jae .finish
-
- stdcall DecodeUtf8, [esi]
- jc .finish
-
- push edx
- stdcall DrawString, [.raster], esi, edx, [.XX], [.y], [.font], [.color]
- stdcall GetTextBounds, [.raster], esi, edx, [.font]
- pop edx
- add esi, edx
- add [.XX], eax
- add [.XX], ecx
-
- cmp [.crem], 0
- je .drawloop
-
- sub ebx, [.rem]
- jge .drawloop
-
- inc [.XX]
- dec [.crem]
- mov ebx, [.len]
- sub ebx, [.rem]
- jmp .drawloop
-
-.finish:
- popad
- return
-
-.cantjustify:
- stdcall DrawString, [.raster], [.ptrString], [.len], [.x], [.y], [.font], [.color]
- jmp .finish
-endp
-
-
-
-endmodule
DELETED freshlib/gui/Linux/Main.asm
Index: freshlib/gui/Linux/Main.asm
==================================================================
--- freshlib/gui/Linux/Main.asm
+++ /dev/null
@@ -1,451 +0,0 @@
-; _______________________________________________________________________________________
-;| |
-;| ..::FreshLib::.. Free, open source. Licensed under "Fresh artistic license." |
-;|_______________________________________________________________________________________|
-;
-; Description: Main procedure of GUI application library.
-;
-; Target OS: Linux
-;
-; Dependencies:
-;
-; Notes: Organize the main message/event loop needed by every GUI engine.
-;_________________________________________________________________________________________
-
-uglobal
- if used fGlobalTerminate
- fGlobalTerminate dd ?
- end if
-endg
-
-
-proc ProcessSystemEvents
- .event XEvent
-begin
- push ebx ecx edx
-
-.event_loop:
-; check for quit
- mov eax, [pApplication]
- mov eax, [eax+TApplication.MainWindow]
- test eax, eax
- jz .continue ; ???????????
-
- cmp dword [eax], 0
- jne .continue
-
- cinvoke XFlush, [hApplicationDisplay]
- xor eax, eax
- mov [fGlobalTerminate], 1
- stc
- pop edx ecx ebx
- return
-
-.continue:
- cinvoke XPending, [hApplicationDisplay]
- test eax, eax
- jz .noevents
-
- lea ebx, [.event]
- cinvoke XNextEvent, [hApplicationDisplay], ebx
- stdcall __ProcessOneSystemEvent, ebx
- jmp .event_loop
-
-.noevents:
- clc
- pop edx ecx ebx
- return
-
-endp
-
-
-
-
-proc WaitForSystemEvent
-.event XEvent
-begin
- push eax ecx edx
- lea eax, [.event]
- cinvoke XPeekEvent, [hApplicationDisplay], eax
- pop edx ecx eax
- return
-endp
-
-
-
-
-;proc EventsQueued, .pWin
-;begin
-; push eax ecx edx
-; cinvoke XQLength, [hApplicationDisplay]
-; test eax, eax
-; clc
-; jz @f
-; stc
-;@@:
-; pop edx ecx eax
-; return
-;endp
-
-
-
-
-proc __ProcessOneSystemEvent, .linux_event
-.event rd 64
-begin
- push eax ebx ecx edx esi edi
-
- mov ebx, [.linux_event]
-
- stdcall _GetWindowStruct, [ebx+XEvent.window]
- mov esi, eax
- lea edi, [.event]
- mov eax, [ebx+XEvent.type]
-
- cmp eax, DestroyNotify
- je .destroy
-
- test esi, esi
- jz .notprocessed
-
- cmp eax, MotionNotify
- je .mousemove
-
- cmp eax, EnterNotify
- je .mouseenter
-
- cmp eax, LeaveNotify
- je .mouseleave
-
- cmp eax, ButtonPress
- je .mouse_btn_press
-
- cmp eax, ButtonRelease
- je .mouse_btn_release
-
- cmp eax, Expose
- je .paint_window
-
- cmp eax, ClientMessage ; event from the window manager - button close for example.
- je .clientmessage
-
- cmp eax, KeyPress
- je .key_press
-
- cmp eax, KeyRelease
- je .key_release
-
- cmp eax, MappingNotify
- je .mapping_notify
-
- cmp eax, FocusIn
- je .focusin
-
- cmp eax, FocusOut
- je .focusout
-
- cmp eax, ConfigureNotify
- je .moveresize
-
-.notprocessed:
- pop edi esi edx ecx ebx eax
- stc
- return
-
-.exec_event:
- pushad
- stdcall ExecEvent, esi, edi
- popad
-
-.finish:
- pop edi esi edx ecx ebx eax
- clc
- return
-
-;.........................................................................
-; Resize events
-.moveresize:
-locals
- .xevent XConfigureEvent
-endl
- lea eax, [.xevent]
- cinvoke XCheckTypedWindowEvent, [hApplicationDisplay], [ebx+XConfigureEvent.window], ConfigureNotify, eax
- test eax, eax
- jz .process
-
- lea eax, [.xevent]
- cinvoke XPutBackEvent, [hApplicationDisplay], eax
-
- mov eax, [.xevent.x]
- cmp eax, [ebx+XConfigureEvent.x]
- jne .finish
-
- mov eax, [.xevent.y]
- cmp eax, [ebx+XConfigureEvent.y]
- jne .finish
-
- mov eax, [.xevent.width]
- cmp eax, [ebx+XConfigureEvent.width]
- jne .finish
-
- mov eax, [.xevent.height]
- cmp eax, [ebx+XConfigureEvent.height]
- jne .finish
-
-.process:
- mov [edi+TMoveResizeEvent.event], seMoveResize
-
- mov eax, [ebx+XConfigureEvent.x]
- mov ecx, [ebx+XConfigureEvent.y]
- mov [edi+TMoveResizeEvent.newX], eax
- mov [edi+TMoveResizeEvent.newY], ecx
-
- cmp [ebx+XConfigureEvent.height], 100
- jl @f
-; DebugMsg "NewX NewY"
-; OutputRegister regEAX, 10
-; OutputRegister regECX, 10
-@@:
- mov eax, [ebx+XConfigureEvent.width]
- mov ecx, [ebx+XConfigureEvent.height]
- mov [edi+TMoveResizeEvent.newWidth], eax
- mov [edi+TMoveResizeEvent.newHeight], ecx
-
- cmp [ebx+XConfigureEvent.height], 100
- jl @f
-; DebugMsg "NewW NewH"
-; OutputRegister regEAX, 10
-; OutputRegister regECX, 10
-@@:
- jmp .exec_event
-
-;.........................................................................
-; Focus events
-.focusout:
- mov [edi+TFocusOutEvent.event], seFocusOut
- jmp .setIC
-
-.focusin:
- mov [edi+TFocusInEvent.event], seFocusIn
-
-.setIC:
- cinvoke XSetICValues, [hInputContext], XNFocusWindow, [esi+TWindow.handle], 0
- jmp .exec_event
-
-;.........................................................................
-; DestroyNotify handler it invalidates the handle in TWindow structure and then destroys TWindow.
-.destroy:
- DebugMsg "Destroy notify"
- OutputNumber [ebx+XDestroyWindowEvent.window], 16, 8
- DebugMsg "h <<< Window handle"
-
- test esi, esi
- jz .finish
-
- DebugMsg "Destroy the object"
-
- mov [esi+TWindow.handle], 0
- stdcall Destroy, esi
- jmp .finish
-
-;.........................................................................
-; Mouse event handlers
-
-.mouseleave:
- mov [edi+TMouseEnterEvent.event], seMouseLeave
- jmp .exec_event
-
-.mouseenter:
- mov [edi+TMouseEnterEvent.event], seMouseEnter
- jmp .exec_event
-
-.mousemove:
- mov [edi+TMouseMoveEvent.event], seMouseMove
- mov eax, [ebx+XMotionEvent.x]
- mov ecx, [ebx+XMotionEvent.y]
- mov [edi+TMouseMoveEvent.x], eax
- mov [edi+TMouseMoveEvent.y], ecx
- jmp .exec_event
-
-.mouse_btn_press:
-.mouse_btn_release:
-
- mov eax, [ebx+XButtonEvent.type]
- mov [edi+TMouseButtonEvent.event], eax ; seMouseBtnPress=ButtonPress and seMouseBtnRelease = ButtonRelease
-
- mov eax, [ebx+XButtonEvent.button]
- dec eax
-
- cmp [edi+TScrollEvent.event], seMouseBtnRelease
- je @f
-
- cmp eax, 3
- jge .wheelscroll
-
-@@:
- mov [edi+TMouseButtonEvent.Button], eax
-
- mov eax, [ebx+XButtonEvent.state]
- mov [edi+TMouseButtonEvent.kbdStatus], eax
-
- mov eax, [ebx+XButtonEvent.x]
- mov ecx, [ebx+XButtonEvent.y]
- mov [edi+TMouseButtonEvent.x], eax
- mov [edi+TMouseButtonEvent.y], ecx
-
- jmp .exec_event
-
-.wheelscroll:
- mov ecx, scWheelUp
- je @f
- mov ecx, scWheelDn
-@@:
- mov [edi+TScrollEvent.event], seScroll
- mov [edi+TScrollEvent.ScrollBar], scrollY
- mov [edi+TScrollEvent.ScrollCmd], ecx
- mov [edi+TScrollEvent.Value], 1
- jmp .exec_event
-
-;.........................................................................
-; Window paint event
-
-.paint_window:
-; cmp [ebx+XExposeEvent.count], 0
-; jne .finish
-
- lea eax, [ebx+XExposeEvent.x]
- stdcall __PaintWindow, esi, eax
-
- jmp .finish
-
-;.........................................................................
-; Keyboard events.
-
-locals
- .utf8buff rb 16
-endl
-
-.key_press:
- mov ecx, seKbdKeyPress
- mov [edi+TKeyboardEvent.event], ecx
- mov ecx, [ebx+XKeyEvent.state]
- mov [edi+TKeyboardEvent.kbdStatus], ecx
-
- mov dword [.utf8buff], 0
- lea eax, [.utf8buff]
- cinvoke Xutf8LookupString, [hInputContext], ebx, eax, 16, 0, 0
-
-; here, .utg8buff contains the utf-8 string with the character typed on the keyboard.
- mov eax, dword [.utf8buff]
- mov [edi+TKeyboardEvent.key], eax
-
-.scancode:
- mov eax, [ebx+XKeyEvent.keycode]
- cinvoke XKeycodeToKeysym, [hApplicationDisplay], eax, 0
- mov [edi+TKeyboardEvent.scancode], eax
- jmp .exec_event
-
-
-.key_release:
- mov ecx, seKbdKeyRelease
- mov eax, [ebx+XKeyEvent.state]
-
- mov [edi+TKeyboardEvent.event], ecx
- mov [edi+TKeyboardEvent.kbdStatus], eax
- mov [edi+TKeyboardEvent.key], 0
- jmp .scancode
-
-
-
-; refreshes keyboard mapping information, stored locally in XLib.
-.mapping_notify:
- cinvoke XRefreshKeyboardMapping, ebx
- jmp .finish
-
-
-;.........................................................................
-; This event is sent from the window manager, when the user click on the close button of the
-; window or close it some other way. So, the window have to decide whether to close or not.
-
-.clientmessage:
- mov eax, dword [ebx+XClientMessageEvent.data]
- cmp eax, [atomWMDelete]
- jne .finish
-
-; The window is closed by click on close button or by pressing Alt+F4 or by other WM method
-;.close_from_wm:
- mov [edi+TCloseEvent.event], seCloseRequest
- mov [edi+TCloseEvent.reason], cerFromUser
- jmp .exec_event
-endp
-
-
-
-
-
-
-
-
-proc __PaintWindow, .pWindow, .ptrBounds
-.event TPaintEvent
-.caret dd ?
-begin
- push eax ebx ecx edx esi edi
-
- lea edi, [.event]
- mov esi, [.pWindow]
-
-if defined Caret
- mov [.caret], -1
- cmp esi, [Caret.pWindow]
- jne @f
- stdcall CaretShow, FALSE
- mov [.caret], eax
-@@:
-end if
- mov [edi+TPaintEvent.event], sePaint
-
- stdcall AllocateContext, [esi+TWindow.handle]
- mov ebx, eax
- mov [edi+TPaintEvent.context], eax
-
- xor eax, eax
- mov [edi+TPaintEvent.rect.left], eax
- mov [edi+TPaintEvent.rect.top], eax
- mov eax, $7fffffff
- mov [edi+TPaintEvent.rect.right], eax
- mov [edi+TPaintEvent.rect.bottom], eax
-
- mov edx, [.ptrBounds]
- test edx, edx
- jz .rectok
-
- mov eax, [edx+TBounds.x]
- mov ecx, [edx+TBounds.y]
-
- mov [edi+TPaintEvent.rect.left], eax
- mov [edi+TPaintEvent.rect.top], ecx
-
- mov eax, [edx+TBounds.width]
- mov ecx, [edx+TBounds.height]
- add eax, [edi+TPaintEvent.rect.left]
- add ecx, [edi+TPaintEvent.rect.top]
- mov [edi+TPaintEvent.rect.right], eax
- mov [edi+TPaintEvent.rect.bottom], ecx
-
-.rectok:
- pushad
- stdcall ExecEvent, esi, edi
- popad
-
- stdcall ReleaseContext, ebx
-
-if defined Caret
- cmp [.caret], -1
- je @f
- stdcall CaretShow, [.caret]
-@@:
-end if
- pop edi esi edx ecx ebx eax
- return
-endp
DELETED freshlib/gui/Linux/TApplication.asm
Index: freshlib/gui/Linux/TApplication.asm
==================================================================
--- freshlib/gui/Linux/TApplication.asm
+++ /dev/null
@@ -1,347 +0,0 @@
-; _______________________________________________________________________________________
-;| |
-;| ..::FreshLib::.. Free, open source. Licensed under "Fresh artistic license." |
-;|_______________________________________________________________________________________|
-;
-; Description: TApplication object class.
-;
-; Target OS: Linux
-;
-; Dependencies:
-;
-; Notes: TApplication by the idea is the base of GUI application, but the implementation
-; somehow need fixing...
-;_________________________________________________________________________________________
-
-
-uglobal
- if used CApplication
- hApplicationDisplay dd ?
- hRootWindow dd ?
-
- hInputMethod dd ?
- hInputContext dd ?
-
- _SystemFont dd ?
-
- atomWMDelete dd ?
- end if
-endg
-
-;cDefaultFont text 'Tahoma-8'
-cDefaultFont text 'Liberation Sans-9'
-cDefaultFontSize = 9
-;cDefaultFont text 'Ubuntu-9:rgba=rgb'
-;cDefaultFont text 'Unifont-12' ; this one have unicode support;
-
-
-; String constants needed for XLib
-; Why, they needed so many strings????????????????? For arguments!??????????
-_cWinDeleteName text 'WM_DELETE_WINDOW'
-
-XNVaNestedList text "XNVaNestedList"
-XNSeparatorofNestedList text "separatorofNestedList"
-XNQueryInputStyle text "queryInputStyle"
-XNClientWindow text "clientWindow"
-XNInputStyle text "inputStyle"
-XNFocusWindow text "focusWindow"
-XNResourceName text "resourceName"
-XNResourceClass text "resourceClass"
-XNGeometryCallback text "geometryCallback"
-XNDestroyCallback text "destroyCallback"
-XNFilterEvents text "filterEvents"
-XNPreeditStartCallback text "preeditStartCallback"
-XNPreeditDoneCallback text "preeditDoneCallback"
-XNPreeditDrawCallback text "preeditDrawCallback"
-XNPreeditCaretCallback text "preeditCaretCallback"
-XNPreeditStateNotifyCallback text "preeditStateNotifyCallback"
-XNPreeditAttributes text "preeditAttributes"
-XNStatusStartCallback text "statusStartCallback"
-XNStatusDoneCallback text "statusDoneCallback"
-XNStatusDrawCallback text "statusDrawCallback"
-XNStatusAttributes text "statusAttributes"
-XNArea text "area"
-XNAreaNeeded text "areaNeeded"
-XNSpotLocation text "spotLocation"
-XNColormap text "colorMap"
-XNStdColormap text "stdColorMap"
-XNForeground text "foreground"
-XNBackground text "background"
-XNBackgroundPixmap text "backgroundPixmap"
-XNFontSet text "fontSet"
-XNLineSpace text "lineSpace"
-XNCursor text "cursor"
-XNQueryIMValuesList text "queryIMValuesList"
-XNQueryICValuesList text "queryICValuesList"
-XNStringConversionCallback text "stringConversionCallback"
-XNStringConversion text "stringConversion"
-XNResetState text "resetState"
-XNHotKey text "hotkey"
-XNHotKeyState text "hotkeyState"
-XNPreeditState text "preeditState"
-XNVisiblePosition text "visiblePosition"
-XNR6PreeditCallbackBehavior text "r6PreeditCallback"
-XNRequiredCharSet text "requiredCharSet"
-XNQueryOrientation text "queryOrientation"
-XNDirectionalDependentDrawing text "directionalDependentDrawing"
-XNContextualDrawing text "contextualDrawing"
-XNBaseFontName text "baseFontName"
-XNMissingCharSet text "missingCharSet"
-XNDefaultString text "defaultString"
-XNOrientation text "orientation"
-XNFontInfo text "fontInfo"
-XNOMAutomatic text "omAutomatic"
-
-
-
-proc TApplication.Create, .obj
-.ptr dd ?
-begin
- push eax ecx edx
-
- cinvoke XInitThreads
- test eax, eax
- jz .exit_error
-
- cinvoke XSetErrorHandler, __FreshXErrorHandler
-
- cinvoke XOpenDisplay, 0
- test eax, eax
- jz .second_try
-
-.continue:
- DebugMsg 'Display opened.'
-
- mov [hApplicationDisplay], eax
-
- cinvoke XDefaultRootWindow, eax
- mov [hRootWindow], eax
-
- cinvoke XOpenIM, [hApplicationDisplay], 0, 0, 0
- mov [hInputMethod], eax
-
- lea eax, [.ptr]
- cinvoke XGetIMValues, [hInputMethod], XNQueryInputStyle, eax, 0
-
- mov eax, [.ptr]
- mov eax, [eax+4]
- cinvoke XCreateIC, [hInputMethod], XNInputStyle, [eax], 0
- mov [hInputContext], eax
-
- cinvoke XFree, [.ptr]
-
- stdcall InitMouseCursors
-
-; Creating internal atoms that to be used with Window manager of the application windows...
-; Maybe this code should reside somewhere else, not in application. In initialize TWindow???
-
- cinvoke XInternAtom, [hApplicationDisplay], _cWinDeleteName, 0
- mov [atomWMDelete], eax
-
- cinvoke XftFontOpenName, [hApplicationDisplay], 0, cDefaultFont
- mov [_SystemFont], eax
-
-
-; clipboard initialization.
-if __UseClipboard = 1
- stdcall __InitLinuxClipboard
-end if
-
- clc
- pop edx ecx eax
- return
-
-.second_try:
- stdcall Sleep, 200 ; wait a little.
-
- cinvoke XOpenDisplay, 0
- test eax, eax
- jnz .continue
-
-.exit_error:
- Message 'Error open display.'
- stc
- pop edx ecx eax
- return
-
-
-
-
-endp
-
-
-
-
-proc TApplication.Get, .obj, .paramID
-begin
- stc
- return
-endp
-
-
-
-proc TApplication.Set, .obj, .paramID, .value
-begin
- stc
- return
-endp
-
-
-
-proc TApplication.SysEventHandler
-begin
- clc
- return
-endp
-
-
-
-
-cXErrorMsg text 'X server error:'
-cXErrorMsg2 text 10, 0
-cXErrorMsg3 text 'Request: '
-cXErrorMsg4 text 'Minor code: '
-cXErrorMsg5 text 'ResourceID: $'
-
-proc __FreshXErrorHandler, .display, .error
-.buff rb 256
-begin
-if (defined options.DebugMode) & options.DebugMode
- cmp [fGlobalTerminate], 0
- jne .exit
-
- stdcall Output, cXErrorMsg
- mov ebx, [.error]
-
- movzx eax, [ebx+XErrorEvent.error_code]
- lea ecx, [.buff]
- cinvoke XGetErrorText, [.display], eax, ecx, 256
-
- lea ecx, [.buff]
- stdcall Output, ecx
- stdcall Output, cXErrorMsg2
-
- stdcall Output, cXErrorMsg3
- movzx eax, [ebx+XErrorEvent.request_code]
- stdcall OutputNumber, eax, 10, 3
- stdcall Output, cXErrorMsg2
-
- stdcall Output, cXErrorMsg4
- movzx eax, [ebx+XErrorEvent.minor_code]
- stdcall OutputNumber, eax, 10, 3
- stdcall Output, cXErrorMsg2
-
- stdcall Output, cXErrorMsg5
- stdcall OutputNumber, [ebx+XErrorEvent.resourceid], 16, 8
- stdcall Output, cXErrorMsg2
- stdcall Output, cXErrorMsg2
-end if
-.exit:
- cret
-endp
-
-
-
-
-; This code and data possibly will be used in FreshLib, but I hope, not very soon. :)
-
-; cinvoke XInternAtom, [hApplicationDisplay], _cWinSyncRequest, 0
-; mov [atomSyncRequest], eax
-;
-;
-; cinvoke XInternAtom, [hApplicationDisplay], _cAtomTypeAtom, 0
-; mov [atomTypeATOM], eax
-;
-;; _NET_WM_WINDOW_TYPE
-; cinvoke XInternAtom, [hApplicationDisplay], _cWinTypeAtomName, 0
-; mov [atomWMType], eax
-;
-; cinvoke XInternAtom, [hApplicationDisplay], _cWinTypeDlg, 0
-; mov [atomWinTypeDlg], eax
-;
-; cinvoke XInternAtom, [hApplicationDisplay], _cWinTypeTool, 0
-; mov [atomWinTypeTool], eax
-;
-; cinvoke XInternAtom, [hApplicationDisplay], _cWinTypeDock, 0
-; mov [atomWinTypeDock], eax
-;
-; cinvoke XInternAtom, [hApplicationDisplay], _cWinTypeNormal, 0
-; mov [atomWinTypeNormal], eax
-;
-; cinvoke XInternAtom, [hApplicationDisplay], atomAllowedActions.text, 0
-; mov [atomAllowedActions], eax
-;
-; cinvoke XInternAtom, [hApplicationDisplay], atomAllowedActions.minimize.text, 0
-; mov [atomAllowedActions.minimize], eax
-;
-; cinvoke XInternAtom, [hApplicationDisplay], atomAllowedActions.close.text, 0
-; mov [atomAllowedActions.close], eax
-;
-; cinvoke XInternAtom, [hApplicationDisplay], atomWMState.text, 0
-; mov [atomWMState], eax
-;
-; cinvoke XInternAtom, [hApplicationDisplay], atomWMState.modal.text, 0
-; mov [atomWMState.modal], eax
-;
-
-;_cWinTypeAtomName text '_NET_WM_WINDOW_TYPE'
-; _cWinTypeDlg text '_NET_WM_WINDOW_TYPE_DIALOG'
-; _cWinTypeTool text '_NET_WM_WINDOW_TYPE_TOOLBAR' ; it is with normal toolbar, but with only close button.
-; _cWinTypeDock text '_NET_WM_WINDOW_TYPE_DOCK' ; without title bar and above all other windows???
-; _cWinTypeNormal text '_NET_WM_WINDOW_TYPE_NORMAL'
-
-;_cWinSyncRequest text '_NET_WM_SYNC_REQUEST'
-;_cAtomTypeAtom text 'ATOM'
-
-; notes on different types, regarding XFWM window manager:
-; _NET_WM_WINDOW_TYPE_SPLASH - no title, goes up on activation.
-; _NET_WM_WINDOW_TYPE_DOCK - no title, always on top
-; _NET_WM_WINDOW_TYPE_DROPDOWN_MENU - ???
-; _NET_WM_WINDOW_TYPE_NOTIFICATION - ???
-; _
-;
-
-
-;macro atomset lbl, name, [valname, value] {
-;common
-; lbl dd ?
-;forward
-; valname dd ?
-;common
-; lbl#.text text `name
-;forward
-; lbl#valname#.text text `value
-;}
-;
-
-;uglobal
-; atomSyncRequest dd ?
-;
-; atomTypeATOM dd ?
-;
-; atomWMType dd ?
-; atomWinTypeDlg dd ?
-; atomWinTypeTool dd ?
-; atomWinTypeDock dd ?
-; atomWinTypeNormal dd ?
-;endg
-;
-;
-;iglobal
-; atomset atomAllowedActions, _NET_WM_ALLOWED_ACTIONS, \
-; .move, _NET_WM_ACTION_MOVE, \
-; .resize, _NET_WM_ACTION_RESIZE, \
-; .minimize, _NET_WM_ACTION_MINIMIZE, \
-; .shade, _NET_WM_ACTION_SHADE, \
-; .stick, _NET_WM_ACTION_STICK, \
-; .maximize_horz, _NET_WM_ACTION_MAXIMIZE_HORZ, \
-; .maximize_vert, _NET_WM_ACTION_MAXIMIZE_VERT, \
-; .fullscreen, _NET_WM_ACTION_FULLSCREEN, \
-; .change_desktop, _NET_WM_ACTION_CHANGE_DESKTOP, \
-; .close, _NET_WM_ACTION_CLOSE
-;
-; atomset atomWMState, _NET_WM_STATE, \
-; .modal, _NET_WM_STATE_MODAL
-;
-;endg
-;
DELETED freshlib/gui/Linux/keycodes.inc
Index: freshlib/gui/Linux/keycodes.inc
==================================================================
--- freshlib/gui/Linux/keycodes.inc
+++ /dev/null
@@ -1,74 +0,0 @@
-; _______________________________________________________________________________________
-;| |
-;| ..::FreshLib::.. Free, open source. Licensed under "Fresh artistic license." |
-;|_______________________________________________________________________________________|
-;
-; Description: This file contains scan code values for control keyboard keys.
-;
-; Target OS: Linux
-;
-; Dependencies:
-;
-; Notes:
-;_________________________________________________________________________________________
-
-keyHomeNumpad = $ff95
-keyUpNumpad = $ff97
-keyPgUpNumpad = $ff9a
-keyLeftNumpad = $ff96
-key5Numpad = $ff9d
-keyRightNumpad = $ff98
-keyEndNumpad = $ff9c
-keyDownNumpad = $ff99
-keyPgDnNumpad = $ff9b
-keyInsNumpad = $ff9e
-keyDelNumpad = $ff9f
-keyEnterNumpad = $ff8d
-keyPlusNumpad = $ffab
-keyMinusNumpad = $ffad
-keyAsteriskNumpad = $ffaa
-keySlashNumpad = $ffaf
-
-keyNumLock = $ff7f
-keyScrollLock = $ff14
-keyPause = $ff13
-
-
-keyLeft = $ff51
-keyRight = $ff53
-keyUp = $ff52
-keyDown = $ff54
-
-keyInsert = $ff63
-keyDelete = $ffff
-keyHome = $ff50
-keyEnd = $ff57
-keyPgUp = $ff55
-keyPgDown = $ff56
-
-keyF1 = $ffbe
-keyF2 = $ffbf
-keyF3 = $ffc0
-keyF4 = $ffc1
-
-keyF5 = $ffc2
-keyF6 = $ffc3
-keyF7 = $ffc4
-keyF8 = $ffc5
-
-keyF9 = $ffc6
-keyF10 = $ffc7
-keyF11 = $ffc8
-keyF12 = $ffc9
-
-keyCapsLock = $ffe5
-keyShiftLeft = $ffe1
-keyCtrlLeft = $ffe3
-;keyWndLeft =
-;keyWndRight =
-keyAltLeft = $ffe9
-keyAltRight = $ffea
-keyPopupMenu = $ff67
-keyShiftRight = $ffe2
-keyCtrlRight = $ffe4
-keyBackSpace = $ff08
DELETED freshlib/gui/Linux/mouse.asm
Index: freshlib/gui/Linux/mouse.asm
==================================================================
--- freshlib/gui/Linux/mouse.asm
+++ /dev/null
@@ -1,100 +0,0 @@
-; _______________________________________________________________________________________
-;| |
-;| ..::FreshLib::.. Free, open source. Licensed under "Fresh artistic license." |
-;|_______________________________________________________________________________________|
-;
-; Description: Provides unified access to standard mouse cursors.
-;
-; Target OS: Linux
-;
-; Dependencies:
-;
-; Notes:
-;_________________________________________________________________________________________
-
-iglobal
- if used _Xcursors
- _Xcursors db 68, 152, 34, 108, 116, 40, 40, 150 ; X standard cursor font
- end if
-endg
-
-
-uglobal
- if used StockCursors
- StockCursors rd mcCount
- end if
-endg
-
-
-proc InitMouseCursors
-begin
- push eax ecx edx ebx
- mov ebx, mcCount-1
-
-.create_cursor_loop:
- movzx eax, [_Xcursors+ebx]
- cinvoke XCreateFontCursor, [hApplicationDisplay], eax
- mov [StockCursors+4*ebx], eax
-
- dec ebx
- jns .create_cursor_loop
- pop ebx edx ecx eax
- return
-endp
-
-
-
-if used InitMouseCursors
-finalize FinalizeMouseCursors
-begin
- mov ebx, mcCount-1
- cmp [hApplicationDisplay], 0
- je .exit
-
-.free_cursor_loop:
- cinvoke XFreeCursor, [hApplicationDisplay], [StockCursors+4*ebx]
- dec ebx
- jns .free_cursor_loop
-
-.exit:
- return
-endp
-end if
-
-
-proc SetMouseCursor, .hCursor
-begin
- push eax ecx edx
- cinvoke XDefineCursor, [hApplicationDisplay], [hRootWindow], [.hCursor]
- pop edx ecx eax
- return
-endp
-
-
-
-proc GetStockCursor, .index
-begin
- mov eax, [.index]
- and eax, 7
- mov eax, [StockCursors+4*eax]
- return
-endp
-
-
-proc MouseCapture, .hwnd
-begin
- push eax ecx edx
- cmp [.hwnd], 0
- je .release
-
- cinvoke XGrabPointer, [hApplicationDisplay], [.hwnd], FALSE, PointerMotionMask or ButtonPressMask or ButtonReleaseMask, \
- GrabModeAsync, GrabModeAsync, None, None, CurrentTime
-
-.finish:
- pop edx ecx eax
- return
-
-.release:
- cinvoke XUngrabPointer, [hApplicationDisplay], CurrentTime
- jmp .finish
-endp
DELETED freshlib/gui/Linux/windows.asm
Index: freshlib/gui/Linux/windows.asm
==================================================================
--- freshlib/gui/Linux/windows.asm
+++ /dev/null
@@ -1,418 +0,0 @@
-; _______________________________________________________________________________________
-;| |
-;| ..::FreshLib::.. Free, open source. Licensed under "Fresh artistic license." |
-;|_______________________________________________________________________________________|
-;
-; Description: Window management OS interface functions.
-;
-; Target OS: Linux
-;
-; Dependencies:
-;
-; Notes:
-;_________________________________________________________________________________________
-
-
-proc _CreateNullWindow
-.attr XSetWindowAttributes
-begin
- push ecx edx esi
-
- lea eax, [.attr]
- mov [eax+XSetWindowAttributes.override_redirect], 1
- mov [eax+XSetWindowAttributes.backing_store], NotUseful
- mov [eax+XSetWindowAttributes.background_pixmap], None
- cinvoke XCreateWindow, [hApplicationDisplay], [hRootWindow], 0, 0, 1, 1, 0, CopyFromParent, InputOutput, CopyFromParent, 0, CWBackingStore or CWOverrideRedirect or CWBackPixmap, eax
- mov esi, eax
- test eax, eax
- jz .exit
-
- cinvoke XSelectInput, [hApplicationDisplay], esi, ExposureMask or StructureNotifyMask or FocusChangeMask or \
- KeyPressMask or KeyReleaseMask or \
- ButtonPressMask or ButtonReleaseMask or \
- EnterWindowMask or LeaveWindowMask or \
- PointerMotionMask
-
- cinvoke XSetWMProtocols, [hApplicationDisplay], esi, atomWMDelete, 1
- mov eax, esi
-.exit:
- pop esi edx ecx
- return
-endp
-
-
-
-;_________________________________________________________________________________________
-
-
-
-proc _DestroyWindow, .hwnd
-begin
- push eax ecx edx
- stdcall _SetWindowStruct, [.hwnd], 0
- cinvoke XDestroyWindow, [hApplicationDisplay], [.hwnd]
- pop edx ecx eax
- return
-endp
-
-
-
-;_________________________________________________________________________________________
-
-
-
-proc _GetParent, .hwnd
-.root dd ?
-.parent dd ?
-.children dd ?
-.count dd ?
-begin
- push ecx edx esi
-
- lea esi, [.count]
- lea edx, [.children]
- lea ecx, [.parent]
- lea eax, [.root]
- cinvoke XQueryTree, [hApplicationDisplay], [.hwnd], eax, ecx, edx, esi
- test eax, eax
- jz .exit ; function failed
-
- cinvoke XFree, [.children]
-
- mov eax, [.parent]
-
-.exit:
- pop esi edx ecx
- return
-endp
-
-
-
-;_________________________________________________________________________________________
-
-
-proc _GetChildren, .hwnd
- .root dd ?
- .parent dd ?
- .children dd ?
- .count dd ?
-begin
- push ebx ecx edx esi
-
-
- lea ebx, [.count]
- lea edx, [.children]
- lea ecx, [.parent]
- lea eax, [.root]
- cinvoke XQueryTree, [hApplicationDisplay], [.hwnd], eax, ecx, edx, ebx
- test eax, eax
- jz .exit ; function failed
-
- xor ebx, ebx
- mov esi, [.children]
- test esi, esi
- jz .endchildren
-
- stdcall CreateArray, sizeof.TWinArrayItem
- mov ebx, eax
- mov ecx, [.count]
-
-.loophwnd:
- dec ecx
- js .endchildren_free
-
- stdcall AddArrayItems, ebx, 1
- mov ebx, edx
-
- mov edx, [esi+4*ecx]
- mov [eax+TWinArrayItem.handle], edx
-
- jmp .loophwnd
-
-.endchildren_free:
- cinvoke XFree, esi
-
-.endchildren:
- mov eax, ebx
-.exit:
- pop esi edx ecx ebx
- return
-endp
-
-
-;_________________________________________________________________________________________
-
-
-
-proc _GetVisible, .hwnd
-.attr XWindowAttributes
-begin
- push ebx ecx edx
-
- lea ebx, [.attr]
- cinvoke XGetWindowAttributes, [hApplicationDisplay], [.hwnd], ebx
- mov eax, [ebx+XWindowAttributes.map_state]
- test eax, eax
- jz @f
- mov eax, 1
-@@:
- pop edx ecx ebx
- return
-endp
-
-;_________________________________________________________________________________________
-
-
-proc _GetWindowBounds, .hwnd, .pBounds
-begin
- push eax ecx edx
-
- int3
- pop edx ecx eax
- return
-endp
-
-
-;_________________________________________________________________________________________
-
-
-proc _SetWindowBounds, .hwnd, .pBounds
- .wch XWindowChanges
-begin
- push eax ecx edx
-
- lea eax, [.wch]
- mov edx, [.pBounds]
-
- push [edx+TBounds.x] [edx+TBounds.y] [edx+TBounds.width] [edx+TBounds.height]
- pop [.wch.height] [.wch.width] [.wch.y] [.wch.x]
-
- cmp [.wch.width], 0
- jnz @f
- inc [.wch.width]
-@@:
- cmp [.wch.height], 0
- jnz @f
- inc [.wch.height]
-@@:
- cinvoke XConfigureWindow, [hApplicationDisplay], [.hwnd], CWX or CWY or CWWidth or CWHeight, eax
-
- pop edx ecx eax
- return
-endp
-
-
-;_________________________________________________________________________________________
-
-
-
-proc _SetWindowBorder, .hwnd, .brdType
- .attr XSetWindowAttributes
-begin
- push eax ecx edx
-
- mov [.attr.override_redirect], 1
- cmp [.brdType], borderNone
- je @f
- mov [.attr.override_redirect], 0
-@@:
- lea eax, [.attr]
- cinvoke XChangeWindowAttributes, [hApplicationDisplay], [.hwnd], CWOverrideRedirect, eax
-
- pop edx ecx eax
- return
-endp
-
-;_________________________________________________________________________________________
-
-
-proc _ShowWindow, .hwnd, .flag
-begin
- push eax ecx edx
-
- mov ecx, XUnmapWindow
- cmp [.flag], 0
- je @f
- mov ecx, XMapWindow
-@@:
- ccall dword [ecx], [hApplicationDisplay], [.hwnd]
- pop edx ecx eax
- return
-endp
-
-
-;_________________________________________________________________________________________
-
-
-proc _RefreshWindow, .hwnd
-begin
- push eax ecx edx
- cinvoke XClearArea, [hApplicationDisplay], [.hwnd], 0, 0, 0, 0, TRUE
- cinvoke XFlush, [hApplicationDisplay]
- pop edx ecx eax
- return
-endp
-
-
-;_________________________________________________________________________________________
-
-
-proc _SetFocus, .hwnd
-begin
- push eax ecx edx
- cinvoke XSetInputFocus, [hApplicationDisplay], [.hwnd], RevertToParent, CurrentTime
- pop edx ecx eax
- return
-endp
-
-;_________________________________________________________________________________________
-
-proc _AddChild, .hwnd, .child
-begin
- push eax ecx edx
- cinvoke XReparentWindow, [hApplicationDisplay], [.child], [.hwnd], 10, 10
- pop edx ecx eax
- return
-endp
-
-;_________________________________________________________________________________________
-
-
-proc _SetWindowTextUtf8, .hwnd, .ptrUtf8
-begin
- push eax ecx edx
- cinvoke XStoreName, [hApplicationDisplay], [.hwnd], [.ptrUtf8]
- pop edx ecx eax
- return
-endp
-
-
-
-;_________________________________________________________________________________________
-
-
-
-proc _GetWindowTextUtf8, .hwnd, .ptrUtf8
-begin
- return
-endp
-
-
-
-
-;_________________________________________________________________________________________
-
-proc _EnableWindow, .hwnd, .flag
-begin
- push eax ecx edx
-
- stdcall _GetChildren, [.hwnd]
- test eax, eax
- jz .children_ok
-
- mov edx, [eax+TArray.count]
-.child_loop:
- dec edx
- js .end_children
-
- stdcall _EnableWindow, [eax+TArray.array+sizeof.TWinArrayItem*edx+TWinArrayItem.handle], [.flag]
- jmp .child_loop
-
-.end_children:
- stdcall FreeMem, eax
-
-.children_ok:
- mov ecx, ExposureMask or StructureNotifyMask or EnterWindowMask or LeaveWindowMask or PointerMotionMask
- cmp [.flag], 0
- je @f
- or ecx, FocusChangeMask or KeyPressMask or KeyReleaseMask or \
- ButtonPressMask or ButtonReleaseMask
-@@:
- cinvoke XSelectInput, [hApplicationDisplay], [.hwnd], ecx
-
- pop edx ecx eax
- return
-endp
-
-;_________________________________________________________________________________________
-
-proc _SetModalTowards, .hwnd, .hwndParent
-begin
- push eax ecx edx
- cinvoke XSetTransientForHint, [hApplicationDisplay], [.hwnd], [.hwndParent]
- pop edx ecx eax
- return
-endp
-
-;_________________________________________________________________________________________
-
-proc _FinalizeModal, .hwnd, .hwndParent
- .flushevent XEvent
-begin
- push eax ecx edx
-
- DebugMsg "Finalize modal"
-
-; dirty hack, but the button receives LeaveNotify after DestroyNotify
- cinvoke XSync, [hApplicationDisplay], FALSE
-.loop_flush:
- lea eax, [.flushevent]
- cinvoke XCheckMaskEvent, [hApplicationDisplay], LeaveWindowMask, eax
- test eax, eax
- jnz .loop_flush
-
- pop edx ecx eax
- return
-endp
-
-
-;_________________________________________________________________________________________
-
-
-win_structure_context = 1
-
-
-proc _GetWindowStruct, .hwin
- .user_data dd ?
-begin
- push ecx edx
- lea eax, [.user_data]
- cinvoke XFindContext, [hApplicationDisplay], [.hwin], win_structure_context, eax
- test eax, eax
- jnz .error
-
- mov eax, [.user_data]
- clc
- pop edx ecx
- return
-
-.error:
- DebugMsg 'FreshLib: Error find context.'
- mov edx, [ebp+4]
- OutputRegister regEDX, 16
-
- xor eax, eax
- pop edx ecx
- return
-endp
-
-
-
-
-;_________________________________________________________________________________________
-
-
-
-proc _SetWindowStruct, .hwin, .value
-begin
- push eax ecx edx
- cinvoke XSaveContext, [hApplicationDisplay], [.hwin], win_structure_context, [.value]
- pop edx ecx eax
- return
-endp
-
-
-
-
-
-
DELETED freshlib/gui/Main.asm
Index: freshlib/gui/Main.asm
==================================================================
--- freshlib/gui/Main.asm
+++ /dev/null
@@ -1,125 +0,0 @@
-; _______________________________________________________________________________________
-;| |
-;| ..::FreshLib::.. Free, open source. Licensed under "Fresh artistic license." |
-;|_______________________________________________________________________________________|
-;
-; Description: Main procedure of GUI application library.
-;
-; Target OS: Any
-;
-; Dependencies:
-;
-; Notes: Organize the main message/event loop needed by every GUI engine.
-; This file contains only OS independent part and includes OS dependent files.
-;_________________________________________________________________________________________
-module "Main library"
-
-uglobal
- if used pApplication
- pApplication dd ?
- end if
-endg
-
-
-proc Run
-begin
-.mainloop:
- stdcall ProcessSystemEvents
- jc .terminate
-
- mov eax, [pApplication]
- test eax, eax
- jz .eventok
-
- cmp [eax+TApplication.OnIdle], 0
- je .eventok
-
- pushad
- stdcall [eax+TApplication.OnIdle], eax
- popad
-
-.eventok:
- stdcall WaitForSystemEvent
- jmp .mainloop
-
-.terminate:
- return
-endp
-
-
-
-
-proc ShowModal, .pForm, .pParent
-.prev dd ?
-begin
- push ecx edx
- mov ecx, [.pParent]
- mov edx, [.pForm]
-
- jecxz @f
- stdcall _SetModalTowards, [edx+TForm.handle], [ecx+TWindow.handle]
-@@:
- stdcall Set, edx, TForm.Visible, TRUE
-
- jecxz @f
- stdcall _EnableWindow, [ecx+TWindow.handle], FALSE
-@@:
-
- mov [edx+TForm.ModalResult], 0
-
- stdcall Get, edx, TForm.OnClose
- mov [.prev], eax
- stdcall Set, edx, TForm.OnClose, __ModalOnClose
-
-.modal_loop:
- stdcall ProcessSystemEvents
- jc .exit_modal
-
- cmp [edx+TForm.ModalResult], 0
- jne .exit_modal
-
- stdcall Get, edx, TWindow.Visible
- test eax, eax
- jz .exit_modal
-
-.vis_ok:
- stdcall WaitForSystemEvent
- jmp .modal_loop
-
-.exit_modal:
- jecxz @f
- stdcall _EnableWindow, [ecx+TWindow.handle], TRUE
-@@:
-
- stdcall Set, edx, TForm.OnClose, [.prev]
- stdcall Set, edx, TForm.Visible, FALSE
-
- jecxz @f
- mov ecx, [ecx+TWindow.handle]
-@@:
- stdcall _FinalizeModal, [edx+TForm.handle], ecx
-
- mov eax, [edx+TForm.ModalResult]
- pop edx ecx
- return
-endp
-
-
-; prevent destroy of the form from the close button or Alt+F4
-proc __ModalOnClose, .self, .reason
-begin
- push eax
- mov eax, [.self]
- mov [eax+TForm.ModalResult], mrCancel
- stc
- pop eax
- return
-endp
-
-
-
-
-
-include '%TargetOS%/Main.asm'
-
-endmodule
DELETED freshlib/gui/ObjTemplates.asm
Index: freshlib/gui/ObjTemplates.asm
==================================================================
--- freshlib/gui/ObjTemplates.asm
+++ /dev/null
@@ -1,131 +0,0 @@
-; _______________________________________________________________________________________
-;| |
-;| ..::FreshLib::.. Free, open source. Licensed under "Fresh artistic license." |
-;|_______________________________________________________________________________________|
-;
-; Description: Objects template engine
-;
-; Target OS: Any
-;
-; Dependencies: objects.asm
-;
-; Notes:
-;_________________________________________________________________________________________
-module "Templates library"
-
-tfChild = 0
-tfParent = 1
-tfEnd = 2
-
-
-struct TObjTemplate
- .flags dd ? ; tfParent; tfEnd
- .class dd ?
- .ptrVar dd ? ; can be NULL
- .paramsize dd ?
- .params:
-ends
-
-
-macro ObjTemplate flags, class, name, [id, param] {
-common
-local ..paramsize, ..prms
- dd flags
- dd C#class
- dd name
- dd ..paramsize
-..prms:
-forward
-local ..value
- dd T#class#.#id
- dd ..value
-common
- dd -1
-forward
- if param eqtype 2
- ..value = param
- else
- ..value db param, 0
- end if
-common
- name dd ?
- ..paramsize = $ - ..prms
-}
-
-
-; returns the last created window in ebx.
-
-proc CreateFromTemplate, .ptrTemplate, .parent
-begin
- push esi
-
- mov esi, [.ptrTemplate]
- stdcall _DoCreateFromTemplate, [.parent]
-
- pop esi
- return
-endp
-
-
-proc _DoCreateFromTemplate, .parent
-begin
- push eax ecx edx
-
-.createloop:
- stdcall Create, [esi+TObjTemplate.class]
- execute [.parent], TObject.AddChild, ebx
-
- lea ecx, [esi+TObjTemplate.params]
-
-.paramloop:
- cmp dword [ecx], -1
- je .paramsok
-
- push ebx ecx edx esi edi
- stdcall Set, ebx, [ecx], [ecx+4]
- pop edi esi edx ecx ebx
- add ecx, 8
- jmp .paramloop
-
-.paramsok:
- mov eax, [esi+TObjTemplate.ptrVar]
- test eax, eax
- jz .oncreate
-
- mov [ebx+TObject.ptrVar], eax ; back link to the object instance variable.
- mov [eax], ebx ; returned pointer/handle to the object.
-
-.oncreate:
- cmp [ebx+TObject.OnCreate], 0
- je .gonext
-
-; execute user OnCreate event.
- pushad
- stdcall [ebx+TObject.OnCreate], ebx
- popad
-
-.gonext:
- mov edx, [esi+TObjTemplate.flags]
-
- mov eax, sizeof.TObjTemplate
- add eax, [esi+TObjTemplate.paramsize]
- add esi, eax
-
- test edx, tfParent
- jz .childrenok
-
- push ebx
- stdcall _DoCreateFromTemplate, ebx
- pop ebx
-
-.childrenok:
- test edx, tfEnd
- jz .createloop
-
-.exit:
- pop edx ecx eax
- return
-endp
-
-
-endmodule
DELETED freshlib/gui/TAction.asm
Index: freshlib/gui/TAction.asm
==================================================================
--- freshlib/gui/TAction.asm
+++ /dev/null
@@ -1,79 +0,0 @@
-; _______________________________________________________________________________________
-;| |
-;| ..::FreshLib::.. Free, open source. Licensed under "Fresh artistic license." |
-;|_______________________________________________________________________________________|
-;
-; Description: Actions management library.
-;
-; Target OS: Any
-;
-; Dependencies:
-;
-; Notes: "Action" is set of executable code, combined with user interface attributes -
-; caption, accelerator keys, enable/disable status flag etc.
-; Different UI elements, such as buttons, menu items etc. can be attached to
-; the action object and to use its attributes. When the programmer changes
-; something in the action, all UI elements are updated automatically.
-;_________________________________________________________________________________________
-
-struc TAction caption, hint, icon, FastKey, enabled, OnExecute, OnIdle {
-common
- .Text dd caption ; handle or pointer to the caption string.
- .Hint dd hint ; handle or pointer to the Hint text.
- .icon dd icon ; pointer to TImage
- .FastKey dd FastKey ; pointer to keyboard accelerator combination.
- .Enabled dd enabled ; if FALSE, the action is not active.
- .OnExecute dd OnExecute ; pointer to procedure to be executed on activation of the action.
- .OnIdle dd OnIdle ; pointer to procedure that to be executed once, when there is no other events in the queue.
-}
-
-virtual at 0
- TAction TAction ?, ?, ?, ?, ?, ?, ?
-end virtual
-
-
-struc TFastKey flags, key, action {
- .flags dd flags
- .key dd key
- .action dd action
-}
-virtual at 0
- TFastKey TFastKey ?, ?, ?
-end virtual
-
-
-struct TActionList
- .count dd ?
- .accelerators dd ?
- .actions:
-ends
-
-
-
-macro ActionList name, [actname, caption, hint, icon, FastKey, OnExecute, OnIdle] {
-common
- local i, count, acclist
- i = 0
- label name dword
- .count dd count
- .accelerators dd acclist
-forward
- local .accitem, txtlbl, hintlbl
-
- txtlbl text caption
- hintlbl text hint
-
- actname TAction txtlbl, hintlbl, icon, accitem, 1, OnExecute, OnIdle
-
- i = i + 1
-common
- count = i
- label acclist dword
-
-forward
- if FastKey eq NONE
- accitem = 0
- else
- .accitem TFastKey FastKey, name#actname
- end if
-}
DELETED freshlib/gui/TApplication.asm
Index: freshlib/gui/TApplication.asm
==================================================================
--- freshlib/gui/TApplication.asm
+++ /dev/null
@@ -1,42 +0,0 @@
-; _______________________________________________________________________________________
-;| |
-;| ..::FreshLib::.. Free, open source. Licensed under "Fresh artistic license." |
-;|_______________________________________________________________________________________|
-;
-; Description: TApplication object class.
-;
-; Target OS: Any
-;
-; Dependencies:
-;
-; Notes: TApplication by the idea is the base of GUI application, but the implementation
-; somehow need fixing...
-;_________________________________________________________________________________________
-module "TApplication library"
-
-ObjectClass Application, \
- Object, \
- TApplication.Create, \
- 0, \
- TApplication.Get, \
- TApplication.Set, \
- 0, \
- TApplication.SysEventHandler
-
-
-
-; The root object in the application.
-; every other object will be child on the TApplication.MainWindow.
-; only one instance of TApplication should be created.
-;
-object TApplication, TObject
- .MainWindow dd ? ; pointer to a variable that contains pointer to the main window of the application. When this variable becomes 0 the application terminates.
- .Accelerators dd ? ; table of application wide hot keys.
- .OnIdle dd ? ; user event handler for idle state.
-endobj
-
-
-include '%TargetOS%/TApplication.asm'
-
-
-endmodule
DELETED freshlib/gui/TButton.asm
Index: freshlib/gui/TButton.asm
==================================================================
--- freshlib/gui/TButton.asm
+++ /dev/null
@@ -1,350 +0,0 @@
-; _______________________________________________________________________________________
-;| |
-;| ..::FreshLib::.. Free, open source. Licensed under "Fresh artistic license." |
-;|_______________________________________________________________________________________|
-;
-; Description: TButton object class
-;
-; Target OS: Any
-;
-; Dependencies:
-;
-; Notes: Represents GUI button.
-;_________________________________________________________________________________________
-module "TButton library"
-
-ObjectClass Button, \
- Window, \
- 0, \
- 0, \
- TButton.Get, \
- TButton.Set, \
- 0, \
- TButton.SysEventHandler
-
-
-; Button states for the field TButton.state
-btnNormal = 0
-btnPressed = 1
-btnPointed = 2
-btnChecked = 3
-
-
-
-
-object TButton, TWindow
- .state dd ?
- .Ficon dd ?
- .FiconAlign dd ?
- .Ftextalign dd ?
-
- .ModalResult dd ?
- .OnClick dd ?
-
- param .TextAlign
- param .Icon
- param .IconPosition
-endobj
-
-
-
-proc TButton.Get, .obj, .paramID
-begin
- mov eax, [.obj]
-
- stdcall IsObject, eax, CButton
- jc .exit
-
- cmp [.paramID], TButton.TextAlign
- je .gettextalign
-
- cmp [.paramID], TButton.IconPosition
- je .geticonposition
-
- cmp [.paramID], TButton.Icon
- je .geticon
-
- stc
-.exit:
- return
-
-.geticonposition:
- mov eax, [eax+TButton.FiconAlign]
- clc
- return
-
-.geticon:
- mov eax, [eax+TButton.Ficon]
- clc
- return
-
-.gettextalign:
- mov eax, [eax+TButton.Ftextalign]
- clc
- return
-endp
-
-
-
-
-proc TButton.Set, .obj, .paramID, .value
-begin
- push eax
-
- mov eax, [.obj]
- stdcall IsObject, eax, CButton
- jc .exit
-
- cmp [.paramID], TButton.TextAlign
- je .settextalign
-
- cmp [.paramID], TButton.Icon
- je .seticon
-
- cmp [.paramID], TButton.IconPosition
- je .seticonposition
-
- stc
-.exit:
- pop eax
- return
-
-.refresh:
- execute [.obj], TWindow.Refresh
- clc
- pop eax
- return
-
-.seticonposition:
- push [.value]
- pop [eax+TButton.FiconAlign]
- jmp .refresh
-
-.seticon:
- push [.value]
- pop [eax+TButton.Ficon]
- jmp .refresh
-
-.seticonalign:
- push [.value]
- pop [eax+TButton.FiconAlign]
- jmp .refresh
-
-.settextalign:
- push [.value]
- pop [eax+TButton.Ftextalign]
- jmp .refresh
-endp
-
-
-
-proc TButton.SysEventHandler, .pObj, .pEvent
-begin
- push eax ebx ecx edx esi edi
-
- mov esi, [.pObj]
- mov ebx, [.pEvent]
- mov eax, [ebx+TSysEvent.event]
- cmp eax, sePaint
- je .onpaint
-
- cmp eax, seMouseEnter
- je .enter
- cmp eax, seMouseLeave
- je .leave
-
- cmp eax, seMouseBtnPress
- je .pressed
- cmp eax, seMouseBtnRelease
- je .released
-
-.finish:
- stc
- pop edi esi edx ecx ebx eax
- return
-
-.pressed:
- mov [esi+TButton.state], btnPressed
- execute esi, TWindow.Refresh
- jmp .finish
-
-.released:
-; test [ebx+TMouseButtonEvent.kbdStatus], maskBtnLeft or maskBtnMiddle or maskBtnRight
-; jnz .finish
-
- cmp [esi+TButton.state], btnPressed
- jne .finish
-
- mov [esi+TButton.state], btnPointed
- execute esi, TButton.Refresh
-
- cmp [esi+TButton.ModalResult], mrNone
- je @f
-
- stdcall Get, esi, TButton.Parent
- stdcall IsObject, eax, CForm
- jc @f
-
- push [esi+TButton.ModalResult]
- pop [eax+TForm.ModalResult]
-
-@@:
- cmp [esi+TButton.OnClick], 0
- je .finish
-
- pushad
- stdcall [esi+TButton.OnClick], esi, [ebx+TMouseButtonEvent.Button]
- popad
- jmp .finish
-
-.enter:
- mov [esi+TButton.state], btnPointed
- execute esi, TButton.Refresh
- jmp .finish
-
-.leave:
- mov [esi+TButton.state], btnNormal
- execute esi, TButton.Refresh
- jmp .finish
-
-; PAINT event is very important.
-
-.onpaint:
- mov edx, bxFlat
- mov edi, [clButtonBk] ; background
- mov ecx, [clButtonTxt] ; text
-
- cmp [esi+TButton.state], btnNormal
- je .drawit
-
- mov edx, bxRaised
- mov edi, [clButtonHotBk]
- mov ecx, [clButtonHotTxt]
-
- cmp [esi+TButton.state], btnPointed
- je .drawit
-
- mov edx, bxSunken
- mov edi, [clButtonBk]
- mov ecx, [clButtonHotTxt]
-
- cmp [esi+TButton.state], btnPressed
- je .drawit
-
- mov edx, bxFlat
-
-.drawit:
-locals
- .bounds TBounds
- .clTxt dd ?
-endl
- mov [.clTxt], ecx
-
- mov ecx, [esi+TButton._width]
- mov eax, [esi+TButton._height]
- mov [.bounds.x], 0
- mov [.bounds.y], 0
- mov [.bounds.width], ecx
- mov [.bounds.height], eax
- lea eax, [.bounds]
- stdcall [DrawBox], [ebx+TPaintEvent.context], eax, edi, edx
-
-; first draw the icon and then resize bounds for the text.
- mov edi, [esi+TButton.Ficon]
- test edi, edi
- jz .draw_text
-
- cmp [esi+TButton.FiconAlign], AlignLeft
- jne @f
-
-; align left
- mov eax, [.bounds.x]
- mov ecx, [.bounds.height]
- add eax, 2
- sub ecx, [edi+TImage.height]
- sar ecx, 1
- add ecx, [.bounds.y]
-
- mov edx, [edi+TImage.width]
- add edx, 4
- add [.bounds.x], edx
- sub [.bounds.width], edx
- jmp .draw_icon
-
-@@:
- cmp [esi+TButton.FiconAlign], AlignRight
- jne @f
-
-; align right
- mov edx, [edi+TImage.width]
-
- mov eax, [.bounds.x]
- add eax, [.bounds.width]
- sub eax, edx
- sub eax, 2
- sub [.bounds.width], edx
- sub [.bounds.width], 4
-
- mov ecx, [.bounds.height]
- sub ecx, [edi+TImage.height]
- sar ecx, 1
- add ecx, [.bounds.y]
- jmp .draw_icon
-
-@@:
- cmp [esi+TButton.FiconAlign], AlignTop
- jne @f
-
-; align top
- mov ecx, [.bounds.y]
- add ecx, 2
- mov eax, [.bounds.width]
- sub eax, [edi+TImage.width]
- sar eax, 1
- add eax, [.bounds.x]
-
- mov edx, [edi+TImage.height]
- add edx, 4
- add [.bounds.y], edx
- sub [.bounds.height], edx
- jmp .draw_icon
-
-@@:
- cmp [esi+TButton.FiconAlign], AlignBottom
- jne .draw_text
-
-; align bottom
- mov edx, [edi+TImage.height]
-
- mov ecx, [.bounds.y]
- add ecx, [.bounds.height]
- sub ecx, edx
- sub ecx, 2
- sub [.bounds.height], edx
- sub [.bounds.height], 4
-
- mov eax, [.bounds.width]
- sub eax, [edi+TImage.width]
- sar eax, 1
- add eax, [.bounds.x]
-
-.draw_icon:
- stdcall DrawImage, [ebx+TPaintEvent.context], [esi+TButton.Ficon], eax, ecx
-
-.draw_text:
- stdcall Get, esi, TWindow.Caption
- test eax, eax
- jz .finish
-
- push eax eax
- stdcall StrLen, eax
- mov ecx, eax
- pop eax
- lea edx, [.bounds]
- stdcall DrawTextBox, [ebx+TPaintEvent.context], eax, edx, [esi+TButton.Ftextalign], 0, [.clTxt]
- stdcall StrDel ; from the stack
- jmp .finish
-endp
-
-
-endmodule
DELETED freshlib/gui/TEdit.asm
Index: freshlib/gui/TEdit.asm
==================================================================
--- freshlib/gui/TEdit.asm
+++ /dev/null
@@ -1,587 +0,0 @@
-; _______________________________________________________________________________________
-;| |
-;| ..::FreshLib::.. Free, open source. Licensed under "Fresh artistic license." |
-;|_______________________________________________________________________________________|
-;
-; Description: TEdit object class
-;
-; Target OS: Any
-;
-; Dependencies:
-;
-; Notes: Represents single line edit control.
-;_________________________________________________________________________________________
-module "TEdit library"
-
-ObjectClass Edit, \
- Window, \
- TEdit.Create, \
- TEdit.Destroy, \
- TEdit.Get, \
- TEdit.Set, \
- 0, \
- TEdit.SysEventHandler
-
-
-object TEdit, TWindow
- ._Text dd ?
- ._Len dd ? ; the length of the string in characters. (UTF-8)
- ._Start dd ? ; Where the string begins to be displayed in the edit window.
- ._Pos dd ? ; Position of the caret in the string.
- ._Sel dd ? ; Position of the selction in the string.
-
- ._MarginLeft dd ?
- ._MarginRight dd ?
-
- ._Focused dd ? ; flag
-
- param .Text
-endobj
-
-
-proc TEdit.Create, .obj
-begin
- push ecx eax
- stdcall StrNew
- mov ecx, [.obj]
- mov [ecx+TEdit._Text], eax
-
-; for test. Normal value is 0 for these fields.
-; mov [ecx+TEdit._MarginLeft], 8
-; mov [ecx+TEdit._MarginRight], 16
-
- mov [ecx+TEdit._cursor], mcText
-
- pop eax ecx
- clc
- return
-endp
-
-
-proc TEdit.Destroy, .obj
-begin
- mov eax, [.obj]
- stdcall StrDel, [eax+TEdit._Text]
- return
-endp
-
-
-proc TEdit.Get, .obj, .paramID
-begin
- stdcall IsObject, [.obj], CEdit
- jc .exit
-
- cmp [.paramID], TEdit.Text
- je .gettext
-
- stc
-.exit:
- return
-
-.gettext:
- mov eax, [.obj]
- stdcall StrDup, [eax+TEdit._Text]
- clc
- return
-endp
-
-
-
-
-proc TEdit.Set, .obj, .paramID, .value
-begin
- push esi
-
- mov esi, [.obj]
-
- cmp [.paramID], TEdit.Text
- je .settext
-
- stc
- pop esi
- return
-
-.settext:
- push eax
- mov [esi+TEdit._Start], 0
- mov [esi+TEdit._Pos], 0
- mov [esi+TEdit._Sel], 0
-
- lea eax, [esi+TEdit._Text]
- stdcall SetString, eax, [.value]
- stdcall StrLenUtf8, [esi+TEdit._Text], -1
- mov [esi+TEdit._Len], eax
-
- execute esi, TEdit.Refresh
- clc
- pop eax
- pop esi
- return
-endp
-
-
-
-
-
-
-proc TEdit.SysEventHandler, .pObj, .pEvent
-.changes dd ?
-.prevpos dd ?
-.PosChanged = 1
-.NeedRefresh = 2
-.ShowCaret = 4
-begin
- push eax ebx ecx edx esi edi
-
- mov [.changes], 0
- mov esi, [.pObj]
- mov ebx, [.pEvent]
- mov eax, [ebx+TSysEvent.event]
-
- cmp eax, sePaint
- je .onpaint
-
- cmp eax, seKbdKeyPress
- je .keypress
-
- cmp eax, seFocusIn
- je .focusin
-
- cmp eax, seFocusOut
- je .focusout
-
-.finish:
- stc
- pop edi esi edx ecx ebx eax
- return
-
-;............................................................................................
-
-.focusin:
- mov [esi+TEdit._Focused], TRUE
- stdcall CaretAttach, esi
- or [.changes], .PosChanged or .ShowCaret
- jmp .endmove
-
-.focusout:
- stdcall CaretShow, FALSE
- mov [esi+TEdit._Focused], FALSE
- or [.changes], .PosChanged
- jmp .endmove
-
-;............................................................................................
-
-.keypress:
-; mov eax, [ebx+TKeyboardEvent.kbdStatus]
-; OutputRegister regEAX, 16
-
- mov eax, [esi+TEdit._Pos]
- mov [.prevpos], eax
-
- mov eax, [ebx+TKeyboardEvent.key]
- test eax, eax
- jz .no_char
-
- cmp eax, $20
- jb .no_char
-
- cmp eax, $7f
- je .no_char
-
- push eax
-
- call .ClearSelection
-
- stdcall StrPtr, [esi+TEdit._Text]
- mov ecx, eax
- stdcall StrOffsUtf8, eax, [esi+TEdit._Pos]
- sub ecx, eax
- neg ecx
-
- pop eax
- stdcall StrCharInsert, [esi+TEdit._Text], eax, ecx
- inc [esi+TEdit._Len]
-
- mov [ebx+TKeyboardEvent.kbdStatus], 0
- or [.changes], .NeedRefresh
- jmp .right
-
-.no_char:
- mov eax, [ebx+TKeyboardEvent.scancode]
-
- cmp eax, keyLeftNumpad
- je .left
- cmp eax, keyLeft
- je .left
-
- cmp eax, keyRightNumpad
- je .right
- cmp eax, keyRight
- je .right
-
- cmp eax, keyHomeNumpad
- je .home
- cmp eax, keyHome
- je .home
-
- cmp eax, keyEndNumpad
- je .end
- cmp eax, keyEnd
- je .end
-
- cmp eax, keyDelNumpad
- je .del
- cmp eax, keyDelete
- je .del
-
- cmp eax, keyBackSpace
- je .backdel
-
- jmp .finish
-
-.left:
- cmp [esi+TEdit._Pos], 0
- jle .endmove
-
- or [.changes], .PosChanged
- dec [esi+TEdit._Pos]
- jmp .endmove
-
-.right:
- mov eax, [esi+TEdit._Pos]
- cmp eax, [esi+TEdit._Len]
- jae .finish
-
- or [.changes], .PosChanged
- inc [esi+TEdit._Pos]
- jmp .endmove
-
-.home:
- mov [esi+TEdit._Pos], 0
- mov [esi+TEdit._Start], 0
- mov [.changes], .PosChanged or .NeedRefresh
- jmp .endmove
-
-.end:
- mov eax, [esi+TEdit._Len]
- mov [esi+TEdit._Pos], eax
- or [.changes], .PosChanged
- jmp .endmove
-
-.backdel:
- call .ClearSelection
- jnc .endmove
-
- cmp [esi+TEdit._Pos], 0
- jle .endmove
-
- or [.changes], .PosChanged
- dec [esi+TEdit._Pos]
-
-.del:
- call .ClearSelection
- jnc .endmove
-
- mov eax, [esi+TEdit._Pos]
- cmp eax, [esi+TEdit._Len]
- jae .finish ; can't delete after the end of string.
-
- stdcall StrPtr, [esi+TEdit._Text]
-
- mov ecx, eax
- stdcall StrOffsUtf8, eax, [esi+TEdit._Pos]
- sub eax, ecx
-
- stdcall StrSplit, [esi+TEdit._Text], eax
- mov ebx, eax
-
- stdcall StrPtr, ebx
- stdcall DecodeUtf8, [eax]
-
- stdcall StrCopyPart, ebx, ebx, edx, -1
- stdcall StrCat, [esi+TEdit._Text], ebx
- stdcall StrDel, ebx
-
- dec [esi+TEdit._Len]
- or [.changes], .NeedRefresh
-
-.endmove:
- mov ebx, [.pEvent]
- mov eax, [esi+TEdit._Pos]
- cmp [ebx+TSysEvent.event], seKbdKeyPress
- jne .setselection
-
- test [ebx+TKeyboardEvent.kbdStatus], maskShift
- jnz .refresh
-
-.setselection:
- mov ecx, [.prevpos]
- cmp ecx, [esi+TEdit._Sel]
- je @f
- or [.changes], .NeedRefresh
-@@:
- mov [esi+TEdit._Sel], eax
-
- test [.changes], .NeedRefresh
- jz .caretmove
-
-.refresh:
- execute [.pObj], TEdit.Refresh
-
-.caretmove:
- cmp [esi+TEdit._Focused], 0
- je .finish
-
- test [.changes], .PosChanged
- jz .showcaret
-
- mov eax, [esi+TEdit._Pos]
- cmp eax, [esi+TEdit._Start]
- jl .scroll
-
- stdcall StrPtr, [esi+TEdit._Text]
- mov edi, eax
-
- stdcall StrOffsUtf8, edi, [esi+TEdit._Pos]
- mov ecx, eax
-
- stdcall StrOffsUtf8, edi, [esi+TEdit._Start]
- sub ecx, eax ; offset to char under cursor.
- jns .leftok
-
-.scroll:
- mov eax, [esi+TEdit._Start]
- sub eax, 8
- test eax, eax
- jns @f
- xor eax, eax
-@@:
- mov [esi+TEdit._Start], eax
- mov [.changes], .PosChanged or .NeedRefresh
- jmp .endmove
-
-.leftok:
- mov edi, eax ; pointer to start of the text.
-
- stdcall AllocateContext, [esi+TEdit.handle]
- push eax
-
- stdcall GetTextBounds, eax, edi, ecx, 0
- lea ecx, [eax+2] ; x coordinate of the cursor.
- add ecx, [esi+TEdit._MarginLeft]
-
- stdcall ReleaseContext ; from the stack.
-
- mov eax, [esi+TEdit._width]
- sub eax, [esi+TEdit._MarginRight]
- sub eax, ecx
- cmp eax, 2
- jge .caretok
-
- mov eax, [esi+TEdit._Start]
- add eax, 8
- cmp eax, [esi+TEdit._Len]
- jle @f
- mov eax, [esi+TEdit._Len]
-@@:
- mov [esi+TEdit._Start], eax
-
- mov [.changes], .PosChanged or .NeedRefresh
- jmp .endmove
-
-
-.caretok:
- mov edx, [esi+TEdit._height]
- sub edx, 4
-
- stdcall CaretChange, ecx, 2, 1, edx
-
-.showcaret:
- test [.changes], .ShowCaret
- jz .finish
-
- stdcall CaretShow, TRUE
- jmp .finish
-
-;............................................................................................
-
-.onpaint:
-locals
- .bounds TBounds
- .selbeg dd ?
- .selend dd ?
- .ypos dd ?
-endl
- mov eax, [esi+TEdit._Pos]
- mov ecx, [esi+TEdit._Sel]
- cmp eax,ecx
- jle @f
- xchg eax, ecx
-@@:
- mov [.selbeg], eax
- mov [.selend], ecx
-
- mov ecx, [esi+TEdit._width]
- mov eax, [esi+TEdit._height]
-
- mov [.bounds.x], 0
- mov [.bounds.y], 0
- mov [.bounds.width], ecx
- mov [.bounds.height], eax
-
- lea eax, [.bounds]
- stdcall [DrawBox], [ebx+TPaintEvent.context], eax, [clEditBk], bxSunken
-
- mov eax, [esi+TEdit._MarginLeft]
- mov ecx, [esi+TEdit._MarginRight]
- add [.bounds.x], eax
- sub [.bounds.width], eax
- sub [.bounds.width], ecx
- cmp [.bounds.width], 0
- jle .finish
-
- mov ecx, [esi+TEdit._Start]
-
- stdcall StrOffsUtf8, [esi+TEdit._Text], ecx
- mov edi, eax
-
- mov eax, [.bounds.y]
- add eax, [.bounds.height]
- sub eax, 4
- mov [.ypos], eax ; y position of the characters.
-
-.drawloop:
- stdcall DecodeUtf8, [edi]
- jc .finish
-
- test eax, eax
- jz .eraseremaining
-
- mov eax, [clEditTxt]
- cmp ecx, [.selbeg]
- jl .colorok
- cmp ecx, [.selend]
- jge .colorok
- mov eax, [clEditSelTxt]
-.colorok:
- push eax 0 [.ypos] [.bounds.x] edx edi
-
- push 0 edx edi
- add edi, edx
- stdcall GetTextBounds, [ebx+TPaintEvent.context] ; remaining from the stack
-
- sub [.bounds.width], eax
- js .nodraw
-
- cmp ecx, [.selbeg]
- jl .drawtxt
- cmp ecx, [.selend]
- jge .drawtxt
-
- mov esi, [.ypos]
- sub esi, edx
- add edx, 2
- stdcall DrawFillRect, [ebx+TPaintEvent.context], [.bounds.x], [.bounds.y], eax, [.bounds.height], [clEditSel]
-
-.drawtxt:
- add [.bounds.x], eax
- stdcall DrawString, [ebx+TPaintEvent.context] ; remaining from the stack
-
- inc ecx
- jmp .drawloop
-
-.nodraw:
- add esp, 24 ; 6*4
- jmp .finish
-
-.eraseremaining:
- stdcall DrawFillRect, [ebx+TPaintEvent.context], [.bounds.x], [.bounds.y], [.bounds.width], [.bounds.height], [clEditBk]
- jmp .finish
-
-.ClearSelection:
- mov eax, [esi+TEdit._Pos]
- mov ecx, [esi+TEdit._Sel]
- cmp eax, [esi+TEdit._Sel]
- je .noselection ; there is no selection.
- jg @f
- xchg eax, ecx ; eax=end_selection; ecx=beg_selection
-@@:
- add [esi+TEdit._Len], ecx
- sub [esi+TEdit._Len], eax
- mov [esi+TEdit._Pos], ecx
- mov [esi+TEdit._Sel], ecx
-
- push -1
- stdcall StrOffsUtf8, [esi+TEdit._Text], eax
- push eax
- stdcall StrOffsUtf8, [esi+TEdit._Text], ecx
- push eax
- stdcall StrPtr, [esi+TEdit._Text]
- sub [esp], eax ; begin of the selection
- sub [esp+4], eax
- mov eax, [esp]
- sub [esp+4], eax ; length of the selection
-
- stdcall StrSplit, [esi+TEdit._Text] ; position from the stack
- mov ecx, eax
- stdcall StrCopyPart, ecx, ecx ; pos and length from the stack.
- stdcall StrCat, [esi+TEdit._Text], ecx
- stdcall StrDel, ecx
-
- or [.changes], .PosChanged or .NeedRefresh
- clc
- retn
-
-.noselection:
- stc
- retn
-endp
-
-
-endmodule
-
-
-; stdcall DecodeUtf8, [edi]
-; jc .finish
-;
-; test eax, eax
-; jz .eraseremaining
-;
-; mov eax, [clEditTxt]
-; mov esi, [clEditBk]
-; cmp ecx, [.selbeg]
-; jl .colorok
-; cmp ecx, [.selend]
-; jge .colorok
-; mov eax, [clEditSelTxt]
-; mov esi, [clEditSel]
-;.colorok:
-; push eax 0 [.ypos] [.bounds.x] edx edi
-;
-; push 0 edx edi
-; add edi, edx
-; stdcall GetTextBounds, [ebx+TPaintEvent.context] ; remaining from the stack
-;
-; add eax, 2
-; stdcall DrawFillRect, [ebx+TPaintEvent.context], [.bounds.x], [.bounds.y], eax, [.bounds.height], esi
-; sub eax, 2
-;
-; add [.bounds.x], eax
-; sub [.bounds.width], eax
-; jc .nodraw
-;
-; stdcall DrawString, [ebx+TPaintEvent.context] ; remaining from the stack
-;
-; inc ecx
-; jmp .drawloop
-;
-;.nodraw:
-; add esp, 24 ; 6*4
-; jmp .finish
-;
-;.eraseremaining:
-; stdcall DrawFillRect, [ebx+TPaintEvent.context], [.bounds.x], [.bounds.y], [.bounds.width], [.bounds.height], [clEditBk]
-; jmp .finish
-;
-;endp
-;
DELETED freshlib/gui/TForm.asm
Index: freshlib/gui/TForm.asm
==================================================================
--- freshlib/gui/TForm.asm
+++ /dev/null
@@ -1,118 +0,0 @@
-; _______________________________________________________________________________________
-;| |
-;| ..::FreshLib::.. Free, open source. Licensed under "Fresh artistic license." |
-;|_______________________________________________________________________________________|
-;
-; Description: TForm object class
-;
-; Target OS: Any
-;
-; Dependencies:
-;
-; Notes: Represents form window that to serve as parent window for other controls.
-;_________________________________________________________________________________________
-module "TForm library"
-
-
-ObjectClass Form, \
- Window, \
- TForm.Create, \
- 0, \
- TForm.Get, \
- TForm.Set, \
- 0, \
- TForm.SysEventHandler
-
-
-mrNone = 0
-mrOK = 1
-mrCancel = 2
-mrAbort = 3
-mrRetry = 4
-mrIgnore = 5
-mrYes = 6
-mrNo = 7
-mrMaybe = 8
-
-
-object TForm, TWindow
-
- .ModalResult dd ?
-
- .OnClose dd ? ; On close window event handler.
-
- param .type
-endobj
-
-
-proc TForm.Create, .obj
-begin
- stdcall Set, [.obj], TWindow.borderKind, borderFull
- return
-endp
-
-
-; OS independent code.
-
-proc TForm.Get, .obj, .paramID
-begin
- stc
- return
-endp
-
-
-
-proc TForm.Set, .obj, .paramID, .value
-begin
- stc
- return
-endp
-
-
-
-proc TForm.SysEventHandler, .pObj, .pEvent
-begin
- push ebx esi
- mov ebx, [.pEvent]
- cmp [ebx+TSysEvent.event], sePaint
- je .onpaint
-
- cmp [ebx+TSysEvent.event], seCloseRequest
- je .close_request
-
-.finish:
- stc
- pop esi ebx
- return
-
-.onpaint:
- mov esi, [.pObj]
-
- mov eax, [esi+TWindow._width]
- mov ecx, [esi+TWindow._height]
-
- stdcall DrawFillRect, [ebx+TPaintEvent.context], 0, 0, eax, ecx, [clDialogBk]
- jmp .finish
-
-.close_request:
-; DebugMsg "Close request"
- cmp [esi+TForm.OnClose], 0
- je @f
-
- stdcall [esi+TForm.OnClose], esi, [ebx+TCloseEvent.reason] ; if OnClose return CF=0 the form is destroyed. Else, the form is not destroyed.
- jc .finish
-
-@@:
- stdcall Set, [.pObj], TForm.Visible, FALSE
- stdcall Destroy, [.pObj]
-
- DebugMsg "Form destroyed"
-
-.destroyed:
- clc
- pop esi ebx
- return
-endp
-
-
-endmodule
DELETED freshlib/gui/TImageLabel.asm
Index: freshlib/gui/TImageLabel.asm
==================================================================
--- freshlib/gui/TImageLabel.asm
+++ /dev/null
@@ -1,198 +0,0 @@
-; _______________________________________________________________________________________
-;| |
-;| ..::FreshLib::.. Free, open source. Licensed under "Fresh artistic license." |
-;|_______________________________________________________________________________________|
-;
-; Description: TImageLabel object class
-;
-; Target OS: Any
-;
-; Dependencies:
-;
-; Notes: Represents GUI picture or image.
-;_________________________________________________________________________________________
-module "TImageLabel library"
-
-ObjectClass ImageLabel, \
- Window, \
- 0, \
- 0, \
- TImageLabel.Get, \
- TImageLabel.Set, \
- 0, \
- TImageLabel.SysEventHandler
-
-iaLeft = 0
-iaRight = 1
-iaCenter = 2
-iaStretchH = 3
-
-iaTop = $0
-iaBottom = $100
-iaMiddle = $200
-iaStrechV = $300
-
-object TImageLabel, TWindow
- .FImageAlign dd ?
- .FImage dd ?
- .FMask dd ?
- .FBackground dd ?
-
- param .ImageAlign ; image align flags.
- param .Image ; TImage object
- param .Mask
-endobj
-
-
-
-proc TImageLabel.Get, .obj, .paramID
-begin
- mov eax, [.obj]
-
- stdcall IsObject, eax, CImageLabel
- jc .exit
-
- cmp [.paramID], TImageLabel.ImageAlign
- je .getimagealign
-
- cmp [.paramID], TImageLabel.Image
- je .getimage
-
- cmp [.paramID], TImageLabel.Mask
- je .getmask
-
- stc
-.exit:
- return
-
-.getimagealign:
- mov eax, [eax+TImageLabel.FImageAlign]
- clc
- return
-
-.getimage:
- mov eax, [eax+TImageLabel.FImage]
- clc
- return
-
-.getmask:
- mov eax, [eax+TImageLabel.FMask]
- clc
- return
-endp
-
-
-
-proc TImageLabel.Set, .obj, .paramID, .value
-begin
- push eax
-
- mov eax, [.obj]
- stdcall IsObject, eax, CImageLabel
- jc .exit
-
- cmp [.paramID], TImageLabel.ImageAlign
- je .setimagealign
-
- cmp [.paramID], TImageLabel.Image
- je .setimage
-
- cmp [.paramID], TImageLabel.Mask
- je .setmask
-
- stc
-.exit:
- pop eax
- return
-
-.setimage:
- push [.value]
- pop [eax+TImageLabel.FImage]
- jmp .refresh
-
-.setmask:
- push [.value]
- pop [eax+TImageLabel.FMask]
- jmp .refresh
-
-.setimagealign:
- push [.value]
- pop [eax+TImageLabel.FImageAlign]
-
-.refresh:
- execute [.obj], TWindow.Refresh
- clc
- pop eax
- return
-endp
-
-
-
-proc TImageLabel.SysEventHandler, .pObj, .pEvent
-begin
- push eax ebx ecx edx esi
-
- mov esi, [.pObj]
- mov ebx, [.pEvent]
- mov eax, [ebx+TSysEvent.event]
-
- cmp eax, sePaint
- je .onpaint
-
-.finish:
- stc
- pop esi edx ecx ebx eax
- return
-
-.onpaint:
- locals
- .bounds TBounds
- endl
- mov ecx, [esi+TImageLabel._width]
- mov eax, [esi+TImageLabel._height]
- mov [.bounds.x], 0
- mov [.bounds.y], 0
- mov [.bounds.width], ecx
- mov [.bounds.height], eax
-
- stdcall SetDrawMode, [ebx+TPaintEvent.context], cmCopy
- stdcall DrawFillRect, [ebx+TPaintEvent.context], [.bounds.x], [.bounds.y], [.bounds.width], [.bounds.height], [clDialogBk]
-
- mov eax, [esi+TImageLabel.FImage]
- mov ecx, [.bounds.width]
- mov edx, [.bounds.height]
- sub ecx, [eax+TImage.width]
- sub edx, [eax+TImage.height]
-
- mov eax, [esi+TImageLabel.FImageAlign]
-
- cmp al, iaRight
- je .x_ok
- cmp al, iaCenter
- je .x_center
- xor ecx, ecx
- jmp .x_ok
-.x_center:
- sar ecx, 1
-.x_ok:
- cmp ah, iaBottom /256
- je .y_ok
- cmp ah, iaMiddle / 256
- je .y_center
- xor edx, edx
- jmp .y_ok
-.y_center:
- sar edx, 1
-.y_ok:
- stdcall DrawMaskedImage, [ebx+TPaintEvent.context], [esi+TImageLabel.FMask], [esi+TImageLabel.FImage], ecx, edx
- jmp .finish
-endp
-
-
-
-
-
-
-
-
-endmodule
DELETED freshlib/gui/TLabel.asm
Index: freshlib/gui/TLabel.asm
==================================================================
--- freshlib/gui/TLabel.asm
+++ /dev/null
@@ -1,136 +0,0 @@
-; _______________________________________________________________________________________
-;| |
-;| ..::FreshLib::.. Free, open source. Licensed under "Fresh artistic license." |
-;|_______________________________________________________________________________________|
-;
-; Description: TLabel object class
-;
-; Target OS: Any
-;
-; Dependencies:
-;
-; Notes: Not finished.
-;_________________________________________________________________________________________
-module "TLabel library"
-
-ObjectClass Label, \
- Window, \
- 0, \
- 0, \
- TLabel.Get, \
- TLabel.Set, \
- 0, \
- TLabel.SysEventHandler
-
-
-object TLabel, TWindow
- .Ftextalign dd ?
-
- param .TextAlign ; text align flags.
- param .Control ; control that to be activated
-endobj
-
-
-
-proc TLabel.Get, .obj, .paramID
-begin
- mov eax, [.obj]
-
- stdcall IsObject, eax, CLabel
- jc .exit
-
- cmp [.paramID], TLabel.TextAlign
- je .gettextalign
-
- stc
-.exit:
- return
-
-.gettextalign:
- mov eax, [eax+TLabel.Ftextalign]
- clc
- return
-endp
-
-
-
-proc TLabel.Set, .obj, .paramID, .value
-begin
- push eax
-
- mov eax, [.obj]
- stdcall IsObject, eax, CLabel
- jc .exit
-
- cmp [.paramID], TLabel.TextAlign
- je .settextalign
-
- stc
-.exit:
- pop eax
- return
-
-.settextalign:
- push [.value]
- pop [eax+TLabel.Ftextalign]
-
-.refresh:
- execute [.obj], TWindow.Refresh
- clc
- pop eax
- return
-endp
-
-
-
-proc TLabel.SysEventHandler, .pObj, .pEvent
-begin
- push eax ebx ecx edx esi
-
- mov esi, [.pObj]
- mov ebx, [.pEvent]
- mov eax, [ebx+TSysEvent.event]
-
- cmp eax, sePaint
- je .onpaint
-
-.finish:
- stc
- pop esi edx ecx ebx eax
- return
-
-.onpaint:
- locals
- .bounds TBounds
- endl
-
- mov ecx, [esi+TLabel._width]
- mov eax, [esi+TLabel._height]
- mov [.bounds.x], 0
- mov [.bounds.y], 0
- mov [.bounds.width], ecx
- mov [.bounds.height], eax
- lea eax, [.bounds]
- stdcall [DrawBox], [ebx+TPaintEvent.context], eax, [clDialogBk], bxNone
-
- stdcall Get, esi, TWindow.Caption
- test eax, eax
- jz .finish
-
- push eax eax
- stdcall StrLen, eax
- mov ecx, eax
- pop eax
- lea edx, [.bounds]
- stdcall DrawTextBox, [ebx+TPaintEvent.context], eax, edx, [esi+TLabel.Ftextalign], 0, [clDialogTxt]
- stdcall StrDel ; from the stack
- jmp .finish
-endp
-
-
-
-
-
-
-
-endmodule
DELETED freshlib/gui/TMenu.asm
Index: freshlib/gui/TMenu.asm
==================================================================
--- freshlib/gui/TMenu.asm
+++ /dev/null
@@ -1,97 +0,0 @@
-; _______________________________________________________________________________________
-;| |
-;| ..::FreshLib::.. Free, open source. Licensed under "Fresh artistic license." |
-;|_______________________________________________________________________________________|
-;
-; Description: TMenu object class
-;
-; Target OS: Any
-;
-; Dependencies:
-;
-; Notes: Represents main menu or popup menu objects.
-;_________________________________________________________________________________________
-module "TMenu library"
-
-ObjectClass Menu, \
- Window, \
- TMenu.Create, \
- TMenu.Destroy,\
- TMenu.Get, \
- TMenu.Set, \
- TMenu.ExecCmd,\
- TMenu.SysEventHandler
-
-; The inherited TWindow.caption serves as a menu item caption in the parent menu.
-; The children TMenu objects are reparent to the root, and their pointers are stored in the
-; list of TMenuItem elements.
-object TMenu, TWindow
- .pForm dd ? ; pointer to TForm object. If NULL, the menu is popup menu.
- .pItems dd ? ;
-
- method .Show, .parent, .kind
-endobj
-
-
-
-proc TMenu.Create, .obj
-begin
- return
-endp
-
-
-proc TMenu.Destroy, .obj
-begin
- return
-endp
-
-
-proc TMenu.Get, .obj, .param
-begin
- return
-endp
-
-
-proc TMenu.Set, .obj, .param
-begin
-
- return
-endp
-
-
-proc TMenu.ExecCmd, .obj, .method
-begin
- cmp [.method], TMenu.Show
- je .show
-
- stc
- return
-
-; Method show
-.show:
-virtual at esi
- .parent dd ?
- .kind dd ?
-end virtual
-
- mov ebx, [.obj]
-; First check item count and set proper size of the menu window.
-
-
-
-
- return
-endp
-
-
-proc TMenu.SysEventHandler, .obj, .event
-begin
-
- return
-endp
-
-
-
-endmodule
-
-
DELETED freshlib/gui/TMenuItem.asm
Index: freshlib/gui/TMenuItem.asm
==================================================================
--- freshlib/gui/TMenuItem.asm
+++ /dev/null
@@ -1,40 +0,0 @@
-; _______________________________________________________________________________________
-;| |
-;| ..::FreshLib::.. Free, open source. Licensed under "Fresh artistic license." |
-;|_______________________________________________________________________________________|
-;
-; Description: TMenuItem object class
-;
-; Target OS: Any
-;
-; Dependencies:
-;
-; Notes: TMenuItems are the items of the GUI menu objects.
-;_________________________________________________________________________________________
-module "TMenuItem library"
-
-ObjectClass MenuItem, \
- Object, \
- TMenu.Create, \
- TMenu.Destroy,\
- TMenu.Get, \
- TMenu.Set, \
- TMenu.ExecCmd,\
- TMenu.SysEventHandler
-
-mikCommand = 0
-mikSubmenu = 1
-mikSeparator = 2
-
-
-object TMenuItem, TObject
- .parent dd ? ; pointer to TMenu object.
- .kind dd ? ; mikCommand, mikSubmenu or mikSeparator
- .pAction dd ? ; depending on the kind. Pointer to TAction or handle of string with the text.
- .child dd ? ; pointer to the child TMenu object
-
- method Paint, .context, .x, .y, .width, .height
-endobj
-
-
-endmodule
DELETED freshlib/gui/TObject.asm
Index: freshlib/gui/TObject.asm
==================================================================
--- freshlib/gui/TObject.asm
+++ /dev/null
@@ -1,59 +0,0 @@
-; _______________________________________________________________________________________
-;| |
-;| ..::FreshLib::.. Free, open source. Licensed under "Fresh artistic license." |
-;|_______________________________________________________________________________________|
-;
-; Description: TObject object class.
-;
-; Target OS: Any
-;
-; Dependencies:
-;
-; Notes: TObject is the root member of FreshLib objects tree.
-;_________________________________________________________________________________________
-module "TObject library"
-
-ObjectClass Object, \
- Root, \
- 0, \
- TObject.Destroy, \
- 0, \
- 0, \
- 0, \
- 0
-
-
-object TObject
- .ptrClass dd ? ; pointer to the object class structure.
-
- .mxAccess dd ? ; access mutex. Procedures from objects.asm will use it to ensure thread safety.
- .ptrVar dd ? ; pointer to the variable that keep the pointer to the object. This field can be 0. If not, Destroy procedure will set it to 0 on destroy.
-
- .OnCreate dd ? ; user event handlers.
- .OnDestroy dd ?
-
- method .AddChild, .objchild ; this method is not implemented in TObject, but every descendent can implement it's own parent/child system.
-endobj
-
-
-
-proc TObject.Destroy, .obj
-begin
- push eax
- mov eax, [.obj]
-
- cmp [eax+TObject.OnDestroy], 0
- je .exit
-
- pushad
- stdcall [eax+TObject.OnDestroy], eax
- popad
-
-.exit:
- pop eax
- return
-endp
-
-
-
-endmodule
DELETED freshlib/gui/TProgressbar.asm
Index: freshlib/gui/TProgressbar.asm
==================================================================
--- freshlib/gui/TProgressbar.asm
+++ /dev/null
@@ -1,190 +0,0 @@
-; _______________________________________________________________________________________
-;| |
-;| ..::FreshLib::.. Free, open source. Licensed under "Fresh artistic license." |
-;|_______________________________________________________________________________________|
-;
-; Description: TProgressBar object class; Simple progress bar control.
-;
-; Target OS: Any
-;
-; Dependencies:
-;
-; Notes:
-;_________________________________________________________________________________________
-module "TProgressbar library"
-
-ObjectClass Progress, \
- Window, \
- 0, \
- 0, \
- TProgress.Get, \
- TProgress.Set, \
- TProgress.ExecCmd, \
- TProgress.SysEventHandler
-
-object TProgress, TWindow
- ._Pos dd ?
- ._Max dd ?
- ._Color dd ?
-
- param .Pos
- param .Max
- param .Color
-
- method .Step
-endobj
-
-
-
-proc TProgress.Get, .pobj, .paramID
-begin
- push ecx
-
- stdcall IsObject, [.pobj], CProgress
- jc .exit
-
- mov eax, [.pobj]
- mov ecx, [.paramID]
-
- cmp ecx, TProgress.Pos
- jb .exit
- cmp ecx, TProgress.Color
- ja .exit
-
- sub ecx, TProgress.Pos
- pushd [eax+TProgress._Pos+4*ecx]
- pop eax
-
- clc
- pop ecx
- return
-
-.exit:
- stc
- pop ecx
- return
-endp
-
-
-
-proc TProgress.Set, .pobj, .paramID, .value
-begin
- push eax ecx
-
- stdcall IsObject, [.pobj], CProgress
- jc .exit
-
- mov eax, [.pobj]
- mov ecx, [.paramID]
-
- cmp ecx, TProgress.Pos
- jb .exit
- cmp ecx, TProgress.Color
- ja .exit
-
- sub ecx, TProgress.Pos
- pushd [.value]
- popd [eax+TProgress._Pos+4*ecx]
-
- execute [.pobj], TProgress.Refresh
-
- clc
- pop ecx eax
- return
-
-.exit:
- stc
- pop ecx eax
- return
-endp
-
-
-proc TProgress.SysEventHandler, .pobj, .pEvent
-begin
- push eax ebx ecx esi
-
- mov ebx, [.pEvent]
- cmp [ebx+TSysEvent.event], sePaint
- je .paint
-
-.finish:
- stc
- pop esi ecx ebx eax
- return
-
-.paint:
-locals
- .bounds TBounds
- .style TLineStyle
-endl
- mov [.bounds.x], 0
- mov [.bounds.y], 0
- mov eax, [esi+TProgress._width]
- mov ecx, [esi+TProgress._height]
- mov [.bounds.width], eax
- mov [.bounds.height], ecx
-
- lea eax, [.bounds]
- stdcall [DrawBox], [ebx+TPaintEvent.context], eax, 0, bxSunken or bxNoFill
-
- stdcall DrawRectangle, [ebx+TPaintEvent.context], eax, [clDialogBk]
-
- inc [.bounds.x]
- inc [.bounds.y]
- sub [.bounds.width], 2
- sub [.bounds.height], 2
-
- mov eax, [esi+TProgress._Pos]
- mov ecx, [esi+TProgress._Max]
- test ecx, ecx
- jnz @f
- inc ecx
-@@:
- cmp eax, ecx
- jle @f
- mov eax, ecx
-@@:
- imul eax, [.bounds.width]
- cdq
- idiv ecx
-
- stdcall DrawFillRect, [ebx+TPaintEvent.context], [.bounds.x], [.bounds.y], eax, [.bounds.height], [esi+TProgress._Color]
- sub [.bounds.width], eax
- inc eax
- inc [.bounds.width]
- stdcall DrawFillRect, [ebx+TPaintEvent.context], eax, [.bounds.y], [.bounds.width], [.bounds.height], [clDialogBk]
-
- jmp .finish
-endp
-
-
-
-
-proc TProgress.ExecCmd, .self, .method
-begin
- cmp [.method], TProgress.Step
- je .step
- stc
- return
-
-;-------------------------------------------------------------------------
-.step:
- push eax ecx
-
- mov eax, [.self]
- mov ecx, [eax+TProgress._Pos]
- cmp ecx, [eax+TProgress._Max]
- jge .exit
-
- inc [eax+TProgress._Pos]
- execute eax, TProgress.Refresh
-
-.exit:
- pop ecx eax
- clc
- return
-endp
-
-
-
-endmodule
DELETED freshlib/gui/TScrollWindow.asm
Index: freshlib/gui/TScrollWindow.asm
==================================================================
--- freshlib/gui/TScrollWindow.asm
+++ /dev/null
@@ -1,502 +0,0 @@
-; _______________________________________________________________________________________
-;| |
-;| ..::FreshLib::.. Free, open source. Licensed under "Fresh artistic license." |
-;|_______________________________________________________________________________________|
-;
-; Description: TScrollWindow object class
-;
-; Target OS: Any
-;
-; Dependencies:
-;
-; Notes: TScrollWindow is window that may have scrollers to scroll the client area.
-;_________________________________________________________________________________________
-module "TScrollWindow library"
-
-ObjectClass ScrollWindow, \
- Window, \
- TScrollWindow.Create, \
- 0, \
- TScrollWindow.Get, \
- TScrollWindow.Set, \
- TScrollWindow.ExecCmd, \
- TScrollWindow.SysEventHandler
-
-
-struct TScrollbar
- .Max dd ?
- .Page dd ?
- .Pos dd ?
-
- ._Drag dd ?
-ends
-
-
-
-object TScrollWindow, TWindow
- ._HScroller TScrollbar
- ._VScroller TScrollbar
-
- method HScrollSet, .Pos, .Max, .Page ; only params >=0 are set. If<0 ignored.
- method VScrollSet, .Pos, .Max, .Page
-endobj
-
-
-ScrollBarWidth = 16
-MinScrollBarWidth = 12
-
-;_________________________________________________________________________________________
-
-proc TScrollWindow.Create, .pobj
-begin
-; push eax
-; mov eax, [.pobj]
-
-; mov [eax+TScrollWindow._HScroller.Max], 255
-; mov [eax+TScrollWindow._HScroller.Page], 1
-; mov [eax+TScrollWindow._HScroller.Pos], 10
-
-; mov [eax+TScrollWindow._VScroller.Max], 1000
-; mov [eax+TScrollWindow._VScroller.Page], 1
-; mov [eax+TScrollWindow._VScroller.Pos], 450
-
-; pop eax
- return
-endp
-
-
-
-;_________________________________________________________________________________________
-
-
-proc TScrollWindow.Get, .pobj, .paramID
-begin
- stc
- return
-endp
-
-
-;_________________________________________________________________________________________
-
-
-proc TScrollWindow.Set, .pobj, .paramID, .value
-begin
-
- stc
- return
-endp
-
-
-;_________________________________________________________________________________________
-
-
-proc TScrollWindow.SysEventHandler, .pobj, .pEvent
- .event TScrollEvent
-begin
- push eax ebx edx esi edi
- mov esi, [.pobj]
- mov ecx, [.pEvent]
-
- cmp [ecx+TSysEvent.event], sePaint
- je .paint
-
- cmp [ecx+TSysEvent.event], seMouseBtnPress
- je .btnpress
-
- cmp [ecx+TSysEvent.event], seMouseBtnRelease
- je .btnrelease
-
- cmp [ecx+TSysEvent.event], seMouseMove
- je .mousemove
-
-.continue:
- stc
-.finish:
- pop edi esi edx ebx eax
- return
-
-
-;.........................................................................................
-
-.paint:
-locals
- .recth TBounds
- .rectv TBounds
- .rectx TBounds
-endl
- stdcall Get, esi, TScrollWindow.FreeArea
- mov ebx, eax
-
- mov eax, [ebx+TBounds.x]
- mov edx, [ebx+TBounds.y]
- mov [.recth.x], eax
- mov [.rectv.y], edx
-
- add eax, [ebx+TBounds.width]
- add edx, [ebx+TBounds.height]
- mov [.rectv.x], eax
- mov [.recth.y], edx
-
- inc edx
- inc eax
- mov [.rectx.y], edx
- mov [.rectx.x], eax
-
- mov [.recth.height], ScrollBarWidth
- mov [.rectv.width], ScrollBarWidth
- mov [.rectx.width], ScrollBarWidth-1
- mov [.rectx.height], ScrollBarWidth-1
-
- mov eax, [ebx+TBounds.width]
- mov edx, [ebx+TBounds.height]
- inc eax
- inc edx
- mov [.recth.width], eax
- mov [.rectv.height], edx
-
- lea eax, [.rectx]
- stdcall [DrawBox], [ecx+TPaintEvent.context], eax, [clDialogBk], bxNone
-
- lea eax, [.recth]
- stdcall [DrawBox], [ecx+TPaintEvent.context], eax, [clScrollBk], bxSunken or bxNoFill
-
- lea eax, [.rectv]
- stdcall [DrawBox], [ecx+TPaintEvent.context], eax, [clScrollBk], bxSunken or bxNoFill
-
- lea eax, [esi+TScrollWindow._HScroller]
- stdcall _SliderPixels, eax, [.recth.width]
-
- push esi
- stdcall DrawFillRect, [ecx+TPaintEvent.context], [.recth.x], [.recth.y], eax, [.recth.height], [clScrollBk]
- mov esi, [.recth.width]
- sub esi, eax
- sub esi, edx
-
- add eax, [.recth.x]
- lea edi, [eax+edx]
- stdcall DrawFillRect, [ecx+TPaintEvent.context], edi, [.recth.y], esi, [.recth.height], [clScrollBk]
- pop esi
-
- mov [.rectx.x], eax
-
- mov [.rectx.width], edx
- push [.recth.y] [.recth.height]
- pop [.rectx.height] [.rectx.y]
-
- lea eax, [.rectx]
- stdcall [DrawSlider], [ecx+TPaintEvent.context], eax, [clScrollSlider], sliderHorizontal
-
- lea eax, [esi+TScrollWindow._VScroller]
- stdcall _SliderPixels, eax, [.rectv.height]
-
- push esi
- stdcall DrawFillRect, [ecx+TPaintEvent.context], [.rectv.x], [.rectv.y], [.rectv.width], eax, [clScrollBk]
- mov esi, [.rectv.height]
- sub esi, eax
- sub esi, edx
-
- add eax, [.rectv.y]
- lea edi, [eax+edx]
- stdcall DrawFillRect, [ecx+TPaintEvent.context], [.rectv.x], edi, [.rectv.width], esi, [clScrollBk]
- pop esi
-
- mov [.rectx.y], eax
-
- mov [.rectx.height], edx
- push [.rectv.x] [.rectv.width]
- pop [.rectx.width] [.rectx.x]
-
- lea eax, [.rectx]
- stdcall [DrawSlider], [ecx+TPaintEvent.context], eax, [clScrollSlider], sliderVertical
-
- clc
- jmp .finish
-
-;.........................................................................................
-
-.btnpress:
- stdcall __ScrollSetCursor, esi, [ecx+TMouseButtonEvent.x], [ecx+TMouseButtonEvent.y]
-
- cmp [ecx+TMouseButtonEvent.Button], mbLeft
- jne .continue
-
- stdcall _WhatScrollbar, esi, [ecx+TMouseButtonEvent.x], [ecx+TMouseButtonEvent.y]
- jc .continue ; not found
-
-; here ecx=height of the scrollbar
-; edi= ptr to TScrollbar structure
-; ebx= coordinate of the mouse in the scrollbar
-
- stdcall _SliderPixels, edi, ecx
- sub ebx, eax
- jl .before
- cmp ebx, edx
- jg .after
-
-; inside the slider - capture the mouse.
- mov [edi+TScrollbar._Drag], ebx
- stdcall MouseCapture, [esi+TWindow.handle]
- jmp .continue
-
-.before:
-.after:
- jmp .continue
-
-;.........................................................................................
-
-.btnrelease:
- stdcall __ScrollSetCursor, esi, [ecx+TMouseButtonEvent.x], [ecx+TMouseButtonEvent.y]
-
- xor eax, eax
- mov [esi+TScrollWindow._HScroller._Drag], eax
- mov [esi+TScrollWindow._VScroller._Drag], eax
-
- stdcall MouseCapture, eax
- jmp .continue
-
-;.........................................................................................
-
-.mousemove:
- mov ecx, [.pEvent]
- stdcall __ScrollSetCursor, esi, [ecx+TMouseMoveEvent.x], [ecx+TMouseMoveEvent.y]
-
- mov ecx, [.pEvent]
- lea edi, [esi+TScrollWindow._HScroller]
- mov eax, [ecx+TMouseMoveEvent.x]
- mov ecx, [esi+TScrollWindow._width]
- mov [.event.ScrollBar], scrollX
- cmp [edi+TScrollbar._Drag], 0
- jne .found
-
- mov ecx, [.pEvent]
- lea edi, [esi+TScrollWindow._VScroller]
- mov eax, [ecx+TMouseMoveEvent.y]
- mov ecx, [esi+TScrollWindow._height]
- mov [.event.ScrollBar], scrollY
- cmp [edi+TScrollbar._Drag], 0
-
- je .continue
-
-
-.found:
- mov [.event.event], seScroll
- mov [.event.ScrollCmd], scTrack
-
- sub ecx, ScrollBarWidth
- sub eax, 2
- sub eax, [edi+TScrollbar._Drag]
- stdcall _SetSliderPos, edi, eax, ecx
- jc .endmove
-
- mov eax, [edi+TScrollbar.Pos]
- mov [.event.Value], eax
-
- lea eax, [.event]
- stdcall ExecEvent, esi, eax
- jnc .finish
-
-; ?????? Do we need this?
-; execute esi, TScrollWindow.Refresh
-
-.endmove:
- clc
- jmp .finish
-
-endp
-
-
-;_________________________________________________________________________________________
-
-
-proc TScrollWindow.ExecCmd, .self, .method
-begin
- cmp [.method], TScrollWindow._ComputeFreeArea
- je .computefreearea
-
- stc
- return
-
-
-.computefreearea:
- mov ecx, [.self]
- sub [ecx+TScrollWindow._FreeArea.width], ScrollBarWidth
- sub [ecx+TScrollWindow._FreeArea.height], ScrollBarWidth
-
- stc
- return
-endp
-
-
-;_________________________________________________________________________________________
-
-
-
-proc _SetSliderPos, .pScrollbar, .x, .lengthpx
-begin
- push eax ecx edx
-
- mov ecx, [.pScrollbar]
- stdcall _SliderPixels, [.pScrollbar], [.lengthpx]
-
- sub [.lengthpx], edx
- jz .zero
-
- mov eax, [ecx+TScrollbar.Max]
- imul [.x]
- idiv [.lengthpx]
-
- cmp eax, 0
- jge .ok
- mov eax, 0
-.ok:
- cmp eax, [ecx+TScrollbar.Max]
- jle .ok2
- mov eax, [ecx+TScrollbar.Max]
-.ok2:
- cmp [ecx+TScrollbar.Pos], eax
- stc
- je @f
- clc
-@@:
- mov [ecx+TScrollbar.Pos], eax
- pop edx ecx eax
- return
-
-.zero:
- xor eax, eax
- jmp .ok2
-endp
-
-
-
-; returns:
-; eax - position in pixels
-; edx - size in pixels
-
-proc _SliderPixels, .pScrollbar, .length
-begin
- push ecx esi
-
- mov ecx, [.pScrollbar]
-
-; page size in pixels.
- mov esi, [ecx+TScrollbar.Max]
- mov eax, [.length]
- add esi, [ecx+TScrollbar.Page]
- test esi, esi
- jz .lengthok
-
- imul [ecx+TScrollbar.Page]
- idiv esi
-
-.lengthok:
- cmp eax, MinScrollBarWidth
- jge @f
- mov eax, MinScrollBarWidth
-@@:
- cmp eax, [.length]
- jle @f
- mov eax, [.length]
-@@:
- push eax
-
-; position in pixels
-
- sub eax, [.length]
- mov esi, [ecx+TScrollbar.Max]
- test esi, esi
- jnz @f
- inc esi
-@@:
- neg eax
- mul [ecx+TScrollbar.Pos]
- div esi
-
- pop edx ; width
-
- pop esi ecx
- return
-endp
-
-
-proc __ScrollSetCursor, .window, .x, .y
-begin
- pushad
-
- mov esi, [.window]
- mov eax, [esi+TWindow._cursor]
- stdcall _WhatScrollbar, esi, [.x], [.y]
- jc @f
-
- mov eax, mcArrow
-@@:
- test eax, $ffffff00
- jnz @f
- stdcall GetStockCursor, eax
-@@:
- stdcall SetMouseCursor, eax
-
- popad
- return
-endp
-
-
-
-; returns:
-; ecx = height of the scrollbar
-; edi = ptr to TScrollbar structure
-; ebx = coordinate of the mouse in the scrollbar
-;
-; CF=1 if the cursor is not in scrollbar
-
-proc _WhatScrollbar, .window, .x, .y
-begin
- push eax edx esi
-
- mov esi, [.window]
-
-
- mov eax, [.x]
- mov edx, [.y]
-
- mov eax, [esi+TWindow._width]
- mov edx, [esi+TWindow._height]
-
- sub eax, ScrollBarWidth
- sub edx, ScrollBarWidth
-
- cmp [.x], eax
- jl .checkh
-
- cmp [.y], edx
- jg .notfound ; we are in the dead square.
-
-; mouse in vscrollbar
- mov ebx, [.y]
- mov ecx, edx
- lea edi, [esi+TScrollWindow._VScroller]
- jmp .found
-
-.checkh:
- cmp [.y], edx
- jl .notfound ; in the client area
-
-; mouse in hscrollbar
- mov ebx, [.x]
- mov ecx, eax
- lea edi, [esi+TScrollWindow._HScroller]
-
-.found:
- clc
- pop esi edx eax
- return
-
-.notfound:
- stc
- pop esi edx eax
- return
-endp
-
-
-
-endmodule
DELETED freshlib/gui/TTreeView.asm
Index: freshlib/gui/TTreeView.asm
==================================================================
--- freshlib/gui/TTreeView.asm
+++ /dev/null
@@ -1,144 +0,0 @@
-; _______________________________________________________________________________________
-;| |
-;| ..::FreshLib::.. Free, open source. Licensed under "Fresh artistic license." |
-;|_______________________________________________________________________________________|
-;
-; Description: TTreeView object class
-;
-; Target OS: Any
-;
-; Dependencies:
-; Notes:
-;_________________________________________________________________________________________
-module "TreeView library"
-
-ObjectClass TreeView, \
- ScrollWindow, \
- TTreeView.Create, \
- TTreeView.Destroy, \
- TTreeView.Get, \
- TTreeView.Set, \
- TTreeView.ExecCmd, \
- TTreeView.SysEventHandler
-
-; tree-view item state flags.
-tvisExpanded = 1
-tvisSelected = 2
-tvisFocused = 4
-
-
-struct TTreeViewItem
- .level dd ? ; the level of the element in the tree.
-
- .caption dd ? ; hString of the name.
- .state dd ? ; one or more state flags.
- .imgNormal dd ? ; index to the icon for normal state
- .iSelected dd ? ; index to the icon for selected state
-
- .pObject dd ? ; the object attached to the item
- align 32
- .shift = 5
-ends
-
-
-object TTreeView, TScrollWindow
- ._items dd ? ; TArray with
- ._first dd ? ; index of the fisrt visible item.
- ._pShadow dd ? ; pointer to TBackBuffer
-
- .OnItemDelete dd ? ; procedure to be call when the item is deleted. It should free the objects attached to the item.
-
- param .Focused
-
- method .AddItem, .iParent
- method .DelItem, .iItem ;deletes the item and all children.
- method .GetItem, .index
-endobj
-
-
-proc TTreeView.Create, .pobj
-begin
- mov ebx, [.pobj]
-
- stdcall CreateBackBuffer, [ebx+TTreeView.handle], 1, 1
- mov [ebx+TTreeView._pShadow], eax
-
- stdcall CreateArray, sizeof.TTreeViewItem
- mov [ebx+TTreeView._items], eax
-
- clc
- return
-endp
-
-
-proc TTreeView.Destroy, .pobj
-begin
- mov ebx, [.pobj]
-
- stdcall DestroyBackBuffer, [ebx+TTreeView._pShadow]
- execute ebx, TTreeView.DelItem, -1
- stdcall FreeMem, [ebx+TTreeView._items]
-
- clc
- return
-endp
-
-
-proc TTreeView.Get, .pobj, .paramID
-begin
- stc
- return
-endp
-
-
-proc TTreeView.Set, .pobj, .paramID, .value
-begin
- stc
- return
-endp
-
-
-proc TTreeView.ExecCmd, .self, .method
-begin
- stc
- return
-endp
-
-
-proc TTreeView.SysEventHandler, .pobj, .pEvent
-begin
- pushad
-
- mov ebx, [.pEvent]
- mov esi, [.pobj]
- mov eax, [ebx+TSysEvent.event]
-
- cmp eax, sePaint
- je .paint
-
- cmp eax, seMoveResize
- je .moveresize
-
-.continue:
- popad
- stc
- return
-
-.paint:
- stdcall SetClipRectangle, [ebx+TPaintEvent.context], 0
- stdcall TScrollWindow.SysEventHandler, [.pobj], [.pEvent]
- stdcall DrawBackBuffer, [ebx+TPaintEvent.context], [esi+TTreeView._pShadow], 0, 0
- jmp .continue
-
-.moveresize:
- stdcall Get, esi, TTreeView.FreeArea
-
- stdcall DestroyBackBuffer, [esi+TTreeView._pShadow]
- stdcall CreateBackBuffer, [esi+TTreeView.handle], [esi+TTreeView._FreeArea.width], [esi+TTreeView._FreeArea.height]
- mov [esi+TTreeView._pShadow], eax
- jmp .continue
-
-endp
-
-
-endmodule
DELETED freshlib/gui/TWindow.asm
Index: freshlib/gui/TWindow.asm
==================================================================
--- freshlib/gui/TWindow.asm
+++ /dev/null
@@ -1,805 +0,0 @@
-; _______________________________________________________________________________________
-;| |
-;| ..::FreshLib::.. Free, open source. Licensed under "Fresh artistic license." |
-;|_______________________________________________________________________________________|
-;
-; Description: TWindow object class
-;
-; Target OS: Any
-;
-; Dependencies:
-;
-; Notes: TWindow is the common ancestor of all visible on the screen controls.
-; This file contains only OS independent part of the library and includes
-; the OS dependent files.
-;_________________________________________________________________________________________
-module "TWindow library"
-
-ObjectClass Window, \
- Object, \
- TWindow.Create, \
- TWindow.Destroy, \
- TWindow.Get, \
- TWindow.Set, \
- TWindow.ExecCmd, \
- TWindow.SysEventHandler
-
-; The elements of the array returned by .GetSiblings param
-; if handle<>0 and pWindow=0 - it is a native window, not added by FreshLib
-struct TWinArrayItem
- .handle dd ? ; The native OS handle of the window.
- .pWindow dd ? ; pointer to TWindow descendent structure.
-ends
-
-; Border kind of window.
-borderNone = 0
-borderFull = 1
-borderModal = 2
-borderToolbox = 3
-
-struct __TInternalAlign
- .client TBounds
- .pClientWindow dd ?
-ends
-; assign X = 01
-; assign Y = 10
-
-; adjheight = 01
-; topleft = 00
-; bottomright = 10
-
-; 00 - adjwidht + bottomright
-
-; Window align values.
-waNone = 0
-waLeft = 1
-waTop = 2
-waRight = 3
-waBottom = 4
-waClient = 5
-
-
-object TWindow, TObject
-
- .handle dd ? ; it is handle to the system provided window.
-
- ._x dd ?
- ._y dd ?
- ._width dd ?
- ._height dd ?
-
- ._visible dd ?
-
- ._bounds_changed dd ?
-
- ._border dd ?
-
- ._align dd ? ; window horizontal alignment
-
- ._FreeArea TBounds ; the window area that remains free after all children aligned. [1]
-
- ._caption dd ? ; string handle with window caption.
- ._cursor dd ? ; it is a handle to the mouse cursor.
-
- .OnKeyPress dd ? ; key press user handler.
-
-; parameters
- param .x
- param .y
- param .width
- param .height
-
- param .Align
-
- param .FreeArea ; read only.
-
- param .borderKind
- param .Zorder
-
- param .Visible
- param .Caption
- param .Parent
- param .Cursor
- param .Children ; read only. returns array with all children; See the notes [2] below.
-
- method .Refresh
- method .Focus
- method .AlignChildren
- method .ToBack
- method .ToFront
-
- method ._ComputeFreeArea
-endobj
-
-; NOTES:
-; [1] FreeArea field
-;
-; [2] The param .children returns an array of TWinArrayItem filled with information about
-; all siblings of the given window.
-; This array is allocated with CreateArray and needs to be free with FreeMem after use.
-; TArray.lparam of the array contains a pointer to the element containing current window
-
-
-; OS dependend code
-include '%TargetOS%/windows.asm'
-
-
-; OS independent code.
-
-
-;_________________________________________________________________________________________
-
-
-proc TWindow.Create, .obj
-begin
- push eax ecx edx
- mov ebx, [.obj]
- stdcall _CreateNullWindow
- mov [ebx+TWindow.handle], eax
- stdcall _SetWindowStruct, eax, ebx
-
- pop edx ecx eax
- clc
- return
-endp
-
-
-;_________________________________________________________________________________________
-
-
-
-proc TWindow.Destroy, .obj
-begin
- push eax
- mov eax, [.obj]
- cmp [eax+TWindow.handle], 0
- je @f
- stdcall _DestroyWindow, [eax+TWindow.handle]
-@@:
- pop eax
- return
-endp
-
-
-
-;_________________________________________________________________________________________
-
-
-proc TWindow.Get, .obj, .paramID
-.rect RECT
-begin
- push edx esi
-
- stdcall IsObject, [.obj], CWindow
- jc .not_processed
-
- mov esi, [.obj]
- mov eax, [.paramID]
-
- test eax, maskParameter
- jz .field
-
- cmp eax, TWindow.x
- je .getrect
- cmp eax, TWindow.y
- je .getrect
- cmp eax, TWindow.width
- je .getrect
- cmp eax, TWindow.height
- je .getrect
-
- cmp eax, TWindow.FreeArea
- je .getfreearea
-
- cmp eax, TWindow.Visible
- je .getvisible
-
- cmp eax, TWindow.Caption
- je .getcaption
-
- cmp eax, TWindow.borderKind
- je .getborder
-
- cmp eax, TWindow.Children
- je .getchildren
-
- cmp eax, TWindow.Parent
- je .getparent
-
-
-.not_processed:
- stc
- pop esi edx
- return
-
-
-.field:
- mov eax, [esi+eax]
-
-
-.finish:
- clc
- pop esi edx
- return
-
-;.........................................................................................
-
-.getparent:
- stdcall _GetParent, [esi+TWindow.handle]
- test eax, eax
- jz .finish
- stdcall _GetWindowStruct, eax
- jmp .finish
-
-;.........................................................................................
-
-.getchildren:
- stdcall _GetChildren, [esi+TWindow.handle]
- test eax, eax
- jz .finish
-
- push ebx edi
-
- mov ebx, eax
- mov ecx, [ebx+TArray.count]
-
-.loop:
- jecxz .endloop
- dec ecx
-
- stdcall _GetWindowStruct, [ebx+TArray.array+8*ecx+TWinArrayItem.handle]
-
- mov [ebx+TArray.array+8*ecx+TWinArrayItem.pWindow], eax
- jmp .loop
-
-.endloop:
- mov eax, ebx
-
- pop edi ebx
- jmp .finish
-
-
-;.........................................................................................
-
-
-.getfreearea:
- mov [esi+TWindow._FreeArea.x], 0
- mov [esi+TWindow._FreeArea.y], 0
- mov eax, [esi+TWindow._width]
- mov ecx, [esi+TWindow._height]
- mov [esi+TWindow._FreeArea.width], eax
- mov [esi+TWindow._FreeArea.height], ecx
-
- execute esi, TWindow._ComputeFreeArea
-
- lea eax, [esi+TWindow._FreeArea]
- jmp .finish
-
-
-;.........................................................................................
-
-
-.getborder:
- mov eax, [esi+TWindow._border]
- jmp .finish
-
-
-;.........................................................................................
-
-
-.getcaption:
- stdcall StrDup, [esi+TWindow._caption]
- jmp .finish
-
-;.........................................................................................
-
-.getvisible:
- mov eax, [esi+TWindow._visible]
-; stdcall _GetVisible, [esi+TWindow.handle]
- jmp .finish
-
-;.........................................................................................
-
-
-.getrect:
- mov eax, [.paramID]
- sub eax, TWindow.x
- mov eax, [esi+TWindow._x+4*eax]
- jmp .finish
-endp
-
-
-;_________________________________________________________________________________________
-
-
-
-proc TWindow.Set, .obj, .paramID, .value
-begin
- stdcall IsObject, [.obj], CWindow
- jc .fault
-
- push eax esi
-
- mov esi, [.obj]
- mov eax, [.paramID]
-
- test eax, maskParameter
- jz .field
-
- cmp eax, TWindow.x
- je .setrect
- cmp eax, TWindow.y
- je .setrect
- cmp eax, TWindow.width
- je .setrect
- cmp eax, TWindow.height
- je .setrect
-
- cmp eax, TWindow.Visible
- je .setvisible
-
- cmp eax, TWindow.Caption
- je .setcaption
-
- cmp eax, TWindow.borderKind
- je .setborder
-
- cmp eax, TWindow.Align
- je .setalign
-
- pop esi eax
-.fault:
- stc
- return
-
-.field:
- pushd [.value]
- popd [esi+eax]
-
-.finish:
- clc
- pop esi eax
- return
-
-;.........................................................................................
-.setalign:
-locals
- .bounds TBounds
-endl
- mov eax, [.value]
- cmp eax, [esi+TWindow._align]
- je .finish
-
- mov [esi+TWindow._align], eax
-
- stdcall Get, esi, TWindow.Parent
- test eax, eax
- jz .finish
-
- execute eax, TWindow.AlignChildren
-
- jmp .finish
-
-;.........................................................................................
-
-
-.setborder:
- mov eax, [.value]
- xchg eax, [esi+TWindow._border]
- cmp eax, [esi+TWindow._border]
- je .finish
-
- stdcall _SetWindowBorder, [esi+TWindow.handle], [esi+TWindow._border]
- jmp .finish
-
-;.........................................................................................
-
-.setcaption:
- lea eax, [esi+TWindow._caption]
- stdcall SetString, eax, [.value]
- stdcall StrPtr, [eax]
-
- stdcall _SetWindowTextUtf8, [esi+TWindow.handle], [.value]
- jmp .finish
-
-;.........................................................................................
-
-.setvisible:
- mov eax, [.value]
- xchg [esi+TWindow._visible], eax
- cmp [esi+TWindow._visible], eax
- je .finish
-
- stdcall _ShowWindow, [esi+TWindow.handle], [.value]
-
- cmp [.value], 0
- je .finish
-
- cmp [esi+TWindow._align], waNone
- je .finish
-
- stdcall Get, esi, TWindow.Parent
- test eax, eax
- jz .finish
-
- execute eax, TWindow.AlignChildren
- jmp .finish
-
-;.........................................................................................
-
-.setrect:
- mov eax, [.paramID]
- sub eax, TWindow.x
-
- mov ecx, [.value]
- cmp ecx, [esi+TWindow._x+4*eax]
- je .finish
-
- mov [esi+TWindow._x+4*eax], ecx
-
- lea eax, [esi+TWindow._x]
- stdcall _SetWindowBounds, [esi+TWindow.handle], eax
- mov [esi+TWindow._bounds_changed], 0
-
- jmp .finish
-endp
-
-
-;_________________________________________________________________________________________
-
-
-
-
-proc TWindow.ExecCmd, .self, .method
-begin
- push eax edx
-
- cmp [.method], TWindow.Refresh
- je .refresh
-
- cmp [.method], TWindow._ComputeFreeArea
- je .computefreearea
-
- cmp [.method], TWindow.AlignChildren
- je .alignchildren
-
- cmp [.method], TWindow.Focus
- je .focus
-
- cmp [.method], TWindow.AddChild
- je .addchild
-
-.error:
- stc
- pop edx eax
- return
-
-;.........................................................................................
-
-.refresh:
- mov eax, [.self]
- cmp [eax+TWindow._visible], 0
- je .finish
- stdcall _RefreshWindow, [eax+TWindow.handle]
-.finish:
- clc
- pop edx eax
- return
-
-;.........................................................................................
-
-.computefreearea:
-
-
-
- jmp .finish
-
-;.........................................................................................
-
-.alignchildren:
-locals
- .winalign __TInternalAlign
-endl
-; THIS METHOD is not written very good. It should be revised some day in order to make
-; alignment fast and smooth for all OS supported!
- push esi edi
-
- stdcall Get, [.self], TWindow.Children
- test eax, eax
- jz .endalign
-
- mov edi, eax
- lea esi, [.winalign]
- mov ecx, [.self]
-
- push [ecx+TWindow._width] [ecx+TWindow._height]
- pop [esi+__TInternalAlign.client.height] [esi+__TInternalAlign.client.width]
-
- xor ecx,ecx
-
- mov [esi+__TInternalAlign.client.y], ecx
- mov [esi+__TInternalAlign.client.x], ecx
- mov [esi+__TInternalAlign.pClientWindow], ecx
-
-.loop:
- cmp ecx, [edi+TArray.count]
- je .endloop
-
- stdcall __DoAlignOne, [edi+TArray.array+8*ecx+TWinArrayItem.pWindow]
- inc ecx
- jmp .loop
-
-.endloop:
- mov ecx, [.winalign.pClientWindow]
- jecxz .updatewindows
-
- mov eax, [esi+__TInternalAlign.client.x]
- mov edx, [esi+__TInternalAlign.client.y]
- sub eax, [ecx+TWindow._x]
- sub edx, [ecx+TWindow._y]
- mov ebx, eax
- or ebx, edx
-
- mov eax, [esi+__TInternalAlign.client.width]
- mov edx, [esi+__TInternalAlign.client.height]
- sub eax, [ecx+TWindow._width]
- sub edx, [ecx+TWindow._height]
- or ebx, eax
- or ebx, edx
- mov [ecx+TWindow._bounds_changed], ebx
-
- push [esi+__TInternalAlign.client.height] [esi+__TInternalAlign.client.width] [esi+__TInternalAlign.client.y] [esi+__TInternalAlign.client.x]
- pop [ecx+TWindow._x] [ecx+TWindow._y] [ecx+TWindow._width] [ecx+TWindow._height]
-
-.updatewindows:
- mov ecx, [edi+TArray.count]
-
-.updateloop:
- dec ecx
- js .endupdate
-
- mov eax, [edi+8*ecx+TArray.array+TWinArrayItem.pWindow]
- cmp [eax+TWindow._bounds_changed], 0
- je .refresh_only
-
- lea edx, [eax+TWindow._x]
-; mov [eax+TWindow._bounds_changed], 0 - it will be zeroed in the seMoveResize event handler.
- stdcall _SetWindowBounds, [eax+TWindow.handle], edx
-
-.refresh_only:
- stdcall _RefreshWindow, [eax+TWindow.handle]
- jmp .updateloop
-
-.endupdate:
- stdcall FreeMem, edi
- mov eax, [.self]
- stdcall _RefreshWindow, [eax+TWindow.handle]
-
-.endalign:
- pop edi esi
- jmp .finish
-
-;.........................................................................................
-
-.focus:
- mov eax, [.self]
- stdcall _SetFocus, [eax+TWindow.handle]
- jmp .finish
-
-;.........................................................................................
-
-.addchild:
-; method parameter.
-virtual at ebx
- .child dd ?
-end virtual
- stdcall IsObject, [.child], CWindow
- jne .add_non_window
-
- mov ebx, [.child]
- mov eax, [.self]
-
- stdcall _AddChild, [eax+TWindow.handle], [ebx+TWindow.handle]
- jmp .finish
-
-.add_non_window: ; this is possible, but not implemented for now.
- jmp .error
-endp
-
-
-
-;_________________________________________________________________________________________
-
-
-proc TWindow.SysEventHandler, .pObj, .pEvent
-begin
- push eax ecx edx esi edi
-
- mov esi, [.pObj]
- mov ebx, [.pEvent]
- mov eax, [ebx+TSysEvent.event]
-
- cmp eax, seMouseEnter
- je .mouseenter
-
- cmp eax, seMouseLeave
- je .mouseleave
-
- cmp eax, seMouseBtnPress
- je .btnpress
-
- cmp eax, seMoveResize
- je .moveresize
-
- cmp eax, seKbdKeyPress
- je .keypress
-
- stc
-.finish:
- pop edi esi edx ecx eax
- return
-
-;.........................................................................................
-.moveresize:
- mov eax, [ebx+TMoveResizeEvent.newX]
- mov ecx, [ebx+TMoveResizeEvent.newY]
- mov [esi+TWindow._x], eax
- mov [esi+TWindow._y], ecx
-
- mov eax, [ebx+TMoveResizeEvent.newWidth]
- mov ecx, [ebx+TMoveResizeEvent.newHeight]
- xchg [esi+TWindow._width], eax
- xchg [esi+TWindow._height], ecx
- sub eax, [esi+TWindow._width]
- sub ecx, [esi+TWindow._height]
- or eax, ecx
- jnz .alignchildren ; when the resize is as a result of internal windows align, the _width and _height fields are already set.
- ; it must be this way, because the resize should be fast, but in Linux there is no DeferWindowPos function like in Win32
-
- cmp [esi+TWindow._bounds_changed], 0
- je .endresize
-
-.alignchildren:
- execute esi, TWindow.AlignChildren
- mov [esi+TWindow._bounds_changed], 0
-
-.endresize:
- clc
- jmp .finish
-
-;.........................................................................................
-
-.btnpress:
- execute esi, TWindow.Focus
- clc
- jmp .finish
-
-;.........................................................................................
-
-.mouseenter:
- mov eax, [esi+TWindow._cursor]
- test eax, $ffffff00
- jnz @f
- stdcall GetStockCursor, eax
-@@:
- stdcall SetMouseCursor, eax
- clc
- jmp .finish
-
-;.........................................................................................
-.mouseleave:
- stdcall GetStockCursor, mcArrow
- stdcall SetMouseCursor, eax
- clc
- jmp .finish
-
-;.........................................................................................
-
-.keypress:
- cmp [esi+TWindow.OnKeyPress], 0
- je @f
- stdcall [esi+TWindow.OnKeyPress], esi, ebx
-@@:
- clc
- jmp .finish
-endp
-
-
-
-proc __DoAlignOne, .pWindow
-.bounds TBounds
-.align dd ?
-begin
- pushad
-
- mov ebx, [.pWindow]
- cmp [ebx+TWindow._align], waNone
- je .exit
- cmp [ebx+TWindow._align], waClient
- ja .exit
-
- stdcall Get, ebx, TWindow.Visible
- test eax, eax
- jz .exit
-
- cmp [ebx+TWindow._align], waClient
- jne .doalign
-
-; only one window with waClient may exists.
- cmp [esi+__TInternalAlign.pClientWindow], 0
- jne .exit
-
- mov [esi+__TInternalAlign.pClientWindow], ebx
- jmp .exit
-
-.doalign:
- mov eax, [ebx+TWindow._align]
- dec eax
- mov [.align], eax
-
-; save the old bounds in order to detect change.
- mov eax, [ebx+TWindow._x]
- mov ecx, [ebx+TWindow._y]
- mov [.bounds.x], eax
- mov [.bounds.y], ecx
- mov eax, [ebx+TWindow._width]
- mov ecx, [ebx+TWindow._height]
- mov [.bounds.width], eax
- mov [.bounds.height], ecx
-
- mov ecx, TBounds.width
- mov edx, [ebx+TWindow._height]
- mov edi, TBounds.y
- bt [.align], 0 ; 0 - width; 1 - height
- jc @f
- mov ecx, TBounds.height
- mov edx, [ebx+TWindow._width]
- mov edi, TBounds.x
-@@:
- mov eax, [esi+__TInternalAlign.client+ecx]
- mov [ebx+TWindow._x+ecx], eax
-
- mov eax, [esi+__TInternalAlign.client.x]
- mov ecx, [esi+__TInternalAlign.client.y]
-
- bt [.align], 1 ; 0 - left/top; 1-right/bottom
- jnc @f
-
- add eax, [esi+__TInternalAlign.client.width]
- add ecx, [esi+__TInternalAlign.client.height]
- sub eax, [ebx+TWindow._width]
- sub ecx, [ebx+TWindow._height]
- neg edx
- add edi, 8
-
-@@:
- mov [ebx+TWindow._x], eax
- mov [ebx+TWindow._y], ecx
- add [esi+__TInternalAlign.client+edi], edx
- test edx, edx
- js @f
- sub [esi+__TInternalAlign.client+edi+8], edx
-@@:
- mov eax, [ebx+TWindow._x]
- mov ecx, [ebx+TWindow._y]
- mov edx, [ebx+TWindow._width]
- mov edi, [ebx+TWindow._height]
- sub eax, [.bounds.x]
- sub ecx, [.bounds.y]
- sub edx, [.bounds.width]
- sub edi, [.bounds.height]
- or ecx, eax
- or edx, edi
- or ecx, edx
- mov [ebx+TWindow._bounds_changed], ecx
-
-.exit:
- popad
- return
-endp
-
-
-
-
-endmodule
-
DELETED freshlib/gui/ThemeGUI.asm
Index: freshlib/gui/ThemeGUI.asm
==================================================================
--- freshlib/gui/ThemeGUI.asm
+++ /dev/null
@@ -1,172 +0,0 @@
-; _______________________________________________________________________________________
-;| |
-;| ..::FreshLib::.. Free, open source. Licensed under "Fresh artistic license." |
-;|_______________________________________________________________________________________|
-;
-; Description: This file contains procedures and data, that form the appearance of the
-; FreshLib GUI application. Colors, control borders, backgrownd drawing etc.
-;
-; Target OS: Any
-;
-; Dependencies:
-;
-; Notes: The user should be able to change these settings and if he uses external
-; procedures, then the code from this library should not be compiled.
-;_________________________________________________________________________________________
-module "GUI theme data and code library"
-
-; Box border type
-bxNone = 0
-bxRaised = 1
-bxSunken = 2
-bxFlat = 3
-bxNoFill = $80000000
-
-; Default colors
-iglobal
- var clBorderLight = $ffffff
- var clBorderDark = $606060 ; soft shadow
- var clBorderNeutral = $a0a0a8
-
- var clEditBk = $fffff0
- var clEditTxt = $000000
- var clEditSel = $0000a0
- var clEditSelTxt = $ffffff
-
- var clButtonBk = $d0d0d8
- var clButtonTxt = $000000
-
- var clButtonHotBk = $e0e0e8
- var clButtonHotTxt = $0000ff
-
- var clDialogBk = $d0d0d8
- var clDialogTxt = $000000
-
- var clScrollBk = $a0a0a0
- var clScrollSlider = $d0d0d8
-
- if ~defined DrawBox | defined ___DrawBox
- var DrawBox = DrawBoxDefault
- ___DrawBox = 1
- end if
-
- if ~defined DrawSlider | defined ___DrawSlider
- var DrawSlider = DrawSliderDefault
- ___DrawSlider = 1
- end if
-
-
-endg
-
-
-
-
-
-; Midnight colors
-;iglobal
-; var clBorderLight = $0000ff
-; var clBorderDark = $000000
-; var clBorderNeutral = $808080
-;
-; var clEditBk = $0000c0
-; var clEditTxt = $ffffff
-; var clEditSel = $0000ff
-; var clEditSelTxt = $000000
-;
-; var clButtonBk = $000080
-; var clButtonTxt = $ffffff
-;
-; var clButtonHotBk = $0000a0
-; var clButtonHotTxt = $ffffff
-;
-; var clDialogBk = $000080
-; var clDialogTxt = $ffffff
-;endg
-
-
-
-
-proc DrawBoxDefault, .context, .pBounds, .bkground, .border
- .brd RECT
-begin
- push eax ecx edx esi
-
-
- stdcall SetDrawMode, [.context], cmCopy
-
- mov esi, [.pBounds]
-
- mov edx, [.border]
- and edx, $ff
- jz .borderok
-
- mov eax, [esi+TBounds.x]
- mov ecx, [esi+TBounds.y]
- mov [.brd.left], eax
- mov [.brd.top], ecx
-
- add eax, [esi+TBounds.width]
- add ecx, [esi+TBounds.height]
- dec eax
- dec ecx
- mov [.brd.right], eax
- mov [.brd.bottom], ecx
-
- sub [esi+TBounds.width], 2
- sub [esi+TBounds.height], 2
- inc [esi+TBounds.x]
- inc [esi+TBounds.y]
-
- mov eax, [clBorderLight]
- mov ecx, [clBorderDark]
-
- cmp edx, bxRaised
- je .colorok
-
- xchg eax, ecx
-
- cmp edx, bxSunken
- je .colorok
-
- mov eax, [clBorderNeutral]
- mov ecx, eax
-
-.colorok:
- stdcall SetSimpleLine, [.context], eax
- stdcall DrawLine, [.context], [.brd.left], [.brd.top], [.brd.left], [.brd.bottom]
- stdcall DrawLine, [.context], [.brd.left], [.brd.top], [.brd.right], [.brd.top]
-
- stdcall SetSimpleLine, [.context], ecx
- stdcall DrawLine, [.context], [.brd.left], [.brd.bottom], [.brd.right], [.brd.bottom]
- inc [.brd.bottom]
- stdcall DrawLine, [.context], [.brd.right], [.brd.top], [.brd.right], [.brd.bottom]
-
-.borderok:
- bt [.border], 31
- jc .fillok
- stdcall DrawFillRect, [.context], [esi+TBounds.x], [esi+TBounds.y], [esi+TBounds.width], [esi+TBounds.height], [.bkground]
-
-; additional 1px margin
- sub [esi+TBounds.width], 2
- sub [esi+TBounds.height], 2
- inc [esi+TBounds.x]
- inc [esi+TBounds.y]
-
-.fillok:
- pop esi edx ecx eax
- return
-endp
-
-
-sliderHorizontal = 0
-sliderVertical = 1
-
-proc DrawSliderDefault, .context, .pBounds, .bkground, .type
-begin
- stdcall [DrawBox], [.context], [.pBounds], [.bkground], bxRaised
- return
-endp
-
-
-
-endmodule
DELETED freshlib/gui/Win32/Main.asm
Index: freshlib/gui/Win32/Main.asm
==================================================================
--- freshlib/gui/Win32/Main.asm
+++ /dev/null
@@ -1,495 +0,0 @@
-; _______________________________________________________________________________________
-;| |
-;| ..::FreshLib::.. Free, open source. Licensed under "Fresh artistic license." |
-;|_______________________________________________________________________________________|
-;
-; Description: Main procedure of GUI application library.
-;
-; Target OS: Win32
-;
-; Dependencies:
-;
-; Notes: Organize the main message/event loop needed by every GUI engine.
-;_________________________________________________________________________________________
-
-proc ProcessSystemEvents
-.msg MSG
-begin
- push ecx edx esi
-
-.msgloop:
- lea esi, [.msg]
- xor eax, eax
-
- invoke PeekMessage, esi, eax, eax, eax, PM_REMOVE
- test eax, eax
- jz .exitok
-
- cmp [.msg.message], WM_TIMER
- je .translate ; express dispatching of the timer messages.
-
- cmp [.msg.message], WM_QUIT
- je .terminate
-
- stdcall __ProcessOneSystemEvent, [esi+MSG.hwnd], [esi+MSG.message], [esi+MSG.wParam], [esi+MSG.lParam]
- jnc .msgloop ; the message is translated to system event and the event is executed by the object SysEvent handler.
-
-; the message is for window that is not an FreshLib object, so process with standard windows behaviour.
-; invoke TranslateMessage, esi
-.translate:
- invoke DispatchMessage, esi
- jmp .msgloop
-
-
-.exitok:
- clc
- pop esi edx ecx
- return
-
-
-.terminate:
- mov eax, [.msg.wParam]
- stc
- pop esi edx ecx
- return
-endp
-
-
-
-
-proc WaitForSystemEvent
-begin
- push eax ecx edx
- invoke WaitMessage
- pop edx ecx eax
- return
-endp
-
-
-
-
-;proc EventsQueued, .pWin
-;.msg MSG
-;begin
-; push eax ecx edx
-; mov eax, [.pWin]
-; mov ecx, [eax+TWindow.handle]
-; lea eax, [.msg]
-; invoke PeekMessage, eax, ecx, 0, 0, PM_NOREMOVE
-; test eax, eax
-; clc
-; jz @f
-; stc
-;@@:
-; pop edx ecx eax
-; return
-;endp
-;
-
-;----------------------------------------------------------------------------------------------------------
-; This procedure makes following:
-; 1. Takes as arguments one windows message
-; 2. Converts this message to FreshLib system event (or not, depending on the message)
-; 3. Calls SysEventHandler procedures for the given object (if any) with the created event structure.
-; 4. returns CF=0 if the event was properly processed.
-; 5. returns CF=1 if the event was not processed.
-;
-; The event can be not processed in the following cases:
-; 1. The window that receives the message is not FreshLib object.
-; 2. TObjectClass.procSysEventHandler = 0 for the given class and all parents.
-; 3. All procSysEventHandler procedures refuse to process the event (CF=1)
-;----------------------------------------------------------------------------------------------------------
-uglobal
- if used __LatestPointedObj
- __LatestPointedObj dd ?
- end if
-endg
-
-
-winproc __ProcessOneSystemEvent
-.event rb 32
-begin
- push eax ebx ecx edx esi edi
-
- stdcall _GetWindowStruct, [.hwnd]
- test eax, eax
- jz .ondefault
-
- mov esi, eax
- mov ebx, [.wmsg]
- lea edi, [.event]
-
-ondefault
- pop edi esi edx ecx ebx eax
- stc
- return
-
-;.........................................................................................
-
-
-.exec_event:
- stdcall ExecEvent, esi, edi
-
-.finish:
- pop edi esi edx ecx ebx eax
- clc
- return
-
-;.........................................................................................
-
-onmessage WM_MOUSEWHEEL
-
- mov eax, [.wparam]
- sar eax, 16
- mov ecx, scWheelUp
- test eax, eax
- jns @f
- mov ecx, scWheelDn
- neg eax
-@@:
- mov [edi+TScrollEvent.event], seScroll
- mov [edi+TScrollEvent.ScrollBar], scrollY
- mov [edi+TScrollEvent.ScrollCmd], ecx
-
- xor edx, edx
- mov ecx, 120
- idiv ecx
- mov [edi+TScrollEvent.Value], eax
-
- jmp .exec_event
-
-;.........................................................................................
-
-onmessage WM_WINDOWPOSCHANGED
-
-locals
- .rect RECT
-endl
- mov ebx, [.lparam]
-
- lea eax, [edi+TMoveResizeEvent.newX]
- invoke GetClientRect, [.hwnd], eax
-
- mov eax, [ebx+WINDOWPOS.x]
- mov ecx, [ebx+WINDOWPOS.y]
- mov [edi+TMoveResizeEvent.newX], eax
- mov [edi+TMoveResizeEvent.newY], ecx
-
- mov [edi+TMoveResizeEvent.event], seMoveResize
- jmp .exec_event
-
-
-
-;.........................................................................................
-
-onmessage WM_SYSKEYDOWN
-onmessage WM_SYSKEYUP
-onmessage WM_KEYDOWN
-onmessage WM_KEYUP
-locals
- .keyboard rb 256
- .unicode rw 16
- .utf8 rb 16
-endl
- lea ebx, [.keyboard]
- invoke GetKeyboardState, ebx
- mov eax, [.lparam]
- mov ecx, eax
- shr eax, 16
- and ecx, $80000000
- and eax, $ff
- mov [edi+TKeyboardEvent.scancode], eax
- or eax, ecx
- lea edx, [.unicode]
- invoke ToUnicode, [.wparam], eax, ebx, edx, 16, 0
- xor ecx, ecx
- test eax, eax
- jz .key_translated ; the key can not be translated.
- js .key_translated ; it is a dead key. What we have to do???
-
- lea edx, [.utf8]
- xor ecx, ecx
- mov [edx], ecx
- mov [edx+4], ecx
- lea ecx, [.unicode]
- invoke WideCharToMultiByte, CP_UTF8, 0, ecx, eax, edx, 8, 0, 0
- xor ecx, ecx
- test eax, eax
- jz .key_translated
-
- mov ecx, dword [.utf8]
-
-.key_translated:
- mov [edi+TKeyboardEvent.key], ecx
-
- mov ecx, seKbdKeyPress
- cmp [.wmsg], WM_KEYDOWN
- je @f
- cmp [.wmsg], WM_SYSKEYDOWN
- je @f
- mov ecx, seKbdKeyRelease
-@@:
- mov [edi+TKeyboardEvent.event], ecx
-
- xor eax, eax
- test [.keyboard+VK_CONTROL], $80
- jz @f
- or eax, maskCtrl
-@@:
- test [.keyboard+VK_SHIFT], $80
- jz @f
- or eax, maskShift
-@@:
- test [.keyboard+VK_MENU], $80
- jz @f
- or eax, maskAlt
-@@:
- test [.keyboard+VK_SCROLL], $01
- jz @f
- or eax, maskScrLk
-@@:
- test [.keyboard+VK_CAPITAL], $01
- jz @f
- or eax, maskCapsLock
-@@:
-
-; or eax, [__MouseButtonMask]
-; OutputRegister regEAX, 16
-
- mov [edi+TKeyboardEvent.kbdStatus], eax
- jmp .exec_event
-
-
-;.........................................................................................
-
-
-onmessage WM_SETFOCUS
- mov [edi+TFocusInEvent.event], seFocusIn
- jmp .exec_event
-
-
-;.........................................................................................
-
-
-onmessage WM_KILLFOCUS
- mov [edi+TFocusOutEvent.event], seFocusOut
- jmp .exec_event
-
-
-;.........................................................................................
-
-
-onmessage WM_SETCURSOR
-
- movzx eax, word [.lparam]
- cmp eax, HTCLIENT
- jne .ondefault
-
- mov eax, [esi+TWindow._cursor]
- test eax, $ffffff00
- jnz .customcursor
-
- stdcall GetStockCursor, eax
-
-.customcursor:
- stdcall SetMouseCursor, eax
- jmp .finish
-
-
-;.........................................................................................
-
-
-onmessage WM_MOUSEMOVE
- cmp esi, [__LatestPointedObj]
- je .normal_mouse_move
-
- mov [edi+TMouseEnterEvent.event], seMouseLeave
- xchg esi, [__LatestPointedObj]
- test esi, esi
- jz .leaveok
- stdcall ExecEvent, esi, edi
-
-.leaveok:
- mov esi, [__LatestPointedObj]
- mov [edi+TMouseEnterEvent.event], seMouseEnter
- stdcall ExecEvent, esi, edi
-
-.normal_mouse_move:
- mov [edi+TMouseMoveEvent.event], seMouseMove
- movsx eax, word [.lparam]
- movsx ecx, word [.lparam+2]
- mov [edi+TMouseMoveEvent.x], eax
- mov [edi+TMouseMoveEvent.y], ecx
- jmp .exec_event
-
-
-
-;.........................................................................................
-
-onmessage WM_PAINT
-locals
- .ps PAINTSTRUCT
- .context TContext
- .caret dd ?
- .rect2 RECT
-endl
- lea eax, [.rect2]
- invoke GetUpdateRect, [.hwnd], eax, FALSE
- test eax, eax
- jz .endpaint
-
- lea eax, [.ps]
- invoke BeginPaint, [.hwnd], eax
-
-if defined Caret
- mov [.caret], -1
- cmp esi, [Caret.pWindow]
- jne @f
-
- stdcall CaretShow, FALSE
- mov [.caret], eax
-@@:
-end if
-
- mov [edi+TPaintEvent.event], sePaint
- push [.ps.hdc]
- pop [.context.handle]
- push [.hwnd]
- pop [.context.raster]
-
- lea eax, [.context]
- mov [edi+TPaintEvent.context], eax
-
-; ?????????????????????????????
-; push [.ps.rcPaint.left] [.ps.rcPaint.top]
- push [.rect2.left] [.rect2.top]
- pop [edi+TPaintEvent.rect.top] [edi+TPaintEvent.rect.left]
-; push [.ps.rcPaint.right] [.ps.rcPaint.bottom]
- push [.rect2.right] [.rect2.bottom]
- pop [edi+TPaintEvent.rect.bottom] [edi+TPaintEvent.rect.right]
-
- stdcall ExecEvent, esi, edi
-
- lea eax, [.ps]
- invoke EndPaint, [.hwnd], eax
-
-if defined Caret
- cmp [.caret], -1
- je @f
- stdcall CaretShow, [.caret]
-@@:
-end if
-
-.endpaint:
- pop edi esi edx ecx ebx eax
- clc
- return
-
-
-;.........................................................................................
-
-
-onmessage WM_CLOSE
- mov eax, [pApplication]
- mov eax, [eax+TApplication.MainWindow]
- cmp [eax], esi
- jne @f
-
-DebugMsg "Quit message posted."
- invoke PostQuitMessage, 0
-
-@@:
- mov [edi+TCloseEvent.event], seCloseRequest
- mov [edi+TCloseEvent.reason], cerFromUser
- jmp .exec_event
-
-onmessage WM_DESTROY
- cmp esi, [__LatestPointedObj]
- jne .ondefault
-
- mov [__LatestPointedObj], 0
- jmp .ondefault
-
-;.........................................................................................
-
-
-onmessage WM_LBUTTONUP
-onmessage WM_RBUTTONUP
-onmessage WM_MBUTTONUP
-onmessage WM_LBUTTONDOWN
-onmessage WM_RBUTTONDOWN
-onmessage WM_MBUTTONDOWN
-onmessage WM_LBUTTONDBLCLK
-onmessage WM_RBUTTONDBLCLK
-onmessage WM_MBUTTONDBLCLK
-
- stdcall __MouseButton, [.wmsg]
- mov [edi+TMouseButtonEvent.event], ecx
- mov [edi+TMouseButtonEvent.Button], eax
- stdcall __KeyStatus, [.wparam]
- mov [edi+TMouseButtonEvent.kbdStatus], eax
-
- movsx eax, word [.lparam]
- movsx ecx, word [.lparam+2]
- mov [edi+TMouseButtonEvent.x], eax
- mov [edi+TMouseButtonEvent.y], ecx
-
-
- jmp .exec_event
-endwp
-
-
-proc __MouseButton, .msg
-begin
- mov eax, [.msg]
- sub eax, WM_LBUTTONDOWN
- movzx ecx, byte [__mouse_event_table+eax]
- movzx eax, byte [__mouse_button_table+eax]
- return
-endp
-
-
-iglobal
- if used __mouse_button_table
- __mouse_button_table db mbLeft, mbLeft, mbLeft
- db mbRight, mbRight, mbRight
- db mbMiddle, mbMiddle, mbMiddle
- end if
-
- if used __mouse_event_table
- __mouse_event_table db seMouseBtnPress, seMouseBtnRelease, seMouseBtnDblClick
- db seMouseBtnPress, seMouseBtnRelease, seMouseBtnDblClick
- db seMouseBtnPress, seMouseBtnRelease, seMouseBtnDblClick
- end if
-endg
-
-
-;.........................................................................................
-
-
-
-proc __KeyStatus, .status
-begin
- xor eax, eax
- test [.status], MK_LBUTTON
- jz @f
- or eax, maskBtnLeft
-@@:
- test [.status], MK_RBUTTON
- jz @f
- or eax, maskBtnRight
-@@:
- test [.status], MK_MBUTTON
- jz @f
- or eax, maskBtnMiddle
-@@:
- test [.status], MK_SHIFT
- jz @f
- or eax, maskCtrl
-@@:
- test [.status], MK_CONTROL
- jz @f
- or eax, maskCtrl
-@@:
- return
-endp
DELETED freshlib/gui/Win32/TApplication.asm
Index: freshlib/gui/Win32/TApplication.asm
==================================================================
--- freshlib/gui/Win32/TApplication.asm
+++ /dev/null
@@ -1,57 +0,0 @@
-; _______________________________________________________________________________________
-;| |
-;| ..::FreshLib::.. Free, open source. Licensed under "Fresh artistic license." |
-;|_______________________________________________________________________________________|
-;
-; Description: TApplication object class.
-;
-; Target OS: Win32
-;
-; Dependencies:
-;
-; Notes: TApplication by the idea is the base of GUI application, but the implementation
-; somehow need fixing...
-;_________________________________________________________________________________________
-
-uglobal
- if used hInstance
- hInstance dd ?
- end if
-endg
-
-
-proc TApplication.Create, .obj
-begin
- push eax ecx edx
- invoke GetModuleHandle, 0
- mov [hInstance], eax
-
- clc
- pop edx ecx eax
- return
-endp
-
-
-
-proc TApplication.Get, .obj, .paramID
-begin
- clc
- return
-endp
-
-
-
-
-proc TApplication.Set, .obj, .paramID, .value
-begin
- clc
- return
-endp
-
-
-
-proc TApplication.SysEventHandler, .obj, .event
-begin
- clc
- return
-endp
DELETED freshlib/gui/Win32/keycodes.inc
Index: freshlib/gui/Win32/keycodes.inc
==================================================================
--- freshlib/gui/Win32/keycodes.inc
+++ /dev/null
@@ -1,77 +0,0 @@
-; _______________________________________________________________________________________
-;| |
-;| ..::FreshLib::.. Free, open source. Licensed under "Fresh artistic license." |
-;|_______________________________________________________________________________________|
-;
-; Description: This file contains scan code values for control keyboard keys.
-;
-; Target OS: Win32
-;
-; Dependencies:
-;
-; Notes:
-;_________________________________________________________________________________________
-
-keyHomeNumpad = $47
-keyUpNumpad = $48
-keyPgUpNumpad = $49
-keyLeftNumpad = $4b
-key5Numpad = $4c
-keyRightNumpad = $4d
-keyEndNumpad = $4f
-keyDownNumpad = $50
-keyPgDnNumpad = $51
-keyInsNumpad = $52
-keyDelNumpad = $53
-keyEnterNumpad = $1c ; it is ASCII $0d
-keyPlusNumpad = $4e
-keyMinusNumpad = $4a
-keyAsteriskNumpad = $37
-keySlashNumpad = $35
-
-keyNumLock = $45
-keyScrollLock = $46
-keyPause = $45
-keyPrtScr = $37
-
-
-keyLeft = $4b
-keyRight = $4d
-keyUp = $48
-keyDown = $50
-
-keyInsert = $52
-keyDelete = $53
-keyHome = $47
-keyEnd = $4f
-keyPgUp = $49
-keyPgDown = $51
-
-keyF1 = $3b
-keyF2 = $3c
-keyF3 = $3d
-keyF4 = $3e
-
-keyF5 = $3f
-keyF6 = $40
-keyF7 = $41
-keyF8 = $42
-
-keyF9 = $43
-keyF10 = $44 ; used for menu and does not generate WM_KEYDOWN.
-keyF11 = $57
-keyF12 = $58
-
-keyCapsLock = $3a
-keyShiftLeft = $2a
-keyCtrlLeft = $1d
-keyWndLeft = $5b
-keyWndRight = $5c
-keyAltLeft = $38
-keyAltRight = $38
-keyPopupMenu = $5d
-keyShiftRight = $36
-keyCtrlRight = $1d
-
-keyBackSpace = $0e
-
DELETED freshlib/gui/Win32/mouse.asm
Index: freshlib/gui/Win32/mouse.asm
==================================================================
--- freshlib/gui/Win32/mouse.asm
+++ /dev/null
@@ -1,60 +0,0 @@
-; _______________________________________________________________________________________
-;| |
-;| ..::FreshLib::.. Free, open source. Licensed under "Fresh artistic license." |
-;|_______________________________________________________________________________________|
-;
-; Description: Provides unified access to standard mouse cursors.
-;
-; Target OS: Win32
-;
-; Dependencies:
-;
-; Notes:
-;_________________________________________________________________________________________
-
-; ToDo: Arbitrary mouse cursors, B&W for the begining.
-
-
-proc SetMouseCursor, .hCursor
-begin
- push ecx edx
- invoke SetCursor, [.hCursor]
- pop edx ecx
- return
-endp
-
-
-
-proc GetStockCursor, .index
-begin
- push ecx edx
- mov eax, [.index]
- and eax, 7
- movzx eax, [_cursors+2*eax]
- invoke LoadCursor, 0, eax
- pop edx ecx
- return
-endp
-
-if used _cursors
- _cursors dw IDC_ARROW, IDC_IBEAM, IDC_CROSS, IDC_SIZEWE, IDC_SIZENS, IDC_SIZENWSE, IDC_SIZENESW, IDC_WAIT
-end if
-
-
-
-proc MouseCapture, .hwnd
-begin
- push eax ecx edx
- cmp [.hwnd], 0
- je .release
-
- invoke SetCapture, [.hwnd]
-
-.finish:
- pop edx ecx eax
- return
-
-.release:
- invoke ReleaseCapture
- jmp .finish
-endp
DELETED freshlib/gui/Win32/windows.asm
Index: freshlib/gui/Win32/windows.asm
==================================================================
--- freshlib/gui/Win32/windows.asm
+++ /dev/null
@@ -1,447 +0,0 @@
-; _______________________________________________________________________________________
-;| |
-;| ..::FreshLib::.. Free, open source. Licensed under "Fresh artistic license." |
-;|_______________________________________________________________________________________|
-;
-; Description: Window management OS interface functions.
-;
-; Target OS: Win32
-;
-; Dependencies:
-;
-; Notes:
-;_________________________________________________________________________________________
-
-iglobal
-if used cWindowClassName
- cWindowClassName du 'FreshWin', 0
-end if
-endg
-
-nWindowExtraBytes = 32
-ofsWindowStruct = nWindowExtraBytes - 4
-
-;_________________________________________________________________________________________
-;
-; Registers common window class
-; Call only once
-;_________________________________________________________________________________________
-
-if used _CreateNullWindow
-initialize __RegisterWindowClass
-
-.wc WNDCLASS
-
-begin
- xor eax, eax
- lea edi, [.wc]
- mov ecx, sizeof.WNDCLASS / 4
- rep stosd
-
- mov [.wc.style], CS_OWNDC or CS_DBLCLKS; or CS_VREDRAW or CS_HREDRAW
- mov [.wc.lpfnWndProc], __CommonWindowProc
- mov [.wc.cbWndExtra], nWindowExtraBytes
-
-; invoke CreateSolidBrush, $0000ff
-; mov [.wc.hbrBackground], eax
-
- mov eax,[hInstance]
- mov [.wc.hInstance],eax
- mov [.wc.lpszClassName], cWindowClassName
-
- lea eax, [.wc]
- invoke RegisterClass, eax
-
- return
-endp
-end if
-
-
-
-;_________________________________________________________________________________________
-
-
-proc _CreateNullWindow
-begin
- push ecx edx
- invoke CreateWindowEx, 0, cWindowClassName, 0, WS_CLIPSIBLINGS or WS_CLIPCHILDREN, 0, 0, 0, 0, 0, 0, 0, 0
- pop edx ecx
- return
-endp
-
-;_________________________________________________________________________________________
-
-
-
-proc _DestroyWindow, .hwnd
-begin
- push eax ecx edx
- invoke DestroyWindow, [.hwnd]
- pop edx ecx eax
- return
-endp
-
-
-;_________________________________________________________________________________________
-
-
-proc _GetParent, .hwnd
-begin
- push ecx edx
- invoke GetParent, [.hwnd]
- pop edx ecx
- return
-endp
-
-;_________________________________________________________________________________________
-
-
-proc _GetChildren, .hwnd
-begin
- push ebx ecx edx
-
- xor ebx, ebx
-
- invoke GetWindow, [.hwnd], GW_CHILD
- mov ecx, eax
- jecxz .endchildren
-
- stdcall CreateArray, sizeof.TWinArrayItem
- mov ebx, eax
-
-.loophwnd:
- stdcall AddArrayItems, ebx, 1
- mov ebx, edx
-
- mov [eax+TWinArrayItem.handle], ecx
-
- invoke GetWindow, ecx, GW_HWNDNEXT
- mov ecx, eax
- jecxz .endchildren
- jmp .loophwnd
-
-.endchildren:
- mov eax, ebx
- pop edx ecx ebx
- return
-endp
-
-
-;_________________________________________________________________________________________
-
-
-
-proc _GetVisible, .hwnd
-begin
- push ecx edx
- invoke IsWindowVisible, [.hwnd]
- pop edx ecx
- return
-endp
-
-;_________________________________________________________________________________________
-
-
-proc _GetWindowBounds, .hwnd, .pBounds
-begin
- push eax ecx edx
-
- invoke GetClientRect, [.hwnd], [.pBounds]
- invoke GetParent, [.hwnd]
- invoke MapWindowPoints, [.hwnd], eax, [.pBounds], 2
-
- mov edx, [.pBounds]
- mov eax, [edx+TBounds.width]
- mov ecx, [edx+TBounds.height]
- sub eax, [edx+TBounds.x]
- sub ecx, [edx+TBounds.y]
- mov [edx+TBounds.width], eax
- mov [edx+TBounds.height], ecx
-
- pop edx ecx eax
- return
-endp
-
-
-
-;_________________________________________________________________________________________
-
-
-proc _SetWindowBounds, .hwnd, .pBounds
-.rect RECT
-begin
- push eax ecx edx
-
- mov eax, [.pBounds]
- push [eax+TBounds.width] [eax+TBounds.height]
- pop [.rect.bottom] [.rect.right]
- mov [.rect.left], 0
- mov [.rect.top], 0
-
- invoke GetWindowLong, [.hwnd], GWL_EXSTYLE
- push eax
- push FALSE
- invoke GetWindowLong, [.hwnd], GWL_STYLE
- push eax
-
- lea eax, [.rect]
- invoke AdjustWindowRectEx, eax ; and from the stack
-
- mov eax, [.rect.right]
- mov ecx, [.rect.bottom]
- sub eax, [.rect.left]
- sub ecx, [.rect.top]
-
- mov edx, [.pBounds]
- invoke SetWindowPos, [.hwnd], 0, [edx+TBounds.x], [edx+TBounds.y], eax, ecx, SWP_NOZORDER or SWP_NOREDRAW
-
- pop edx ecx eax
- return
-endp
-
-
-
-
-
-;_________________________________________________________________________________________
-wsNoneWindowBorder = WS_POPUP
-wsFullWindowBorder = WS_BORDER or WS_CAPTION or WS_SYSMENU or WS_SIZEBOX or WS_MINIMIZEBOX or WS_MAXIMIZEBOX
-wsModalWindowBorder = WS_CAPTION or WS_DLGFRAME or WS_SYSMENU
-wsToolboxWindowBorder = WS_BORDER or WS_CAPTION or WS_SYSMENU or WS_SIZEBOX
-
-wsAllWindowBorder = wsNoneWindowBorder or wsFullWindowBorder or wsModalWindowBorder or wsToolboxWindowBorder
-
-proc _SetWindowBorder, .hwnd, .brdType
-.bounds TBounds
-begin
- push eax ebx ecx edx esi
-
- invoke GetWindowLong, [.hwnd], GWL_STYLE
- mov ebx, eax
-
- mov esi, [.brdType]
- and esi, 3
-
- invoke SetWindowLong, [.hwnd], GWL_EXSTYLE, [.exstyles+4*esi]
-
- and ebx, not wsAllWindowBorder
- or ebx, [.styles+4*esi]
- invoke SetWindowLong, [.hwnd], GWL_STYLE, ebx
-
- lea esi, [.bounds]
- stdcall _GetWindowBounds, [.hwnd], esi
- stdcall _SetWindowBounds, [.hwnd], esi
-
- pop esi edx ecx ebx eax
- return
-
-.styles dd wsNoneWindowBorder
- dd wsFullWindowBorder
- dd wsModalWindowBorder
- dd wsToolboxWindowBorder
-
-.exstyles dd 0
- dd WS_EX_APPWINDOW
- dd WS_EX_DLGMODALFRAME
- dd WS_EX_TOOLWINDOW
-
-endp
-
-;_________________________________________________________________________________________
-
-proc _ShowWindow, .hwnd, .flag
-begin
- push eax ecx edx
- invoke ShowWindow, [.hwnd], [.flag]
- pop edx ecx eax
- return
-endp
-
-
-;_________________________________________________________________________________________
-
-
-proc _RefreshWindow, .hwnd
-.rect RECT
-begin
- push eax ecx edx
-
-; lea eax, [.rect]
-; invoke GetClientRect, [.hwnd], eax
-; lea eax, [.rect]
- invoke InvalidateRect, [.hwnd], 0, FALSE
-
- pop edx ecx eax
- return
-endp
-
-
-;_________________________________________________________________________________________
-
-
-proc _SetFocus, .hwnd
-begin
- push eax ecx edx
-
- invoke SetFocus, [.hwnd]
-
- pop edx ecx eax
- return
-endp
-
-;_________________________________________________________________________________________
-
-proc _AddChild, .hwnd, .child
-begin
- push eax ecx edx
-
- invoke GetWindowLong, [.child], GWL_STYLE
- or eax, WS_CHILD
- and eax, not (WS_DLGFRAME or WS_BORDER)
- invoke SetWindowLong, [.child], GWL_STYLE, eax
- invoke SetParent, [.child], [.hwnd]
-
- pop edx ecx eax
- return
-endp
-
-;_________________________________________________________________________________________
-
-
-; Common utility procedures.
-
-
-;_________________________________________________________________________________________
-;
-; Returns the window TObject structure, from the window handle.
-;_________________________________________________________________________________________
-
-proc _GetWindowStruct, .hwin
-begin
- push ecx edx
- invoke GetWindowLong, [.hwin], ofsWindowStruct
- pop edx ecx
- return
-endp
-
-
-
-;_________________________________________________________________________________________
-
-
-
-proc _SetWindowStruct, .hwin, .value
-begin
- push eax ecx edx
- invoke SetWindowLong, [.hwin], ofsWindowStruct, [.value]
- pop edx ecx eax
- return
-endp
-
-
-;_________________________________________________________________________________________
-
-
-
-proc _SetWindowTextUtf8, .hwnd, .ptrUtf8
-.pwc dd ?
-.charlen dd ?
-begin
- stdcall StrLen, [.ptrUtf8]
- lea ecx, [eax*4]
-
- stdcall GetMem, ecx
- mov [.pwc], eax
-
- invoke MultiByteToWideChar, CP_UTF8, 0, [.ptrUtf8], -1, [.pwc], ecx
- mov [.charlen], eax
-
- invoke SendMessage, [.hwnd], WM_SETTEXT, 0, [.pwc]
- stdcall FreeMem, [.pwc]
- return
-endp
-
-
-
-;_________________________________________________________________________________________
-
-
-
-proc _GetWindowTextUtf8, .hwnd, .ptrUtf8
-.pwc dd ?
-.charlen dd ?
-begin
- push ebx ecx edx edi
- stdcall StrNew
- mov ebx, eax
-
- invoke SendMessage, [.hwnd], WM_GETTEXTLENGTH, 0, 0
- mov [.charlen], eax
- lea ecx, [eax*4]
-
- stdcall StrSetCapacity, ebx, ecx
- mov edi, eax
-
- stdcall GetMem, ecx
- mov [.pwc], eax
-
- invoke SendMessage, [.hwnd], WM_GETTEXT, [.charlen], [.pwc]
- invoke WideCharToMultiByte, CP_UTF8, 0, [.pwc], -1, edi, [edi+string.capacity], 0, 0
- stdcall FreeMem, [.pwc]
- stdcall StrFixLen, ebx
- mov eax, ebx
- pop edi edx ecx ebx
- return
-endp
-
-
-
-;_________________________________________________________________________________________
-
-
-proc _EnableWindow, .hwnd, .flag
-begin
- push eax ecx edx
- invoke EnableWindow, [.hwnd], [.flag]
- pop edx ecx eax
- return
-endp
-
-
-;_________________________________________________________________________________________
-
-
-proc _SetModalTowards, .hwnd, .hwndParent
-begin
- push eax ecx edx
- stdcall _SetWindowBorder, [.hwnd], borderModal
- invoke SetWindowLong, [.hwnd], GWL_HWNDPARENT, [.hwndParent]
-
- pop edx ecx eax
- return
-endp
-
-
-;_________________________________________________________________________________________
-
-
-proc _FinalizeModal, .hwnd, .hwndParent
-begin
- return
-endp
-
-
-;_________________________________________________________________________________________
-
-
-proc __CommonWindowProc, .hwnd, .wmsg, .wparam, .lparam
-begin
- stdcall __ProcessOneSystemEvent, [.hwnd], [.wmsg], [.wparam], [.lparam] ; sometimes windows calls winproc directly instead of using postmessage.
- jnc .finish
-
- invoke DefWindowProc, [.hwnd], [.wmsg], [.wparam], [.lparam]
-
-.finish:
- return
-endp
-
DELETED freshlib/gui/all.asm
Index: freshlib/gui/all.asm
==================================================================
--- freshlib/gui/all.asm
+++ /dev/null
@@ -1,56 +0,0 @@
-; _______________________________________________________________________________________
-;| |
-;| ..::FreshLib::.. Free, open source. Licensed under "Fresh artistic license." |
-;|_______________________________________________________________________________________|
-;
-; Description: All GUI libraries combined include.
-;
-; Target OS: Any
-;
-; Dependencies:
-;
-; Notes: Includes all GUI libraries at once.
-;_________________________________________________________________________________________
-
-AlignLeft = 0
-AlignRight = 1
-AlignTop = 2
-AlignBottom = 3
-
-include 'sysevents.asm'
-
-; includes OS specific utility procedures, data, etc.
-include 'progutils.asm'
-
-include 'mouse.asm'
-include 'textcaret.asm'
-
-; OS independent support code
-include 'objects.asm'
-include 'TAction.asm'
-
-; OS independent template engine.
-include 'ObjTemplates.asm'
-
-; OS independent components
-include 'TObject.asm'
-include 'TWindow.asm'
-include 'TScrollWindow.asm'
-
-include 'TApplication.asm'
-include 'TForm.asm'
-include 'TButton.asm'
-include 'TEdit.asm'
-include 'TLabel.asm'
-include 'TImageLabel.asm'
-include 'TMenuItem.asm'
-include 'TMenu.asm'
-include 'TProgressbar.asm'
-include 'TTreeView.asm'
-
-include 'ThemeGUI.asm'
-
-include 'dialogs.asm'
-
-; OS independent main procedures.
-include 'Main.asm'
DELETED freshlib/gui/dialogs.asm
Index: freshlib/gui/dialogs.asm
==================================================================
--- freshlib/gui/dialogs.asm
+++ /dev/null
@@ -1,196 +0,0 @@
-; _______________________________________________________________________________________
-;| |
-;| ..::FreshLib::.. Free, open source. Licensed under "Fresh artistic license." |
-;|_______________________________________________________________________________________|
-;
-; Description: Common dialogs procedures library.
-;
-; Target OS: Any
-;
-; Dependencies:
-;
-; Notes:
-;_________________________________________________________________________________________
-module "Common dialogs library"
-
-
-iglobal
- getfile _DlgIconError, '%lib%/gui/images/error.gif'
- getfile _DlgIconInformation, '%lib%/gui/images/information.gif'
- getfile _DlgIconQuestion, '%lib%/gui/images/question.gif'
- getfile _DlgIconWarning, '%lib%/gui/images/warning.gif'
- getfile _DlgMaskDialogIcons, '%lib%/gui/images/icon_mask.gif'
-
- if used _CommonDialogTemplate
- _CommonDialogTemplate:
- ObjTemplate tfParent or tfEnd, Form, frmCommonDialog, x, 200, y, 100, width, 480, height, 100
- ObjTemplate tfChild, ImageLabel, .imgIcon, x, 4, y, 4, width, 50, height, 50, Visible, TRUE, ImageAlign, iaCenter or iaMiddle
- ObjTemplate tfChild, Label, .LblText, x,58, y, 4, width, 10, height, 10, TextAlign, dtfAlignLeft or dtfAlignMiddle or dtfWordWrap or dtfCRLF, Visible, TRUE
-
- ObjTemplate tfChild, Button, .btnOK, x, 0, y, 0, width, 64, height, 24, TextAlign, dtfAlignCenter or dtfAlignMiddle, Caption, 'OK', ModalResult, mrOK
- ObjTemplate tfChild, Button, .btnCancel, x, 0, y, 0, width, 64, height, 24, TextAlign, dtfAlignCenter or dtfAlignMiddle, Caption, 'Cancel', ModalResult, mrCancel
- ObjTemplate tfChild, Button, .btnAbort, x, 0, y, 0, width, 64, height, 24, TextAlign, dtfAlignCenter or dtfAlignMiddle, Caption, 'Abort', ModalResult, mrAbort
- ObjTemplate tfChild, Button, .btnRetry, x, 0, y, 0, width, 64, height, 24, TextAlign, dtfAlignCenter or dtfAlignMiddle, Caption, 'Retry', ModalResult, mrRetry
- ObjTemplate tfChild, Button, .btnIgnore, x, 0, y, 0, width, 64, height, 24, TextAlign, dtfAlignCenter or dtfAlignMiddle, Caption, 'Ignore', ModalResult, mrIgnore
- ObjTemplate tfChild, Button, .btnYes, x, 0, y, 0, width, 64, height, 24, TextAlign, dtfAlignCenter or dtfAlignMiddle, Caption, 'Yes', ModalResult, mrYes
- ObjTemplate tfChild, Button, .btnNo, x, 0, y, 0, width, 64, height, 24, TextAlign, dtfAlignCenter or dtfAlignMiddle, Caption, 'No', ModalResult, mrNo
- ObjTemplate tfChild, Button, .btnMaybe, x, 0, y, 0, width, 64, height, 24, TextAlign, dtfAlignCenter or dtfAlignMiddle, Caption, 'Maybe', ModalResult, mrMaybe
- ObjTemplate tfEnd, Button, .btnHelp, x, 0, y, 0, width, 64, height, 24, TextAlign, dtfAlignCenter or dtfAlignMiddle, Caption, 'Help', ModalResult, mrNone
- end if
-endg
-
-
-; buttons flags used:
-smbOK = $01
-smbCancel = $02
-smbAbort = $04
-smbRetry = $08
-smbIgnore = $10
-smbYes = $20
-smbNo = $40
-smbMaybe = $80
-smbHelp = $100
-smbMaxButton = smbHelp
-
-smiError = 0
-smiInformation = 1
-smiQuestion = 2
-smiWarning = 3
-
-
-
-proc ShowMessage, .parent, .icon, .hTitle, .hMessage, .maskButtons
-.xrow dd ?
-.yrow dd ?
-.hicon dd ?
-.hmask dd ?
-begin
- push ebx ecx edx esi
- stdcall CreateFromTemplate, _CommonDialogTemplate, 0
-
-; First set the position and size of the dialog box, depending on the flags, and the size of the message.
-
-
-
-; Set the message text:
- stdcall Set, [frmCommonDialog.LblText], TLabel.Caption, [.hMessage]
-
-; Set the message title:
- stdcall Set, ebx, TForm.Caption, [.hTitle]
-
-; arrange the buttons
- mov eax, [.maskButtons]
- mov ecx, 32
- xor edx, edx
-.count:
- rol eax, 1
- adc edx, 0
- loop .count
-
- mov ecx, edx
- imul edx, 64 ; button width
- jecxz @f
- dec ecx
- imul ecx, 16
-@@:
- add edx, ecx ; edx contains the width of the button row in pixels.
-
- stdcall Get, ebx, TForm.width
- cmp eax, edx
- jge .widthok
-
- lea eax, [edx+32]
- stdcall Set, ebx, TForm.width, eax
-
-.widthok:
- sub eax, edx
- sar eax, 1 ; eax is the begin X coordinate of the row
- mov [.xrow], eax
-
- stdcall Get, ebx, TForm.height
- sub eax, 24+8
- mov [.yrow], eax
-
- mov edx, .btnTable
- mov ecx, $1
-
-.btnLoop:
- test [.maskButtons], ecx
- jz @f
-
- mov esi, [edx]
- stdcall Set, [esi], TButton.x, [.xrow]
- stdcall Set, [esi], TButton.y, [.yrow]
- stdcall Set, [esi], TButton.Visible, TRUE
- add [.xrow], 64+16
-
-@@:
- add edx, 4
- shl ecx, 1
- cmp ecx, smbMaxButton
- jbe .btnLoop
-
-; set the icon
- mov eax, [.icon]
- cmp eax, .iconCount
- jb @f
- xor eax, eax
-@@:
- stdcall CreateImageGIF, [.iconTable+4*eax], [.iconSizes+4*eax]
- OutputRegister regEAX, 16
- mov [.hicon], eax
- stdcall Set, [frmCommonDialog.imgIcon], TImageLabel.Image, eax
-
- stdcall CreateImageGIF, _DlgMaskDialogIcons, _DlgMaskDialogIcons.size
- OutputRegister regEAX, 16
- mov [.hmask], eax
- stdcall Set, [frmCommonDialog.imgIcon], TImageLabel.Mask, eax
-
-; set the text position and size.
- mov ecx, [.yrow]
- sub ecx, 8
- stdcall Set, [frmCommonDialog.LblText], TLabel.height, ecx
- stdcall Set, [frmCommonDialog.imgIcon], TImageLabel.height, ecx
-
- stdcall Get, [frmCommonDialog], TForm.width
- sub eax, 66
- stdcall Set, [frmCommonDialog.LblText], TLabel.width, eax
-
- stdcall ShowModal, ebx, [.parent]
- stdcall Destroy, ebx
- stdcall DestroyImage, [.hicon]
- stdcall DestroyImage, [.hmask]
-
- pop esi edx ecx ebx
- return
-
-.btnTable dd frmCommonDialog.btnOK, \
- frmCommonDialog.btnCancel, \
- frmCommonDialog.btnAbort, \
- frmCommonDialog.btnRetry, \
- frmCommonDialog.btnIgnore, \
- frmCommonDialog.btnYes, \
- frmCommonDialog.btnNo, \
- frmCommonDialog.btnMaybe, \
- frmCommonDialog.btnHelp
-
-.iconTable dd _DlgIconError, _DlgIconInformation, _DlgIconQuestion, _DlgIconWarning
-.iconCount = ($ - .iconTable)/4
-.iconSizes dd _DlgIconError.size, _DlgIconInformation.size, _DlgIconQuestion.size, _DlgIconWarning.size
-
-endp
-
-
-proc InputString, .parent
-begin
-
-
- return
-endp
-
-
-
-
-
-
-endmodule
DELETED freshlib/gui/images/error.gif
Index: freshlib/gui/images/error.gif
==================================================================
--- freshlib/gui/images/error.gif
+++ /dev/null
cannot compute difference between binary files
DELETED freshlib/gui/images/icon_mask.gif
Index: freshlib/gui/images/icon_mask.gif
==================================================================
--- freshlib/gui/images/icon_mask.gif
+++ /dev/null
cannot compute difference between binary files
DELETED freshlib/gui/images/information.gif
Index: freshlib/gui/images/information.gif
==================================================================
--- freshlib/gui/images/information.gif
+++ /dev/null
cannot compute difference between binary files
DELETED freshlib/gui/images/question.gif
Index: freshlib/gui/images/question.gif
==================================================================
--- freshlib/gui/images/question.gif
+++ /dev/null
cannot compute difference between binary files
DELETED freshlib/gui/images/theme_rhomb/Icons.odg
Index: freshlib/gui/images/theme_rhomb/Icons.odg
==================================================================
--- freshlib/gui/images/theme_rhomb/Icons.odg
+++ /dev/null
cannot compute difference between binary files
DELETED freshlib/gui/images/theme_rhomb/myown/error.gif
Index: freshlib/gui/images/theme_rhomb/myown/error.gif
==================================================================
--- freshlib/gui/images/theme_rhomb/myown/error.gif
+++ /dev/null
cannot compute difference between binary files
DELETED freshlib/gui/images/theme_rhomb/myown/information.gif
Index: freshlib/gui/images/theme_rhomb/myown/information.gif
==================================================================
--- freshlib/gui/images/theme_rhomb/myown/information.gif
+++ /dev/null
cannot compute difference between binary files
DELETED freshlib/gui/images/theme_rhomb/myown/mask.gif
Index: freshlib/gui/images/theme_rhomb/myown/mask.gif
==================================================================
--- freshlib/gui/images/theme_rhomb/myown/mask.gif
+++ /dev/null
cannot compute difference between binary files
DELETED freshlib/gui/images/theme_rhomb/myown/question.gif
Index: freshlib/gui/images/theme_rhomb/myown/question.gif
==================================================================
--- freshlib/gui/images/theme_rhomb/myown/question.gif
+++ /dev/null
cannot compute difference between binary files
DELETED freshlib/gui/images/theme_rhomb/myown/warning.gif
Index: freshlib/gui/images/theme_rhomb/myown/warning.gif
==================================================================
--- freshlib/gui/images/theme_rhomb/myown/warning.gif
+++ /dev/null
cannot compute difference between binary files
DELETED freshlib/gui/images/warning.gif
Index: freshlib/gui/images/warning.gif
==================================================================
--- freshlib/gui/images/warning.gif
+++ /dev/null
cannot compute difference between binary files
DELETED freshlib/gui/mouse.asm
Index: freshlib/gui/mouse.asm
==================================================================
--- freshlib/gui/mouse.asm
+++ /dev/null
@@ -1,29 +0,0 @@
-; _______________________________________________________________________________________
-;| |
-;| ..::FreshLib::.. Free, open source. Licensed under "Fresh artistic license." |
-;|_______________________________________________________________________________________|
-;
-; Description: Provides unified access to standard mouse cursors.
-;
-; Target OS: Any
-;
-; Dependencies:
-;
-; Notes: This file contains OS independent part and includes OS dependent files.
-;_________________________________________________________________________________________
-module "Mouse library"
-
-mcArrow = 0
-mcText = 1
-mcCross = 2
-mcSizeH = 3
-mcSizeV = 4
-mcSizeUL_LR = 5
-mcSizeLL_UR = 6
-mcWait = 7
-
-mcCount = 8
-
-include '%TargetOS%/mouse.asm'
-
-endmodule
DELETED freshlib/gui/objects.asm
Index: freshlib/gui/objects.asm
==================================================================
--- freshlib/gui/objects.asm
+++ /dev/null
@@ -1,511 +0,0 @@
-; _______________________________________________________________________________________
-;| |
-;| ..::FreshLib::.. Free, open source. Licensed under "Fresh artistic license." |
-;|_______________________________________________________________________________________|
-;
-; Description: Contains the base procedures for the FreshLib OOP framework
-;
-; Target OS: Any
-;
-; Dependencies: memory.asm
-;
-; Notes:
-;
-; TODO: Thread safety! The whole FreshLib should be thread safe. GUI part,as long as
-; uses memory objects should be thread safe. This can be achieved by locking
-; objects, during processing. objects.asm is the proper place for such lock mechanism.
-; The lock should be provided by some kind of mutex objects, associated with the objects.
-;
-;_________________________________________________________________________________________
-module "Objects library"
-
-struct TObjectClass
- .ptrParent dd 0 ; pointer to the parent TObjectClass
- .dataSize dd 0 ; size of TObject structure.
- .procCreate dd 0
- .procDestroy dd 0
- .procGetParam dd 0
- .procSetParam dd 0
- .procExecCmd dd 0 ; executes method in chain.
- .procSysEventHandler dd 0
-ends
-
-
-
-macro ObjectClass name*, parent*, procCreate*, procDestroy*, procGetParam*, procSetParam*, procExecCmd*, procSysEvents* {
- if used C#name
- C#name TObjectClass
- store dword C#parent at C#name#.ptrParent
- store dword sizeof.T#name at C#name#.dataSize
- store dword procCreate at C#name#.procCreate
- store dword procDestroy at C#name#.procDestroy
- store dword procGetParam at C#name#.procGetParam
- store dword procSetParam at C#name#.procSetParam
- store dword procExecCmd at C#name#.procExecCmd
- store dword procSysEvents at C#name#.procSysEventHandler
- end if
-}
-
-
-CRoot = 0
-
-
-maskParameter = $80000000
-Sequence param, maskParameter
-
-
-macro method name*, [arg] {
-common
- local ..argcount
- ..argcount = 0
- param name
- forward
- if ~arg eq
- ..argcount = ..argcount + 1
- end if
- common
- name#.argcount = ..argcount
-}
-
-
-macro execute obj*, meth*, [arg] {
-reverse
- if ~arg eq
- pushd arg
- end if
-common
- pushd meth#.argcount
- pushd meth
- pushd obj
- call __Exec
-}
-
-
-macro object name*, parent {
- macro name@object \{ name name \}
- macro size@object \{ sizeof.#name = $ \}
- struc name \{
- param.current = maskParameter
- if ~parent eq
- . parent
- end if
-}
-
-endobj fix } obj_helper
-
-macro obj_helper {
- virtual at 0
- name@object
- size@object
- end virtual
- purge name@object
- purge size@object
-}
-
-
-mxTimeout = 1000 ; 1s timeout for the access mutex objects.
-
-; common object procedures
-; These procedures work with every TObject descendent object type.
-
-
-;_________________________________________________________________________________________
-;
-; proc Create, .class - creates an instance from the given class.
-;
-; Arguments:
-; .class - pointer to TObjectClass structure for needed object.
-;
-; Returns:
-; ebx = pointer to the instance of the object.
-;
-; This procedure calls procCreate for the given object class and all
-; parent classes in reverce order.
-;_________________________________________________________________________________________
-
-proc Create, .class
-begin
- push eax ecx
-
- mov ecx, [.class]
- stdcall GetMem, [ecx+TObjectClass.dataSize]
- mov ebx, eax
- mov [eax+TObject.ptrClass], ecx
-
- lea eax, [eax+TObject.mxAccess]
- stdcall MutexCreate, 0, eax
-
- push 0
-
-.loop:
- cmp [ecx+TObjectClass.procCreate], 0
- je .parent
-
- push [ecx+TObjectClass.procCreate]
-
-.parent:
- mov ecx, [ecx+TObjectClass.ptrParent]
- test ecx, ecx
- jnz .loop
-
-.loop2:
- pop ecx
- jecxz .endcreate
-
- push ebx
- stdcall ecx, ebx
- pop ebx
- jmp .loop2
-
-.endcreate:
- lea eax, [ebx+TObject.mxAccess]
- stdcall MutexRelease, eax
- pop ecx eax
- return
-endp
-
-
-
-;_________________________________________________________________________________________
-;
-; proc Destroy, .obj - destroys the object instance.
-;
-; Arguments:
-; .obj - pointer to TObject descendent object.
-;
-; Returns:
-; nothing.
-;
-; This procedure calls procDestroy for the given object class and all
-; parent classes. Note that the memory is freed only by the last
-; destroy handled from CObject class.
-;_________________________________________________________________________________________
-
-proc Destroy, .obj
-begin
- push eax ebx
-
- mov ebx, [.obj]
- test ebx, ebx
- jz .error
-
- stdcall _LockObject, [.obj]
-
- mov ebx, [ebx+TObject.ptrClass]
-
-.loop:
- cmp [ebx+TObjectClass.procDestroy], 0
- je .parent
-
- mov eax, [ebx+TObjectClass.procDestroy]
-
- push ebx
- stdcall [ebx+TObjectClass.procDestroy], [.obj]
- pop ebx
-
-.parent:
- mov ebx, [ebx+TObjectClass.ptrParent]
- test ebx, ebx
- jnz .loop
-
- mov ebx, [.obj]
- lea eax, [ebx+TObject.mxAccess]
-
- mov ebx, [ebx+TObject.ptrVar]
- test ebx, ebx
- jz @f
- mov dword [ebx], 0
-@@:
- stdcall MutexDestroy, eax
- stdcall FreeMem, [.obj]
- clc
- pop ebx eax
- return
-
-.error:
- stdcall _UnlockObject, [.obj]
- stc
- pop ebx eax
- return
-endp
-
-
-
-
-;_________________________________________________________________________________________
-;
-; proc Get, .obj, .paramID - returns the value of given parameter
-;
-; Arguments:
-; .obj - pointer to TObject descendent object.
-; .paramID - ID number of the parameter being read.
-; Returns:
-; CF=0; eax = parameter value.
-; CF=1; the parameter is unknown and can not be retrived.
-;
-; This procedure calls procGet for the given object class and
-; if the procedure returns CF=1; tries to call the parents procedure
-; procGet, until the value is retrived, or the root level of inheritance
-; is reached.
-;_________________________________________________________________________________________
-
-proc Get, .obj, .paramID
-begin
- push ecx
-
-
- stdcall _LockObject, [.obj]
-
- mov ecx, [.obj]
-.loop0:
- stc
- jecxz .finish
-
-.loop:
- mov ecx, [ecx] ; TObject.ptrClass = TObjectClass.ptrParent = 0
- jecxz .finish
-
- cmp [ecx+TObjectClass.procGetParam], 0
- je .loop0
-
- push ecx
- stdcall [ecx+TObjectClass.procGetParam], [.obj], [.paramID]
- pop ecx
- jc .loop
-
-.finish:
- stdcall _UnlockObject, [.obj]
- pop ecx
- return
-endp
-
-
-
-;_________________________________________________________________________________________
-;
-; proc Set, .obj, .paramID - sets the value of given parameter
-;
-; Arguments:
-; .obj - pointer to TObject descendent object.
-; .paramID - ID number of the parameter being read.
-; .value - value of the parameter that should be set.
-; Returns:
-; CF=0 - the value is successfully set.
-; CF=1; the value is not set, because the parameter is unknown.
-;
-; This procedure calls procSet for the given object class and
-; if the procedure returns CF=1; tries to call the parents procedures
-; procSet, until the value is set, or the root level of inheritance
-; is reached.
-;_________________________________________________________________________________________
-
-proc Set, .obj, .paramID, .value
-begin
- push ecx
-
- stdcall _LockObject, [.obj]
- mov ecx, [.obj]
-.loop0:
- stc
- jecxz .finish
-
-.loop:
- mov ecx, [ecx] ; TObject.ptrClass = TObjectClass.ptrParent = 0
- jecxz .finish
-
- cmp [ecx+TObjectClass.procSetParam], 0
- je .loop0
-
- push ecx
- stdcall [ecx+TObjectClass.procSetParam], [.obj], [.paramID], [.value]
- pop ecx
- jc .loop
-
-.finish:
- stdcall _UnlockObject, [.obj]
- pop ecx
- return
-endp
-
-
-
-
-
-;_________________________________________________________________________________________
-;
-; proc ExecEvent, .obj, .event
-; Arguments:
-; .obj - pointer to the TObject descendent object.
-; .event - pointer to TSysEvent descendent structure.
-;_________________________________________________________________________________________
-
-proc ExecEvent, .obj, .event
-begin
- push ecx
-
- stdcall _LockObject, [.obj]
- mov ecx, [.obj]
-.loop0:
- stc
- jecxz .finish
-
-.loop:
- mov ecx, [ecx] ; TObject.ptrClass = TObjectClass.ptrParent = 0
- jecxz .finish
-
- cmp [ecx+TObjectClass.procSysEventHandler], 0
- je .loop0
-
- push ecx
- stdcall [ecx+TObjectClass.procSysEventHandler], [.obj], [.event]
- pop ecx
- jc .loop
-
-.finish:
- stdcall _UnlockObject, [.obj]
- pop ecx
- return
-endp
-
-
-
-
-;_________________________________________________________________________________________
-;
-; proc IsObject, .class - returns CF=0 if the given object belongs to
-; the given class. Else returns CF=1
-;_________________________________________________________________________________________
-proc IsObject ; , .obj, .class
-virtual at esp+8
- .obj dd ?
- .class dd ?
-end virtual
-begin
- push ecx
- lea ecx, [.obj]
-
-.loop:
- stc
- mov ecx, [ecx] ; TObject.ptrClass = TObjectClass.ptrParent = 0
- jecxz .finish
-
- cmp ecx, [.class] ; the first cmp will always fail because ecx contains pointer to obj that can't be equal to a class.
- jne .loop
-
-.finish:
- pop ecx
- retn 8
-endp
-
-
-
-;_________________________________________________________________________________________
-;
-; Executes a method of given class.
-; This procedure have arbitrary count of arguments
-; it calls in chain procExecCmd the classes and passes
-; a pointer to the arguments in esi.
-; It first calls the procExecCmd of the childs and then of the parents.
-; If some class have 0 in [procExecCmd] this class is skiped and
-; the execution continues on its parent.
-; If there is no proper handler back to the root, then the procedure
-; returns CF=1
-;_________________________________________________________________________________________
-
-proc __Exec ;, .obj, .method, .argcount, ..
-begin
-virtual at ebp+8
- .obj dd ?
- .method dd ?
- .argcount dd ?
- .arguments:
-end virtual
- push ebp
- mov ebp, esp ; now ebp+8 points to the arguments.
-
- push ecx ebx
-
- xor ebx, ebx
- cmp [.argcount], 0
- je @f
- lea ebx, [.arguments]
-@@:
- mov ecx, [.obj]
-
-.loop0:
- stc
- jecxz .exit
-
-.loop:
- mov ecx, [ecx] ; TObject.ptrClass = TObjectClass.ptrParent = 0
- jecxz .exit
-
- cmp [ecx+TObjectClass.procExecCmd], 0
- je .loop0
-
- push ecx ebx
- stdcall [ecx+TObjectClass.procExecCmd], [.obj], [.method]
- pop ebx ecx
- jc .loop
-
-.exit:
- pop ebx ecx
-
- ; experimental return from procedure with arbitrary count of arguments.
- ; with keeping all registers unchanged.
- mov esp, ebp
- push ecx
- mov ebp, [.argcount]
- lea ebp, [esp+8+4*ebp+12] ; the place where the return address should be placed. (Exec have 3 more arguments, including .argcount)
- mov ecx, [esp+8] ; return address
- mov [ebp], ecx ; move the return address to the proper place.
- pop ecx ; restore ecx
- pop esp ; old value of ebp
- xchg esp, ebp ; restore ebp and set esp to the proper value
- retn
-endp
-
-
-
-
-proc _LockObject, .obj
-begin
- push eax
-
- mov eax, [.obj]
- lea eax, [eax+TObject.mxAccess]
- stdcall WaitForMutex, eax, mxTimeout
- jc .stop
-
- pop eax
- return
-
-.stop:
- int3
- pop eax
- return
-
-endp
-
-
-
-
-proc _UnlockObject, .obj
-begin
- pushf
- push eax
-
- mov eax, [.obj]
- lea eax, [eax+TObject.mxAccess]
- stdcall MutexRelease, eax
-
- pop eax
- popf
- return
-endp
-
-
-
-
-
-endmodule
DELETED freshlib/gui/progutils.asm
Index: freshlib/gui/progutils.asm
==================================================================
--- freshlib/gui/progutils.asm
+++ /dev/null
@@ -1,62 +0,0 @@
-; _______________________________________________________________________________________
-;| |
-;| ..::FreshLib::.. Free, open source. Licensed under "Fresh artistic license." |
-;|_______________________________________________________________________________________|
-;
-; Description: Common OS independent programming utilities.
-;
-; Target OS: Any
-;
-; Dependencies:
-;
-; Notes:
-;_________________________________________________________________________________________
-module "Programming utilities"
-
-macro JumpList [id, target] {
- forward
- dw id, target - $ - 2
- common
- dd 0
-}
-
-macro JumpTable [id, target] {
-if ~ msg eq
- call JumpTo
- JumpList msg, target
-end if
-}
-
-
-;------------------------------------------------------
-; proc JumpTo
-; Searches for the message in the message table.
-; Arguments:
-; ebx - message number to search in the table.
-; Returns:
-; This procedure doesn't returns. It simply
-; jumps to the address from table or imediately
-; after the table if the message is not found.
-; in both cases esi = eip
-; Changes:
-; eax, ecx
-;------------------------------------------------------
-proc JumpTo
-begin
- pop ecx ; get table address, remove return address from the stack and save the value of esi.
-.loop:
- mov eax, [ecx]
- lea ecx, [ecx+4]
- test eax,eax
- jz .exit
-
- cmp bx, ax
- jne .loop
-
- sar eax, 16
- add ecx, eax
-.exit:
- jmp ecx
-endp
-
-endmodule
DELETED freshlib/gui/sysevents.asm
Index: freshlib/gui/sysevents.asm
==================================================================
--- freshlib/gui/sysevents.asm
+++ /dev/null
@@ -1,297 +0,0 @@
-; _______________________________________________________________________________________
-;| |
-;| ..::FreshLib::.. Free, open source. Licensed under "Fresh artistic license." |
-;|_______________________________________________________________________________________|
-;
-; Description: Defines constants and structures for system events of FreshLib
-;
-; Target OS: Any
-;
-; Dependencies:
-;
-; Notes:
-;_________________________________________________________________________________________
-module "System events library"
-
-seMouseMove = $0001
-seMouseEnter = $0002
-seMouseLeave = $0003
-seMouseBtnPress = $0004
-seMouseBtnRelease = $0005
-seMouseBtnClick = $0006
-seMouseBtnDblClick = $0007
-seTimer = $0008
-seKbdKeyPress = $0009
-seKbdKeyRelease = $000a
-seKbdStatusChanged = $000b
-seKbdChar = $000c
-
-seScroll = $000d
-
-
-sePaint = $0100
-seCloseRequest = $0101
-
-seFocusIn = $0102
-seFocusOut = $0103
-
-seMoveResize = $0104
-
-
-struct TSysEvent
- .event dd ?
-ends
-
-
-struct TMouseMoveEvent
- . TSysEvent
- .x dd ?
- .y dd ?
-ends
-
-mbLeft = 0
-mbMiddle = 1
-mbRight = 2
-
-maskBtnLeft = $0100
-maskBtnMiddle = $0200
-maskBtnRight = $0400
-maskShift = $1
-maskCapsLock = $2
-maskCtrl = $4
-maskAlt = $8
-maskScrLk = $10
-
-
-struct TMouseButtonEvent
- . TSysEvent
- .Button dd ?
- .kbdStatus dd ?
- .x dd ? ; coordinates of the mouse pointer in the client
- .y dd ?
-ends
-
-
-struct TMouseEnterEvent
- . TSysEvent
-ends
-
-
-; These are scan codes for the non character keys. They are OS dependent and should be used by
-; their names.
-include '%TargetOS%/keycodes.inc'
-
-
-struct TKeyboardEvent
- . TSysEvent
- .key dd ? ; 1..4 bytes UTF-8 character typed by the keyboard, or 0 if non character key is pressed/released.
- .scancode dd ? ; scan code of the pressed key.
- .kbdStatus dd ? ; same as mouse button event - contains mouse buttons and Ctrl, Shift and Alt keys status.
-ends
-
-
-scTrack = 1
-scUp = 2
-scDown = 3
-scWheelUp = 4
-scWheelDn = 5
-
-scrollX = 0
-scrollY = 1
-
-
-struct TScrollEvent
- . TSysEvent
- .ScrollBar dd ? ; 0
- .ScrollCmd dd ? ;
- .Value dd ? ; Distance for scUp and scDown and position for scTrack
-ends
-
-
-struct TTimerEvent
- . TSysEvent
- .timer dd ?
-ends
-
-
-struct TPaintEvent
- . TSysEvent
-
- .context dd ? ; pointer to TContext structure, properly initialized.
- .rect RECT
-ends
-
-
-struct TCloseEvent
- . TSysEvent
- .reason dd ? ; how the close was requested?
-ends
-
-cerFromUser = 0 ; user pressed X button on the window header, pressed alt+F4 from the keyboard, or choose "Close" from the title menu.
-cerFromProgram = 1 ; Method Close was executed from the program.
-
-
-struct TFocusInEvent
- . TSysEvent
-ends
-
-struct TFocusOutEvent
- . TSysEvent
-ends
-
-
-struct TMoveResizeEvent
- . TSysEvent
- .newX dd ?
- .newY dd ?
- .newWidth dd ?
- .newHeight dd ?
-ends
-
-
-
-; creates and returns a string with the textual identifier of the pressed/released key.
-proc CreateKeyName, .pKeyEvent
-begin
- push ebx ecx esi edi
-
- stdcall StrDup, .strkey
- mov ebx, eax
-
- mov edi, [.pKeyEvent]
- test [edi+TKeyboardEvent.kbdStatus], maskCtrl
- jz @f
-
- stdcall StrCharCat, ebx, 'Ctrl'
- stdcall StrCharCat, ebx, '+'
-@@:
- test [edi+TKeyboardEvent.kbdStatus], maskAlt
- jz @f
- stdcall StrCharCat, ebx, 'Alt+'
-@@:
- test [edi+TKeyboardEvent.kbdStatus], maskShift
- jz @f
- stdcall StrCharCat, ebx, 'Shif'
- stdcall StrCharCat, ebx, 't+'
-@@:
- mov ecx, [edi+TKeyboardEvent.key]
- jecxz .searchlist
-
- cmp ecx, ' '
- jne @f
- mov ecx, 'Spc'
-@@:
- cmp ecx, ' '
- jae @f
- add ecx, '@'
-@@:
- cmp ecx, 'a'
- jb @f
- cmp ecx, 'z'
- ja @f
- xor ecx, $20
-@@:
- stdcall StrCharCat, ebx, ecx
-
-.exitok:
- mov eax, ebx
- clc
-
-.finish:
- pop edi esi ecx ebx
- return
-
-.searchlist:
- mov esi, __FunctionalKeyNames
-
-.loop:
- movzx ecx, word [esi]
- jecxz .notfound
- cmp ecx, [edi+TKeyboardEvent.scancode]
- je .found
- add esi, 4
- jmp .loop
-
-.found:
- movsx eax, word [esi+2]
- add esi, eax
- stdcall StrCat, ebx, esi
- jmp .exitok
-
-.notfound:
- stdcall StrDel, ebx
- xor eax, eax
- stc
- jmp .finish
-
-.strkey db 'key', 0
-endp
-
-
-macro keynames lbl, [scancode, name] {
-common
- label lbl word
-forward
- local pname
- dw scancode
- dw pname - $ + 2
-common
- dw 0
-forward
- pname db name, 0
-}
-
-
-iglobal
- if used __FunctionalKeyNames
- keynames __FunctionalKeyNames, \
- keyHomeNumpad, 'Home', \
- keyUpNumpad, 'Up', \
- keyPgUpNumpad, 'PgUp', \
- keyLeftNumpad, 'Left', \
- key5Numpad, 'Num5', \
- keyRightNumpad, 'Right', \
- keyEndNumpad, 'End', \
- keyDownNumpad, 'Down', \
- keyPgDnNumpad, 'PgDn', \
- keyInsNumpad, 'Ins', \
- keyDelNumpad, 'Del', \
- keyEnterNumpad, 'Enter', \
- keyNumLock, 'NumLock', \
- keyScrollLock, 'ScrLock', \
- keyPause, 'Pause', \
- keyLeft, 'Left', \
- keyRight, 'Right', \
- keyUp, 'Up', \
- keyDown, 'Down', \
- keyInsert, 'Ins', \
- keyDelete, 'Del', \
- keyHome, 'Home', \
- keyEnd, 'End', \
- keyPgUp, 'PgUp', \
- keyPgDown, 'PgDn', \
- keyF1, 'F1', \
- keyF2, 'F2', \
- keyF3, 'F3', \
- keyF4, 'F4', \
- keyF5, 'F5', \
- keyF6, 'F6', \
- keyF7, 'F7', \
- keyF8, 'F8', \
- keyF9, 'F9', \
- keyF10, 'F10', \
- keyF11, 'F11', \
- keyF12, 'F12', \
- keyCapsLock, 'CapsLock', \
- keyShiftLeft, 'ShiftL', \
- keyCtrlLeft, 'CtrlL', \
- keyAltLeft, 'AltL', \
- keyAltRight, 'AltR', \
- keyPopupMenu, 'PopupMenu', \
- keyShiftRight, 'ShiftR', \
- keyCtrlRight, 'CtrlR', \
- keyBackSpace, 'BackSp'
- end if
-endg
-
-endmodule
DELETED freshlib/gui/textcaret.asm
Index: freshlib/gui/textcaret.asm
==================================================================
--- freshlib/gui/textcaret.asm
+++ /dev/null
@@ -1,263 +0,0 @@
-; _______________________________________________________________________________________
-;| |
-;| ..::FreshLib::.. Free, open source. Licensed under "Fresh artistic license." |
-;|_______________________________________________________________________________________|
-;
-; Description: Text caret control library.
-;
-; Target OS: Any
-;
-; Dependencies: timers.asm; graphics libraries.
-;
-; Notes: Text caret have always only one instance.
-;_________________________________________________________________________________________
-module "Text caret library"
-
-; the caret is shared resource and can exists only in one instance
-struct TCaret
- .pWindow dd ?
- .visible dd ?
- .state dd ? ; 1 if the caret is displayed 0 if not.
- .Pos TBounds
- .OldPos TBounds
- .timer dd ?
- .sync dd ?
-ends
-
-
-
-uglobal
- if used CaretAttach
- Caret TCaret
- end if
-endg
-
-iglobal
- if used CaretTimes
- CaretTimes dd 200, 300
- end if
-endg
-
-
-if used CaretAttach
-
-initialize InitCaretTimer
-begin
- stdcall TimerCreate
- mov [eax+TTimer.interval], 200
- mov [eax+TTimer.Callback], __CaretTimerProc
- mov [eax+TTimer.flags], tmfCallProc
- mov [Caret.timer], eax
- return
-endp
-
-
-finalize DestroyCaretTimer
-begin
- stdcall CaretAttach, 0
- mov eax, [Caret.timer]
- and [eax+TTimer.flags], not tmfRunning
- stdcall TimerDestroy, eax
- return
-endp
-
-end if
-
-
-; Attaches the caret to the window, if the window needs caret.
-proc CaretAttach, .pWindow
-begin
- mov eax,[.pWindow]
- cmp eax, [Caret.pWindow]
- je .exit
-
- mov eax, -1
-@@:
- xchg [Caret.sync], eax
- test eax, eax
- jnz @b
-
- stdcall __DrawCaret, 0 ; hide the caret.
-
- mov eax, [.pWindow]
- xchg [Caret.pWindow], eax
- push eax
-
- xor eax, eax
- mov [Caret.visible], eax
- mov [Caret.Pos.x], eax
- mov [Caret.Pos.y], eax
- mov [Caret.Pos.height], eax
- mov [Caret.Pos.width], eax
-
-.finish:
- mov [Caret.sync], 0
- pop eax ; the old window.
-.exit:
- return
-endp
-
-
-
-
-proc CaretChange, .x, .y, .width, .height
-begin
- push eax
-
- mov eax, -1
-@@:
- xchg [Caret.sync], eax
- test eax, eax
- jnz @b
-
- stdcall __DrawCaret, 0
-
- push [.x] [.y]
- pop [Caret.Pos.y] [Caret.Pos.x]
-
- cmp [.width], 0
- je .endchange
-
- push [.width] [.height]
- pop [Caret.Pos.height] [Caret.Pos.width]
-
- stdcall __DrawCaret, 1
-
-.endchange:
- mov [Caret.sync], 0
-
- pop eax
- return
-endp
-
-
-; returns the old mode.
-proc __CaretShow, .visible
-begin
- mov eax, [.visible]
- cmp eax, [Caret.visible] ; old vs new mode.
- je .exit
-
- push [Caret.visible]
- mov [Caret.visible], eax
-
- push ecx edx
-
- mov ecx, [Caret.timer]
- mov edx, [ecx+TTimer.flags]
-
- or edx, tmfRunning
- test eax, eax
- jnz .timerok
- and edx, not tmfRunning
-.timerok:
- mov [ecx+TTimer.flags], edx
-
- stdcall __DrawCaret, [Caret.visible]
- pop edx ecx
-
- pop eax
-.exit:
- return
-endp
-
-
-proc CaretShow, .visible
-begin
- mov eax, -1
-@@:
- xchg [Caret.sync], eax
- test eax, eax
- jnz @b
-
- stdcall __CaretShow, [.visible]
- mov [Caret.sync], 0
-
- return
-endp
-
-
-
-proc __CaretTimerProc, .timer
-begin
- cmp [Caret.pWindow], 0
- je .exit
-
- mov eax, -1
- xchg [Caret.sync], eax
- test eax, eax
- jnz .exit ; don't wait for lock.
-
- cmp [Caret.visible], 0
- je @f
- mov eax, 2
-@@:
- stdcall __DrawCaret, eax
-
- mov [Caret.sync], 0
-
-.exit:
- return
-endp
-
-
-
-proc __DrawCaret, .operation ; 0 - erase; 1-draw; 2-change
-begin
- push ecx esi
-
- mov eax, [Caret.state]
- cmp eax, [.operation]
- je .exit
-
- cmp [Caret.pWindow], 0
- je .exit
-
- push $ffffff
-
- xor eax, 1
- mov [Caret.state], eax
-
- mov ecx, [Caret.timer]
- mov eax, [Caret.state]
- mov eax, [CaretTimes+4*eax]
- mov [ecx+TTimer.interval], eax
- mov [ecx+TTimer.value], 0
-
- test eax, eax
- jnz .draw
-; clear
- push [Caret.OldPos.height]
- push [Caret.OldPos.width]
- push [Caret.OldPos.y]
- push [Caret.OldPos.x]
- jmp .drawit
-
-.draw:
- push [Caret.Pos.height] [Caret.Pos.width] [Caret.Pos.y] [Caret.Pos.x]
- push [Caret.Pos.height] [Caret.Pos.width] [Caret.Pos.y] [Caret.Pos.x]
- pop [Caret.OldPos.x] [Caret.OldPos.y] [Caret.OldPos.width] [Caret.OldPos.height]
-
-.drawit:
- mov eax, [Caret.pWindow]
- stdcall AllocateContext, [eax+TWindow.handle]
- test eax, eax
- jz .exit
-
- mov esi, eax
-
- stdcall SetDrawMode, esi, cmXor
- stdcall DrawFillRect, esi ; arguments from the stack
- stdcall ReleaseContext, esi
-
-.exit:
- pop esi ecx
- return
-endp
-
-
-
-
-endmodule
-
-
DELETED freshlib/imports/Linux/_libX11.inc
Index: freshlib/imports/Linux/_libX11.inc
==================================================================
--- freshlib/imports/Linux/_libX11.inc
+++ /dev/null
@@ -1,791 +0,0 @@
-; _______________________________________________________________________________________
-;| |
-;| ..::FreshLib::.. Free, open source. Licensed under "Fresh artistic license." |
-;|_______________________________________________________________________________________|
-;
-; Description: libX11 (XLib) import library.
-;
-; Target OS: Linux
-;
-; Dependencies:
-;
-; Notes: Needs editing of the function arguments
-;_________________________________________________________________________________________
-
-
-import_proto 'libX11.so.6', \
- XActivateScreenSaver ,