forked from KolibriOS/kolibrios
9a2d26f2a7
git-svn-id: svn://kolibrios.org@9926 a494cfbc-eb01-0410-851d-a64ba20cac60
384 lines
11 KiB
PHP
384 lines
11 KiB
PHP
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
;; ;;
|
|
;; Copyright (C) KolibriOS team 2004-2016. All rights reserved. ;;
|
|
;; Copyright (C) MenuetOS 2000-2004 Ville Mikael Turjanmaa ;;
|
|
;; Distributed under terms of the GNU General Public License ;;
|
|
;; ;;
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
|
|
$Revision$
|
|
|
|
button.MAX_BUTTONS = 4095
|
|
|
|
struct SYS_BUTTON
|
|
pslot dw ?
|
|
id_lo dw ?
|
|
left dw ?
|
|
width dw ?
|
|
top dw ?
|
|
height dw ?
|
|
id_hi dw ?
|
|
dw ?
|
|
ends
|
|
;---------------------------------------------------------------
|
|
align 4
|
|
; @brief system function 17 - Get the identifier of the pressed button
|
|
; @param eax 17 - number function
|
|
; @return eax = 1 - buffer empty,
|
|
; eax = high 24 bits contain button identifier,
|
|
; al = 0 - the button was pressed with left mouse button,
|
|
; al = bit corresponding to used mouse button otherwise
|
|
sys_getbutton:
|
|
mov ebx, [current_slot_idx] ; TOP OF WINDOW STACK
|
|
mov [esp + SYSCALL_STACK.eax], dword 1
|
|
movzx ecx, word [WIN_STACK + ebx * 2]
|
|
mov edx, [thread_count] ; less than 256 processes
|
|
cmp ecx, edx
|
|
jne .exit
|
|
movzx eax, byte [BTN_COUNT]
|
|
test eax, eax
|
|
jz .exit
|
|
mov eax, [BTN_BUFF]
|
|
and al, 0xFE ; delete left button bit
|
|
mov [BTN_COUNT], byte 0
|
|
mov [esp + SYSCALL_STACK.eax], eax
|
|
;--------------------------------------
|
|
align 4
|
|
.exit:
|
|
ret
|
|
;---------------------------------------------------------------
|
|
; @brief system function 8 - define/delete the button
|
|
; @param eax = 8 - number function
|
|
; @param ebx = [offset_x]*65536 + [width]
|
|
; @param ecx = [offset_y]*65536 + [height]
|
|
; @param edx = 0xXYnnnnnn, where:
|
|
; nnnnnn = identifier of the button
|
|
; 31 bit - delete button
|
|
; 30 bit - don't draw button
|
|
; 29 bit - don't draw button frame when pressed
|
|
; @param esi = 0x00RRGGBB - button color
|
|
; @return function does not return value
|
|
syscall_button:
|
|
;---------------------------------------------------------------
|
|
;? Define/undefine GUI button object
|
|
;---------------------------------------------------------------
|
|
;; Define button:
|
|
;> ebx = pack[16(x), 16(width)]
|
|
;> ecx = pack[16(y), 16(height)]
|
|
;> edx = pack[8(flags), 24(button identifier)]
|
|
;> flags bits:
|
|
;> 7 (31) = 0
|
|
;> 6 (30) = don't draw button
|
|
;> 5 (29) = don't draw button frame when pressed
|
|
;> esi = button color
|
|
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
;; Undefine button:
|
|
;> edx = pack[8(flags), 24(button identifier)]
|
|
;> flags bits:
|
|
;> 7 (31) = 1
|
|
;---------------------------------------------------------------
|
|
; do we actually need to undefine the button?
|
|
test edx, 0x80000000
|
|
jnz .remove_button
|
|
|
|
; do we have free button slots available?
|
|
mov edi, [BTN_ADDR]
|
|
mov eax, [edi]
|
|
cmp eax, button.MAX_BUTTONS
|
|
jge .exit
|
|
|
|
; does it have positive size? (otherwise it doesn't have sense)
|
|
or bx, bx
|
|
jle .exit
|
|
or cx, cx
|
|
jle .exit
|
|
|
|
; make coordinates clientbox-relative
|
|
push eax
|
|
mov eax, [current_slot_idx]
|
|
shl eax, BSF sizeof.WDATA
|
|
rol ebx, 16
|
|
add bx, word[window_data + eax + WDATA.clientbox.left]
|
|
rol ebx, 16
|
|
rol ecx, 16
|
|
add cx, word[window_data + eax + WDATA.clientbox.top]
|
|
rol ecx, 16
|
|
pop eax
|
|
|
|
; basic checks passed, define the button
|
|
inc eax
|
|
mov [edi], ax
|
|
shl eax, 4
|
|
add edi, eax
|
|
; NOTE: this code doesn't rely on SYS_BUTTON struct,
|
|
; please revise it, if you change something.
|
|
mov ax, word [current_slot_idx]
|
|
stosw
|
|
mov ax, dx
|
|
stosw ; button id number: bits 0-15
|
|
mov eax, ebx
|
|
rol eax, 16
|
|
stosd ; x start | x size
|
|
mov eax, ecx
|
|
rol eax, 16
|
|
stosd ; y start | y size
|
|
mov eax, edx
|
|
shr eax, 16
|
|
stosw ; button id number: bits 16-31
|
|
|
|
; do we also need to draw the button?
|
|
test edx, 0x40000000
|
|
jnz .exit
|
|
|
|
and esi, 0xFFFFFF
|
|
xor edi, edi
|
|
push ebx ecx esi
|
|
dec cx
|
|
dec cx
|
|
cmp [buttontype], 1
|
|
jnz .draw
|
|
cmp cx, 65
|
|
jnc .draw
|
|
|
|
; calculate gradient data
|
|
mov eax, esi
|
|
shl eax, 8
|
|
mov edx, 3
|
|
.calculate:
|
|
rol eax, 8
|
|
shl al, 1
|
|
jnc @f
|
|
neg al
|
|
jnz @f
|
|
mov al, 64
|
|
@@:
|
|
cmp al, 65
|
|
jc @f
|
|
mov al, 64
|
|
@@:
|
|
div cl
|
|
shl ax, 8
|
|
dec edx
|
|
jnz .calculate
|
|
mov dl, cl
|
|
dec edx
|
|
shr edx, 1
|
|
shr eax, 8
|
|
mov edi, eax
|
|
mul edx
|
|
add esi, eax
|
|
|
|
.draw: ; calculate window-relative coordinates
|
|
movzx ebp, cx
|
|
dec ebp
|
|
shr ebx, 16
|
|
shr ecx, 16
|
|
mov eax, [current_slot_idx]
|
|
shl eax, BSF sizeof.WDATA
|
|
add ebx, [eax + window_data + WDATA.box.left]
|
|
add ecx, [eax + window_data + WDATA.box.top]
|
|
mov eax, ebx
|
|
inc eax
|
|
mov edx, ebx
|
|
add dx, [esp+8]
|
|
dec edx
|
|
mov ebx, ecx
|
|
mov ecx, esi
|
|
shr ecx, 1
|
|
and cx, 7F7Fh
|
|
push esi
|
|
mov esi, edi
|
|
xor edi, edi
|
|
call hline ; top border
|
|
inc ebx
|
|
or ecx, 808080h
|
|
call hline ; top light line
|
|
pop ecx
|
|
inc ebx
|
|
.next_line:
|
|
call hline ; button body
|
|
inc ebx
|
|
sub ecx, esi
|
|
dec ebp
|
|
jnz .next_line
|
|
shr ecx, 2
|
|
and cx, 3F3Fh
|
|
mov ebp, ecx
|
|
shl ecx, 1
|
|
add ecx, ebp
|
|
call hline ; bottom dark line
|
|
inc ebx
|
|
sub ecx, ebp
|
|
call hline ; bottom border
|
|
pop ecx
|
|
shr ecx, 1
|
|
inc edx
|
|
push edx
|
|
mov edx, ebx
|
|
sub bx, [esp+4]
|
|
dec edx
|
|
inc ebx
|
|
cmp [buttontype], 0
|
|
jnz @f
|
|
dec edx
|
|
or ecx, 808080h
|
|
call vline ; left light line
|
|
inc edx
|
|
@@:
|
|
and ecx, 7F7F7Fh
|
|
dec eax
|
|
call vline ; left border
|
|
pop eax
|
|
call vline ; right border
|
|
cmp [buttontype], 0
|
|
jnz @f
|
|
mov ebp, ecx
|
|
shr ecx, 1
|
|
and cx, 7F7Fh
|
|
add ecx, ebp
|
|
dec eax
|
|
inc ebx
|
|
dec edx ; avoid lines overflow
|
|
call vline ; right dark line
|
|
@@:
|
|
pop ecx ebx
|
|
.exit:
|
|
ret
|
|
|
|
; FIXME: mutex needed
|
|
.remove_button:
|
|
and edx, 0x00ffffff
|
|
mov edi, [BTN_ADDR]
|
|
mov ebx, [edi]
|
|
inc ebx
|
|
imul esi, ebx, sizeof.SYS_BUTTON
|
|
add esi, edi
|
|
xor ecx, ecx
|
|
add ecx, -sizeof.SYS_BUTTON
|
|
add esi, sizeof.SYS_BUTTON
|
|
|
|
.next_button:
|
|
dec ebx
|
|
jz .exit
|
|
|
|
add ecx, sizeof.SYS_BUTTON
|
|
add esi, -sizeof.SYS_BUTTON
|
|
|
|
; does it belong to our process?
|
|
mov ax, word [current_slot_idx]
|
|
cmp ax, [esi + SYS_BUTTON.pslot]
|
|
jne .next_button
|
|
|
|
; does the identifier match?
|
|
mov eax, dword[esi + SYS_BUTTON.id_hi - 2]
|
|
mov ax, [esi + SYS_BUTTON.id_lo]
|
|
and eax, 0x00ffffff
|
|
cmp edx, eax
|
|
jne .next_button
|
|
|
|
; okay, undefine it
|
|
push ebx
|
|
mov ebx, esi
|
|
lea eax, [esi + sizeof.SYS_BUTTON]
|
|
call memmove
|
|
dec dword[edi]
|
|
add ecx, -sizeof.SYS_BUTTON
|
|
pop ebx
|
|
jmp .next_button
|
|
|
|
;---------------------------------------------------------------
|
|
sys_button_activate_handler:
|
|
sys_button_deactivate_handler:
|
|
;---------------------------------------------------------------
|
|
;> eax = pack[8(process slot), 24(button id)]
|
|
;> ebx = pack[16(button x coord), 16(button y coord)]
|
|
;> cl = mouse button mask this system button was pressed with
|
|
;---------------------------------------------------------------
|
|
; find system button by specified process slot, id and coordinates
|
|
push ecx edx esi edi
|
|
mov edx, eax
|
|
shr edx, 24
|
|
and eax, 0x0ffffff
|
|
mov edi, [BTN_ADDR]
|
|
mov ecx, [edi]
|
|
imul esi, ecx, sizeof.SYS_BUTTON
|
|
add esi, edi
|
|
inc ecx
|
|
add esi, sizeof.SYS_BUTTON
|
|
.next_button:
|
|
dec ecx
|
|
jz .popexit
|
|
add esi, -sizeof.SYS_BUTTON
|
|
|
|
; does it belong to our process?
|
|
cmp dx, [esi + SYS_BUTTON.pslot]
|
|
jne .next_button
|
|
|
|
; does id match?
|
|
mov edi, dword[esi + SYS_BUTTON.id_hi - 2]
|
|
mov di, [esi + SYS_BUTTON.id_lo]
|
|
and edi, 0x0ffffff
|
|
cmp eax, edi
|
|
jne .next_button
|
|
|
|
; does coordinates match?
|
|
mov edi, dword[esi + SYS_BUTTON.left - 2]
|
|
mov di, [esi + SYS_BUTTON.top]
|
|
cmp ebx, edi
|
|
jne .next_button
|
|
|
|
mov eax, esi
|
|
pop edi esi edx ecx
|
|
mov ebx, dword[eax + SYS_BUTTON.id_hi - 2]
|
|
|
|
; display button border on press?
|
|
bt ebx, 29
|
|
jc .exit
|
|
|
|
; invert system button border
|
|
pushad
|
|
mov esi, eax
|
|
mov edi, ebx
|
|
movzx ecx, [esi + SYS_BUTTON.pslot]
|
|
shl ecx, BSF sizeof.WDATA
|
|
mov eax, dword[esi + SYS_BUTTON.left]
|
|
mov ebx, dword[esi + SYS_BUTTON.top]
|
|
add eax, [window_data + ecx + WDATA.box.left]
|
|
add ebx, [window_data + ecx + WDATA.box.top]
|
|
mov ecx, eax
|
|
mov edx, ebx
|
|
bt edi, 30
|
|
jc @f
|
|
inc ax
|
|
inc bx
|
|
dec cx
|
|
dec dx
|
|
@@:
|
|
rol eax, 16
|
|
rol ebx, 16
|
|
add ax, cx
|
|
add bx, dx
|
|
mov esi, 1000000h
|
|
call draw_rectangle.forced
|
|
popad
|
|
.exit:
|
|
ret
|
|
.popexit:
|
|
pop edi esi edx ecx
|
|
ret
|
|
|
|
;---------------------------------------------------------------
|
|
sys_button_perform_handler:
|
|
;---------------------------------------------------------------
|
|
;> eax = pack[8(process slot), 24(button id)]
|
|
;> ebx = pack[16(button x coord), 16(button y coord)]
|
|
;> cl = mouse button mask this system button was pressed with
|
|
;---------------------------------------------------------------
|
|
shl eax, 8
|
|
mov al, cl
|
|
movzx ebx, byte[BTN_COUNT]
|
|
mov [BTN_BUFF + ebx * 4], eax
|
|
inc bl
|
|
mov [BTN_COUNT], bl
|
|
ret
|