;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; ;; Copyright (C) KolibriOS team 2004-2024. All rights reserved. ;; ;; Copyright (C) MenuetOS 2000-2004 Ville Mikael Turjanmaa ;; ;; Distributed under terms of the GNU General Public License ;; ;; ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 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] mov eax, [eax + APPDATA.window] rol ebx, 16 add bx, word[eax + WDATA.clientbox.left] rol ebx, 16 rol ecx, 16 add cx, word[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] mov eax, [eax + APPDATA.window] add ebx, [eax + WDATA.box.left] add ecx, [eax + 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