;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; ;; Copyright (C) KolibriOS team 2004-2008. All rights reserved. ;; ;; Distributed under terms of the GNU General Public License ;; ;; ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; $Revision$ LOAD_FROM_FILE equ 0 LOAD_FROM_MEM equ 1 LOAD_INDIRECT equ 2 LOAD_SYSTEM equ 3 struc BITMAPINFOHEADER { .biSize dd ? ; DWORD .biWidth dd ? ; LONG .biHeight dd ? ; LONG .biPlanes dw ? ; WORD .biBitCount dw ? ; WORD .biCompression dd ? ; DWORD .biSizeImage dd ? ; DWORD .biXPelsPerMeter dd ? ; LONG .biYPelsPerMeter dd ? ; LONG .biClrUsed dd ? ; DWORD .biClrImportant dd ? ; DWORD } virtual at 0 BI BITMAPINFOHEADER end virtual align 4 proc vesa_init_cursor stdcall, dst:dword, src:dword locals rBase dd ? pQuad dd ? pBits dd ? pAnd dd ? width dd ? height dd ? counter dd ? endl mov esi, [src] add esi,[esi+18] mov eax,esi cmp [esi+BI.biBitCount], 24 je .img_24 cmp [esi+BI.biBitCount], 8 je .img_8 cmp [esi+BI.biBitCount], 4 je .img_4 .img_2: add eax, [esi] mov [pQuad],eax add eax,8 mov [pBits],eax add eax, 128 mov [pAnd],eax mov eax,[esi+4] mov [width],eax mov ebx,[esi+8] shr ebx,1 mov [height],ebx mov edi, [dst] add edi, 32*31*4 mov [rBase],edi mov esi,[pQuad] .l21: mov ebx, [pBits] mov ebx, [ebx] bswap ebx mov eax, [pAnd] mov eax, [eax] bswap eax mov [counter], 32 @@: xor edx, edx shl eax,1 setc dl dec edx xor ecx, ecx shl ebx,1 setc cl mov ecx, [esi+ecx*4] and ecx, edx and edx, 0xFF000000 or edx, ecx mov [edi], edx add edi, 4 dec [counter] jnz @B add [pBits], 4 add [pAnd], 4 mov edi,[rBase] sub edi,128 mov [rBase],edi sub [height],1 jnz .l21 ret .img_4: add eax, [esi] mov [pQuad],eax add eax,64 mov [pBits],eax add eax, 0x200 mov [pAnd],eax mov eax,[esi+4] mov [width],eax mov ebx,[esi+8] shr ebx,1 mov [height],ebx mov edi, [dst] add edi, 32*31*4 mov [rBase],edi mov esi,[pQuad] mov ebx, [pBits] .l4: mov eax, [pAnd] mov eax, [eax] bswap eax mov [counter], 16 @@: xor edx, edx shl eax,1 setc dl dec edx movzx ecx, byte [ebx] and cl, 0xF0 shr ecx, 2 mov ecx, [esi+ecx] and ecx, edx and edx, 0xFF000000 or edx, ecx mov [edi], edx xor edx, edx shl eax,1 setc dl dec edx movzx ecx, byte [ebx] and cl, 0x0F mov ecx, [esi+ecx*4] and ecx, edx and edx, 0xFF000000 or edx, ecx mov [edi+4], edx inc ebx add edi, 8 dec [counter] jnz @B add [pAnd], 4 mov edi,[rBase] sub edi,128 mov [rBase],edi sub [height],1 jnz .l4 ret .img_8: add eax, [esi] mov [pQuad],eax add eax,1024 mov [pBits],eax add eax, 1024 mov [pAnd],eax mov eax,[esi+4] mov [width],eax mov ebx,[esi+8] shr ebx,1 mov [height],ebx mov edi, [dst] add edi, 32*31*4 mov [rBase],edi mov esi,[pQuad] mov ebx, [pBits] .l81: mov eax, [pAnd] mov eax, [eax] bswap eax mov [counter], 32 @@: xor edx, edx shl eax,1 setc dl dec edx movzx ecx, byte [ebx] mov ecx, [esi+ecx*4] and ecx, edx and edx, 0xFF000000 or edx, ecx mov [edi], edx inc ebx add edi, 4 dec [counter] jnz @B add [pAnd], 4 mov edi,[rBase] sub edi,128 mov [rBase],edi sub [height],1 jnz .l81 ret .img_24: add eax, [esi] mov [pQuad],eax add eax, 0xC00 mov [pAnd],eax mov eax,[esi+BI.biWidth] mov [width],eax mov ebx,[esi+BI.biHeight] shr ebx,1 mov [height],ebx mov edi, [dst] add edi, 32*31*4 mov [rBase],edi mov esi,[pAnd] mov ebx, [pQuad] .row_24: mov eax, [esi] bswap eax mov [counter], 32 @@: xor edx, edx shl eax,1 setc dl dec edx mov ecx, [ebx] and ecx, 0x00FFFFFF and ecx, edx and edx, 0xFF000000 or edx, ecx mov [edi], edx add ebx, 3 add edi, 4 dec [counter] jnz @B add esi, 4 mov edi,[rBase] sub edi,128 mov [rBase],edi sub [height],1 jnz .row_24 ret endp align 4 proc set_cursor stdcall, hcursor:dword mov eax, [hcursor] cmp [eax+CURSOR.magic], 'CURS' jne .fail ; cmp [eax+CURSOR.size], CURSOR_SIZE ; jne .fail mov ebx, [current_slot] xchg eax, [ebx+APPDATA.cursor] ret .fail: mov eax, [def_cursor] mov ebx, [current_slot] xchg eax, [ebx+APPDATA.cursor] ret endp ; param ; eax= pid ; ebx= src ; ecx= flags vesa_cursor: .src equ esp .flags equ esp+4 .hcursor equ esp+8 sub esp, 4 ;space for .hcursor push ecx push ebx mov ebx, eax mov eax, CURSOR_SIZE call create_kernel_object test eax, eax jz .fail mov [.hcursor],eax xor ebx, ebx mov [eax+CURSOR.magic], 'CURS' mov [eax+CURSOR.destroy], destroy_cursor mov [eax+CURSOR.hot_x], ebx mov [eax+CURSOR.hot_y], ebx mov edi, eax mov ecx, 0x1000 mov edx, PG_SW call @mem_alloc@8 test eax, eax mov [edi+CURSOR.base], eax jz .fail mov esi, [.src] mov ebx, [.flags] cmp bx, LOAD_INDIRECT je .indirect movzx ecx, word [esi+10] movzx edx, word [esi+12] mov [edi+CURSOR.hot_x], ecx mov [edi+CURSOR.hot_y], edx stdcall vesa_init_cursor, eax, esi mov eax, [.hcursor] .fail: add esp, 12 ret .indirect: shr ebx, 16 movzx ecx, bh movzx edx, bl mov [eax+CURSOR.hot_x], ecx mov [eax+CURSOR.hot_y], edx xchg edi, eax mov ecx, 1024 cld rep movsd add esp, 12 ret align 4 proc load_cursor stdcall, src:dword, flags:dword locals handle dd ? endl xor eax, eax cmp [create_cursor], eax je .fail2 mov [handle], eax cmp word [flags], LOAD_FROM_FILE jne @F stdcall load_file, [src] test eax, eax mov [src], eax jz .fail @@: push ebx push esi push edi mov eax, [CURRENT_TASK] shl eax, 5 mov eax, [CURRENT_TASK+eax+4] mov ebx, [src] mov ecx, [flags] call [create_cursor] ;eax, ebx, ecx mov [handle], eax cmp word [flags], LOAD_FROM_FILE jne .exit mov ecx, [src] call @mem_free@4 .exit: pop edi pop esi pop ebx .fail: mov eax, [handle] .fail2: ret endp align 4 proc delete_cursor stdcall, hcursor:dword locals hsrv dd ? io_code dd ? input dd ? inp_size dd ? output dd ? out_size dd ? endl mov esi, [hcursor] cmp [esi+CURSOR.magic], 'CURS' jne .fail ; cmp [esi+CURSOR.size], CURSOR_SIZE ; jne .fail mov ebx, [CURRENT_TASK] shl ebx, 5 mov ebx, [CURRENT_TASK+ebx+4] cmp ebx, [esi+CURSOR.pid] jne .fail mov ebx, [current_slot] cmp esi, [ebx+APPDATA.cursor] jne @F mov eax, [def_cursor] mov [ebx+APPDATA.cursor], eax @@: mov eax, [hcursor] call [eax+APPOBJ.destroy] .fail: ret endp ; param ; eax= cursor align 4 destroy_cursor: push eax mov ecx, [eax+CURSOR.base] call @mem_free@4 pop eax call destroy_kernel_object ret align 4 select_cursor: ret 4 align 4 proc init_cursors cmp [scr_mode], 0x13 jbe .fail test [scr_mode], 0x4000 jz .fail mov eax, [ScreenBPP] mov ebx, [BytesPerScanLine] cmp eax, 32 jne @F sub ebx, 128 jmp .init @@: cmp eax, 24 jne .fail sub ebx, 96 .init: ; stdcall load_driver, szHwMouse ; mov [hw_cursor], eax ; test eax, eax ; jz .sw_mouse ; stdcall load_cursor, def_arrow, dword LOAD_FROM_MEM ; mov [def_cursor], eax ; ret .sw_mouse: mov [create_cursor], vesa_cursor stdcall load_cursor, def_arrow, dword LOAD_FROM_MEM mov [def_cursor], eax mov ebx, [ScreenBPP] cmp ebx, 32 jne @F mov dword [select_hw_cursor], select_cursor mov dword [set_hw_cursor], cursor_32 mov dword [hw_restore], restore_32 ret @@: mov dword [select_hw_cursor], select_cursor mov dword [set_hw_cursor], cursor_24 mov dword [hw_restore], restore_24 ret .fail: xor eax, eax mov dword [select_hw_cursor], eax mov dword [set_hw_cursor], eax mov dword [hw_restore], eax ret endp align 4 proc restore_24 stdcall, x:dword, y:dword mov ebx, [cur_saved_base] mov edx, [cur.h] test edx, edx jz .ret mov esi, cur_saved_data @@: mov edi, ebx add ebx, [BytesPerScanLine] mov ecx, [cur.w] lea ecx, [ecx+ecx*2] rep movsb dec edx jnz @B .ret: ret endp align 4 proc restore_32 stdcall, x:dword, y:dword mov ebx, [cur_saved_base] mov edx, [cur.h] test edx, edx jz .ret mov esi, cur_saved_data @@: mov edi, ebx add ebx, [BytesPerScanLine] mov ecx, [cur.w] rep movsd dec edx jnz @B .ret: ret endp align 4 proc cursor_24 stdcall, hcursor:dword, x:dword, y:dword locals h dd ? _dx dd ? _dy dd ? endl mov esi, [hcursor] mov ecx, [x] mov eax, [y] mov ebx, [BytesPerScanLine] xor edx, edx sub ecx, [esi+CURSOR.hot_x] lea ebx, [ecx+32-1] mov [x], ecx sets dl dec edx and ecx, edx ;clip x to 0<=x mov [cur.left], ecx mov edi, ecx sub edi, [x] mov [_dx], edi xor edx, edx sub eax, [esi+CURSOR.hot_y] lea edi, [eax+32-1] mov [y], eax sets dl dec edx and eax, edx ;clip y to 0<=y mov [cur.top], eax mov edx, eax sub edx, [y] mov [_dy], edx mul [BytesPerScanLine] lea edx, [LFB_BASE+ecx*3] add edx, eax mov [cur_saved_base],edx cmp ebx, [Screen_Max_X] jbe @F mov ebx, [Screen_Max_X] @@: cmp edi, [Screen_Max_Y] jbe @F mov edi, [Screen_Max_Y] @@: mov [cur.right], ebx mov [cur.bottom], edi sub ebx, [x] sub edi, [y] inc ebx inc edi mov [cur.w], ebx mov [cur.h], edi mov [h], edi mov eax, edi mov edi, cur_saved_data @@: mov esi, edx add edx, [BytesPerScanLine] mov ecx, [cur.w] lea ecx, [ecx+ecx*2] rep movsb dec eax jnz @B ;draw cursor mov ebx, [cur_saved_base] mov eax, [_dy] shl eax, 5 add eax, [_dx] mov esi, [hcursor] mov esi, [esi+CURSOR.base] lea edx, [esi+eax*4] .row: mov ecx, [cur.w] mov esi, edx mov edi, ebx add edx, 32*4 add ebx, [BytesPerScanLine] .pix: lodsd test eax, 0xFF000000 jz @F mov [edi], ax shr eax, 16 mov [edi+2], al @@: add edi, 3 dec ecx jnz .pix dec [h] jnz .row ret endp align 4 proc cursor_32 stdcall, hcursor:dword, x:dword, y:dword locals h dd ? _dx dd ? _dy dd ? endl mov esi, [hcursor] mov ecx, [x] mov eax, [y] xor edx, edx sub ecx, [esi+CURSOR.hot_x] lea ebx, [ecx+32-1] mov [x], ecx sets dl dec edx and ecx, edx ;clip x to 0<=x mov [cur.left], ecx mov edi, ecx sub edi, [x] mov [_dx], edi xor edx, edx sub eax, [esi+CURSOR.hot_y] lea edi, [eax+32-1] mov [y], eax sets dl dec edx and eax, edx ;clip y to 0<=y mov [cur.top], eax mov edx, eax sub edx, [y] mov [_dy], edx mul [BytesPerScanLine] lea edx, [LFB_BASE+eax+ecx*4] mov [cur_saved_base],edx cmp ebx, [Screen_Max_X] jbe @F mov ebx, [Screen_Max_X] @@: cmp edi, [Screen_Max_Y] jbe @F mov edi, [Screen_Max_Y] @@: mov [cur.right], ebx mov [cur.bottom], edi sub ebx, [x] sub edi, [y] inc ebx inc edi mov [cur.w], ebx mov [cur.h], edi mov [h], edi mov eax, edi mov edi, cur_saved_data @@: mov esi, edx add edx, [BytesPerScanLine] mov ecx, [cur.w] rep movsd dec eax jnz @B ;draw cursor mov ebx, [cur_saved_base] mov eax, [_dy] shl eax, 5 add eax, [_dx] mov esi, [hcursor] mov esi, [esi+CURSOR.base] lea edx, [esi+eax*4] .row: mov ecx, [cur.w] mov esi, edx mov edi, ebx add edx, 32*4 add ebx, [BytesPerScanLine] .pix: lodsd test eax, 0xFF000000 jz @F mov [edi], eax @@: add edi, 4 dec ecx jnz .pix dec [h] jnz .row ret endp align 4 def_arrow: file 'arrow.cur'