diff --git a/kernel/trunk/const.inc b/kernel/trunk/const.inc index 96afd915c0..f9a50a5507 100644 --- a/kernel/trunk/const.inc +++ b/kernel/trunk/const.inc @@ -175,7 +175,7 @@ BTN_DOWN equ OS_BASE+0x000FB40 MOUSE_DOWN equ OS_BASE+0x000FB44 X_UNDER equ OS_BASE+0x000FB4A Y_UNDER equ OS_BASE+0x000FB4C -;ScreenBPP equ OS_BASE+0x000FBF1 +ScreenBPP equ OS_BASE+0x000FBF1 MOUSE_BUFF_COUNT equ OS_BASE+0x000FCFF HD_CACHE_ENT equ OS_BASE+0x000FE10 LFBAddress equ OS_BASE+0x000FE80 @@ -312,6 +312,20 @@ struc SYS_VARS dd ? } +struc CURSOR +{ .magic dd ? + .size dd ? + .pid dd ? + .base dd ? + .hot_x dd ? + .hot_y dd ? +} +virtual at 0 + CURSOR CURSOR +end virtual + +CURSOR_SIZE equ 24 + struc BOOT_DATA { .bpp dd ? .scanline dd ? @@ -436,7 +450,7 @@ virtual at 0 end virtual -SRV_SIZE equ 32 +SRV_SIZE equ 36 virtual at 0 LIB LIB diff --git a/kernel/trunk/core/dll.inc b/kernel/trunk/core/dll.inc index dc4cd6c2ee..9b4b96213e 100644 --- a/kernel/trunk/core/dll.inc +++ b/kernel/trunk/core/dll.inc @@ -946,11 +946,13 @@ endp drv_sound db '/rd/1/drivers/unisound.obj', 0 drv_infinity db '/rd/1/drivers/infinity.obj', 0 -drv_ati2d db '/rd/1/drivers/ati2d.obj', 0 +;drv_ati2d db '/rd/1/drivers/vesa.obj', 0 +;drv_cursor db '/rd/1/drivers/vesa.obj',0 szSound db 'SOUND',0 szInfinity db 'INFINITY',0 -szHMouse db 'ATI2D',0 +;szHMouse db 'ATI2D',0 +;szCURSOR db 'VESACURSOR',0 szSTART db 'START',0 szEXPORTS db 'EXPORTS',0 @@ -962,10 +964,12 @@ msg_CR db 13,10,0 align 4 set_hw_cursor dd 0 +hw_restore dd 0 align 16 services: dd szSound, drv_sound dd szInfinity, drv_infinity - dd szHMouse, drv_ati2d +; dd szHMouse, drv_ati2d +; dd szCURSOR, drv_cursor dd 0 diff --git a/kernel/trunk/core/exports.inc b/kernel/trunk/core/exports.inc index 614059f84f..febecf36c4 100644 --- a/kernel/trunk/core/exports.inc +++ b/kernel/trunk/core/exports.inc @@ -1,5 +1,28 @@ iglobal + szKernel db 'KERNEL', 0 + szAttachIntHandler db 'AttachIntHandler',0 + szSysMsgBoardStr db 'SysMsgBoardStr', 0 + szPciApi db 'PciApi', 0 + szPciRead32 db 'PciRead32', 0 + szPciRead8 db 'PciRead8', 0 + szPciWrite8 db 'PciWrite8',0 + szAllocKernelSpace db 'AllocKernelSpace',0 + szMapPage db 'MapPage',0 + szRegService db 'RegService',0 + szKernelAlloc db 'KernelAlloc',0 + szKernelFree db 'KernelFree',0 + szGetPgAddr db 'GetPgAddr',0 + szGetCurrentTask db 'GetCurrentTask',0 + szGetService db 'GetService',0 + szServiceHandler db 'ServiceHandler',0 + szFpuSave db 'FpuSave',0 + szFpuRestore db 'FpuRestore',0 + szLoadCursor db 'LoadCursor',0 + szSetHwCursor db 'SetHwCursor',0 + szHWRestore db 'HWRestore', 0 + szLFBAddress db 'LFBAddress',0 + szLoadFile db 'LoadFile',0 align 16 kernel_export: @@ -20,33 +43,14 @@ kernel_export: dd szServiceHandler , srv_handler dd szFpuSave , fpu_save dd szFpuRestore , fpu_restore + dd szLoadCursor , load_cursor dd szSetHwCursor , set_hw_cursor + dd szHWRestore , hw_restore dd szLoadFile , load_file exp_lfb: dd szLFBAddress , 0 dd 0 - szKernel db 'KERNEL', 0 - szAttachIntHandler db 'AttachIntHandler',0 - szSysMsgBoardStr db 'SysMsgBoardStr', 0 - szPciApi db 'PciApi', 0 - szPciRead32 db 'PciRead32', 0 - szPciRead8 db 'PciRead8', 0 - szPciWrite8 db 'PciWrite8',0 - szAllocKernelSpace db 'AllocKernelSpace',0 - szMapPage db 'MapPage',0 - szRegService db 'RegService',0 - szKernelAlloc db 'KernelAlloc',0 - szKernelFree db 'KernelFree',0 - szGetPgAddr db 'GetPgAddr',0 - szGetCurrentTask db 'GetCurrentTask',0 - szGetService db 'GetService',0 - szServiceHandler db 'ServiceHandler',0 - szFpuSave db 'FpuSave',0 - szFpuRestore db 'FpuRestore',0 - szSetHwCursor db 'SetHwCursor',0 - szLFBAddress db 'LFBAddress',0 - szLoadFile db 'LoadFile',0 endg diff --git a/kernel/trunk/core/fpu.inc b/kernel/trunk/core/fpu.inc index 1dc447c7a0..13b028cac1 100644 --- a/kernel/trunk/core/fpu.inc +++ b/kernel/trunk/core/fpu.inc @@ -3,8 +3,8 @@ init_fpu: clts fninit - bt [cpu_caps], CAPS_FXSR - jnc .no_FXSR + bt [cpu_caps], CAPS_SSE + jnc .no_SSE stdcall kernel_alloc, 512*256 mov [fpu_data], eax @@ -31,7 +31,7 @@ init_fpu: xorps xmm7, xmm7 fxsave [eax] ret -.no_FXSR: +.no_SSE: stdcall kernel_alloc, 112*256 mov [fpu_data], eax mov ecx, cr0 @@ -50,7 +50,7 @@ proc fpu_save mov ebx, [CURRENT_TASK] mov [fpu_owner], ebx - bt [cpu_caps], CAPS_FXSR + bt [cpu_caps], CAPS_SSE jnc .no_SSE fxsave [eax] @@ -66,7 +66,7 @@ proc fpu_restore mov ebx, [CURRENT_TASK] shl ebx, 8 mov eax, [ebx+PROC_BASE+0x10] - bt [cpu_caps], CAPS_FXSR + bt [cpu_caps], CAPS_SSE jnc .no_SSE fxrstor [eax] @@ -91,7 +91,7 @@ e7: ;#NM exception handler shl ebx, 8 mov eax, [ebx+PROC_BASE+APPDATA.fpu_state] - bt [cpu_caps], CAPS_FXSR + bt [cpu_caps], CAPS_SSE jnc .no_SSE fxsave [eax] diff --git a/kernel/trunk/core/memory.inc b/kernel/trunk/core/memory.inc index 68aa674b46..4263ab1470 100644 --- a/kernel/trunk/core/memory.inc +++ b/kernel/trunk/core/memory.inc @@ -1053,7 +1053,7 @@ proc test_cpu pop eax xor eax, ecx mov [cpu_type], CPU_386 - jz .end_cpu + jz .end_cpuid push ecx popfd @@ -1065,7 +1065,7 @@ proc test_cpu pushfd pop eax xor eax, ecx - je .end_cpu + je .end_cpuid mov [cpu_id], 1 xor eax, eax @@ -1091,23 +1091,31 @@ proc test_cpu shr eax, 8 and eax, 0x0f - mov [cpu_type], eax ret - .end_cpuid: mov eax, [cpu_type] ret .check_AMD: cmp ebx, dword [AMD_str] - jne .end_cpu + jne .unknown cmp edx, dword [AMD_str+4] - jne .end_cpu + jne .unknown cmp ecx, dword [AMD_str+8] - jne .end_cpu + jne .unknown mov [cpu_AMD], 1 cmp eax, 1 - jl .end_cpuid + jl .unknown + mov eax, 1 + cpuid + mov [cpu_sign], eax + mov [cpu_info], ebx + mov [cpu_caps], edx + mov [cpu_caps+4],ecx + shr eax, 8 + and eax, 0x0f + ret +.unknown: mov eax, 1 cpuid mov [cpu_sign], eax @@ -1116,9 +1124,6 @@ proc test_cpu mov [cpu_caps+4],ecx shr eax, 8 and eax, 0x0f - mov [cpu_type], eax -.end_cpu: - mov eax, [cpu_type] ret endp @@ -1263,6 +1268,27 @@ align 16 cpu_sign rd 1 cpu_info rd 1 +;;;;; cursors data + +align 16 +cur_saved_data rb 4096 + +cursors rb CURSOR_SIZE*64 +cursor_map rd 2 +cursor_start rd 1 +cursor_end rd 1 + +def_cursor rd 1 + +scr_width rd 1 +scr_height rd 1 + +cur_def_interl rd 1 +cur_saved_base rd 1 +cur_saved_interl rd 1 +cur_saved_w rd 1 +cur_saved_h rd 1 + endg uglobal diff --git a/kernel/trunk/core/sys32.inc b/kernel/trunk/core/sys32.inc index 8f4395765d..5d14bfdc08 100644 --- a/kernel/trunk/core/sys32.inc +++ b/kernel/trunk/core/sys32.inc @@ -100,7 +100,7 @@ iglobal dd except_16, e17,e18, except_19 times 12 dd unknown_interrupt - dd irq0 , irq_serv.irq_1, p_irq2 ,irq_serv.irq_3 + dd irq0 , irq_serv.irq_1, p_irq2 , p_irq3 ;irq_serv.irq_3 dd p_irq4 ,irq_serv.irq_5,p_irq6,irq_serv.irq_7 dd irq_serv.irq_8, irq_serv.irq_9, irq_serv.irq_10 dd irq_serv.irq_11,p_irq12,irqD ,p_irq14,p_irq15 @@ -638,7 +638,7 @@ terminate: ; terminate application mov [fpu_owner],1 mov eax, [256+PROC_BASE+0x10] - bt [cpu_caps], CAPS_FXSR + bt [cpu_caps], CAPS_SSE jnc .no_SSE fxrstor [eax] jmp fpu_ok_1 diff --git a/kernel/trunk/core/taskman.inc b/kernel/trunk/core/taskman.inc index abc8d88931..4094cdbfec 100644 --- a/kernel/trunk/core/taskman.inc +++ b/kernel/trunk/core/taskman.inc @@ -606,7 +606,7 @@ proc add_app_parameters stdcall,slot:dword,img_base:dword,\ mov edi, [slot] mov esi, [fpu_data] - bt [cpu_caps], CAPS_FXSR + bt [cpu_caps], CAPS_SSE jnc .no_SSE shl edi, 8 @@ -639,7 +639,10 @@ proc add_app_parameters stdcall,slot:dword,img_base:dword,\ .noinc: shl ebx,8 mov eax,[app_mem] - mov [PROC_BASE+0x8c+ebx],eax + mov [PROC_BASE+APPDATA.mem_size+ebx],eax + + mov ecx, [def_cursor] + mov [PROC_BASE+APPDATA.cursor+ebx],ecx shr ebx,3 mov eax, new_app_base diff --git a/kernel/trunk/docs/sysfuncr.txt b/kernel/trunk/docs/sysfuncr.txt index 88cf905146..744187109b 100644 --- a/kernel/trunk/docs/sysfuncr.txt +++ b/kernel/trunk/docs/sysfuncr.txt @@ -1864,6 +1864,71 @@ db 'Kolibri',0 * бит 1 установлен = правая кнопка нажата * прочие биты сброшены +----------------- Подфункция 3 - установить позицию курсора ------------ +------------------ функция зарезервирована ----------------- +Параметры: + * eax = 37 - номер функции + * ebx = 3 - номер подфункции + * ecx = координаты курсора +Возвращаемое значение: + * eax предыдущие координаты курсора + +----------------- Подфункция 4 - загрузить курсор ----------------- +Параметры: + * eax = 37 - номер функции + * ebx = 4 - номер подфункции + * ecx = указатель на входные двнные + * edx = (hotspot << 16) or flags + +Возвращаемое значение: + * eax содержит логический номер курсора + или 0 в случае неудачи + +Значение ecx интерпретируется в зависимости от флагов установленных +в младшем слове регистра edx + + * dx = LOAD_FROM_FILE = 0 + * ecx = полный путь к файлу курсора + * hotspot игнорируется + * курсор должен быть в формате MS Windows 32*32 пикселя 16 цветов + + * dx = LOAD_FROM_MEM = 1 + * ecx = указатель на загруженный в память файл курсора + * hotspot игнорируется + * курсор должен быть в формате MS Windows 32*32 пикселя 16 цветов + + * dx = LOAD_INDIRECT = 2 + * ecx = указатель на образ курсора в формате ARGB 32*32 пикселя + * hotspot (hotspot.x <<8)or hotspot.y + 0<= x,y <=31 + + * dx = LOAD_SYSTEM = 3; зарезервировано + * ecx = номер системного курсора + * hotspot игнорируется + +----------------- Подфункция 5 - установить курсор ----------------- +Параметры: + * eax = 37 - номер функции + * ebx = 5 - номер подфункции + * ecx = логический номер курсора загруженного фн. 37.4 +Возвращаемое значение: + * eax = логический номер предыдущего курсора + +Функция устанавливает новый курсор для окна вызвавшего её потока, + +----------------- Подфункция 6 - удалить курсор ----------------- +------------------ функция зарезервирована ----------------- +Параметры: + * eax = 37 - номер функции + * ebx = 6 - номер подфункции + * ecx = логический номер курсора загруженного фн. 37.4 +Возвращаемое значение: + * eax = общее количество загруженных курсоров + +Если удаляемый курсор является активным для данного окна,он заменяется +системным. Функция не удаляет курсоры загруженные другим приложением. +Системные курсоры не удаляются. + ====================================================================== ================== Функция 38 - нарисовать отрезок. ================== ====================================================================== diff --git a/kernel/trunk/hid/mousedrv.inc b/kernel/trunk/hid/mousedrv.inc index 5a7d437ad3..eea8df5667 100644 --- a/kernel/trunk/hid/mousedrv.inc +++ b/kernel/trunk/hid/mousedrv.inc @@ -41,7 +41,12 @@ draw_mouse_under: ; return old picture cmp [set_hw_cursor], 0 - jz @F + jz @F + pushad + movzx eax,word [0xfb4a] + movzx ebx,word [0xfb4c] + stdcall [hw_restore], eax, ebx + popad ret @@: pushad @@ -83,13 +88,23 @@ save_draw_mouse: cmp [set_hw_cursor], 0 jz @F + pushad + mov [0xfb4a],ax mov [0xfb4c],bx - movzx ebx,word [0xfb0c] - movzx eax,word [0xfb0a] - push ebx + movzx eax,word [0xfb0c] + movzx ebx,word [0xfb0a] push eax + push ebx + + mov ecx, [0xfe00] + inc ecx + mul ecx + movzx edx, byte [display_data+ebx+eax] + shl edx, 8 + push [edx+PROC_BASE+APPDATA.cursor] call [set_hw_cursor] + popad ret @@: pushad diff --git a/kernel/trunk/kernel.asm b/kernel/trunk/kernel.asm index 39bf4b92ea..c9b8e26340 100644 --- a/kernel/trunk/kernel.asm +++ b/kernel/trunk/kernel.asm @@ -358,6 +358,7 @@ B32: ; MEMORY MODEL call mem_test + mov [MEM_AMOUNT], eax mov [pg_data.mem_amount], eax @@ -394,7 +395,7 @@ include 'detect/disks.inc' ; btr [cpu_caps], CAPS_PSE ;test: don't use large pages ; btr [cpu_caps], CAPS_PGE ;test: don't use global pages ; btr [cpu_caps], CAPS_MTRR ;test: don't use MTRR -; bts [cpu_caps], CAPS_TSC ;test: don't use TSC + bts [cpu_caps], CAPS_TSC ;force use rdtsc call init_memEx call init_page_map @@ -549,8 +550,10 @@ include 'vmodeld.inc' call boot_log call setmouse - mov [pci_access_enabled],1 - stdcall get_service, szHMouse + call init_cursors + +; mov [pci_access_enabled],1 +; stdcall get_service, szCURSOR ; SET PRELIMINARY WINDOW STACK AND POSITIONS @@ -589,21 +592,24 @@ include 'vmodeld.inc' ; name for OS/IDLE process mov dword [0x80000+256+APPDATA.app_name], dword 'OS/I' mov dword [0x80000+256+APPDATA.app_name+4], dword 'DLE ' + mov ebx, [def_cursor] + mov dword [0x80000+256+APPDATA.cursor], ebx + mov dword [0x80000+256+APPDATA.fpu_handler], 0 mov dword [0x80000+256+APPDATA.sse_handler], 0 ;set fpu save area mov esi, eax - bt [cpu_caps], CAPS_FXSR + bt [cpu_caps], CAPS_SSE jnc .no_sse lea edi, [eax+512] - mov dword [0x80000+256+APPDATA.fpu_state], edi + mov dword [PROC_BASE+256+APPDATA.fpu_state], edi mov ecx, 512/4 jmp @F .no_sse: lea edi, [eax+112] - mov dword [0x80000+256+APPDATA.fpu_state], edi + mov dword [PROC_BASE+256+APPDATA.fpu_state], edi mov ecx, 112/4 @@: rep movsd @@ -1712,51 +1718,68 @@ sys_getsetup: align 4 +mousefn dd msscreen, mswin, msbutton, msset + dd app_load_cursor + dd app_set_cursor + dd msset ;app_delete_cursor readmousepos: ; eax=0 screen relative ; eax=1 window relative ; eax=2 buttons pressed +; eax=3 set mouse pos ; reserved +; eax=4 load cursor +; eax=5 set cursor +; eax=6 delete cursor ; reserved - test eax,eax - jnz nosr - mov eax,[0xfb0a] - shl eax,16 - mov ax,[0xfb0c] - mov [esp+36],eax - ret - nosr: + cmp eax, 6 + ja msset + jmp [mousefn+eax*4] +msscreen: + mov eax,[0xfb0a] + shl eax,16 + mov ax,[0xfb0c] + mov [esp+36],eax + ret +mswin: + mov eax,[0xfb0a] + shl eax,16 + mov ax,[0xfb0c] + mov esi,[0x3010] + mov bx, word [esi-twdw+WDATA.box.left] + shl ebx,16 + mov bx, word [esi-twdw+WDATA.box.top] + sub eax,ebx - cmp eax,1 - jnz nowr - mov eax,[0xfb0a] - shl eax,16 - mov ax,[0xfb0c] - mov esi,[0x3010] - mov bx, word [esi-twdw+WDATA.box.left] - shl ebx,16 - mov bx, word [esi-twdw+WDATA.box.top] - sub eax,ebx + mov edi,[CURRENT_TASK] + shl edi,8 + sub ax,word[edi+PROC_BASE+APPDATA.wnd_clientbox.top] + rol eax,16 + sub ax,word[edi+PROC_BASE+APPDATA.wnd_clientbox.left] + rol eax,16 + mov [esp+36],eax + ret +msbutton: + movzx eax,byte [0xfb40] + mov [esp+36],eax + ret +msset: + ret - mov edi,[0x3000] - shl edi,8 - sub ax,word[edi+0x80000+APPDATA.wnd_clientbox.top] - rol eax,16 - sub ax,word[edi+0x80000+APPDATA.wnd_clientbox.left] - rol eax,16 +app_load_cursor: + add ebx, new_app_base + cmp ebx, new_app_base + jb msset + stdcall load_cursor, ebx, ecx + mov [esp+36], eax + ret - mov [esp+36],eax - ret - nowr: +app_set_cursor: + stdcall set_cursor, ebx + mov [esp+36], eax + ret - cmp eax,2 - jnz nomb - movzx eax,byte [0xfb40] - nomb: - mov [esp+36],eax - - ret is_input: @@ -3074,6 +3097,7 @@ sys_window_move: mov edx, [edi + WDATA.box.height] add ecx,eax add edx,ebx + call calculatescreen popad @@ -3251,7 +3275,7 @@ checkpixel: mov dl, [eax+edx+display_data] ; lea eax, [...] xor ecx, ecx - mov eax, [0x3000] + mov eax, [CURRENT_TASK] cmp al, dl setne cl @@ -4866,8 +4890,6 @@ undefined_syscall: ; Undefined system call ; ret - - keymap: db '6',27 diff --git a/kernel/trunk/kernel32.inc b/kernel/trunk/kernel32.inc index e11889ed4e..dcc005ff58 100644 --- a/kernel/trunk/kernel32.inc +++ b/kernel/trunk/kernel32.inc @@ -173,14 +173,15 @@ struc APPDATA db 5 dup(?) .fpu_state dd ? ;+16 - .fpu_init dd ? ;+20 + dd ? ;+20 unused .fpu_handler dd ? ;+24 .sse_handler dd ? ;+28 .event dd ? ;+32 .heap_base dd ? ;+36 .heap_top dd ? ;+40 + .cursor dd ? ;+44 - db 84 dup(?) ;+44 + db 80 dup(?) ;+48 .wnd_shape dd ? ;+128 .wnd_shape_scale dd ? @@ -253,6 +254,7 @@ include "sound/playnote.inc" ; player Note for Speaker PC include "video/vesa12.inc" ; Vesa 1.2 functions include "video/vesa20.inc" ; Vesa 2.0 functions include "video/vga.inc" ; VGA 16 color functions +include "video/cursors.inc" ; cursors functions ; Network Interface & TCPIP Stack diff --git a/kernel/trunk/video/arrow.cur b/kernel/trunk/video/arrow.cur new file mode 100644 index 0000000000..5e07900955 Binary files /dev/null and b/kernel/trunk/video/arrow.cur differ diff --git a/kernel/trunk/video/cursors.inc b/kernel/trunk/video/cursors.inc new file mode 100644 index 0000000000..362f3b948c --- /dev/null +++ b/kernel/trunk/video/cursors.inc @@ -0,0 +1,548 @@ + +LOAD_FROM_FILE equ 0 +LOAD_FROM_MEM equ 1 +LOAD_INDIRECT equ 2 +LOAD_SYSTEM equ 3 + +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+18d] + + mov eax,esi + 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,[pAnd] + mov ebx, [pBits] +.l1: + mov eax, [esi] + bswap eax + mov [counter], 16 +@@: + xor edx, edx + shl eax,1 + setc dl + dec edx + + mov ecx, [ebx] + and ecx, 0xF0 + shr ecx, 2 + add ecx, [pQuad] + mov ecx, [ecx] + and ecx, edx + and edx, 0xFF000000 + or edx, ecx + mov [edi], edx + + xor edx, edx + shl eax,1 + setc dl + dec edx + + mov ecx, [ebx] + and ecx, 0x0F + shl ecx, 2 + add ecx, [pQuad] + mov ecx, [ecx] + and ecx, edx + and edx, 0xFF000000 + or edx, ecx + mov [edi+4], edx + + inc ebx + add edi, 8 + dec [counter] + jnz @B + + add esi, 4 + mov edi,[rBase] + sub edi,128 + mov [rBase],edi + sub [height],1 + jnz .l1 + ret +endp + +align 4 +proc alloc_cursor + + pushfd + cli + mov ebx, [cursor_start] + mov ecx, [cursor_end] +.l1: + bsf eax,[ebx]; + jnz .found + add ebx,4 + cmp ebx, ecx + jb .l1 + popfd + xor eax,eax + ret +.found: + btr [ebx], eax + mov [cursor_start],ebx + sub ebx, cursor_map + shl ebx, 3 + add eax,ebx + shl eax,3 + lea eax,[cursors+eax+eax*2] + popfd + ret +endp + +align 4 +proc create_cursor + locals + h_cur dd ? + endl + + call alloc_cursor + test eax, eax + jz .fail + + mov [h_cur], eax + mov edi, eax + + xor ebx, ebx + + mov [edi+CURSOR.magic], 'CURS' + mov [edi+CURSOR.size], CURSOR_SIZE + mov [edi+CURSOR.pid], ebx + mov [edi+CURSOR.hot_x], ebx + mov [edi+CURSOR.hot_y], ebx + + stdcall kernel_alloc, dword 0x2000 + test eax, eax + jz .fail + + mov ebx, eax + mov eax, [h_cur] + mov [eax+CURSOR.base], ebx + ret +.fail: + ret +endp + +align 4 +proc set_cursor stdcall, hcursor:dword + mov eax, [hcursor] + mov ebx, [CURRENT_TASK] + shl ebx, 8 + xchg eax, [ebx+PROC_BASE+APPDATA.cursor] + ret +endp + +align 4 +proc load_cursor stdcall, src:dword, flags:dword + locals + handle dd ? + endl + + movzx eax, word [flags] + cmp eax, LOAD_FROM_FILE + jne .from_mem + + stdcall load_file, [src] + test eax, eax + jz .exit + mov [src], eax + + call create_cursor + test eax, eax + jz .fail + + mov [handle], eax + mov esi, [src] + movzx ebx, word [esi+10] + movzx ecx, word [esi+12] + mov [eax+CURSOR.hot_x], ebx + mov [eax+CURSOR.hot_y], ecx + + stdcall vesa_init_cursor, [eax+CURSOR.base], esi + stdcall kernel_free, [src] + mov eax, [handle] + ret + +.from_mem: + cmp eax, LOAD_FROM_MEM + jne .indirect + + call create_cursor + test eax, eax + jz .exit + + mov [handle], eax + mov esi, [src] + movzx ebx, word [esi+10] + movzx ecx, word [esi+12] + mov [eax+CURSOR.hot_x], ebx + mov [eax+CURSOR.hot_y], ecx + + stdcall vesa_init_cursor, [eax+CURSOR.base], [src] + mov eax, [handle] + ret + +.indirect: + cmp eax, LOAD_INDIRECT + jne .fail + + call create_cursor + test eax, eax + jz .exit + + movzx edx, byte [flags+2] + movzx ebx, byte [flags+3] + mov [eax+CURSOR.hot_x], ebx + mov [eax+CURSOR.hot_y], edx + + mov edi, [eax+CURSOR.base] + mov esi, [src] + mov ecx, 1024 + cld + rep movsd + ret +.fail: + mov ebx, [src] + stdcall kernel_free, ebx +.exit: + xor eax, eax + ret +endp + +align 4 +proc init_cursors + movzx eax, byte [ScreenBPP] + mov ebx, [SCR_BYTES_PER_LINE] + cmp eax, 32 + jne @F + sub ebx, 128 + jmp .init +@@: + cmp eax, 24 + jne .fail + sub ebx, 96 +.init: + mov [cur_def_interl], ebx + + xor eax, eax + mov edi, cursors + mov ecx, CURSOR_SIZE*16 + cld + rep stosd + + not eax + mov [cursor_map], eax + mov [cursor_map+4], eax + mov edx, cursor_map + mov [cursor_start], edx + add edx, 4 + mov [cursor_end], edx + + stdcall load_cursor, def_arrow, dword LOAD_FROM_MEM + mov [def_cursor], eax + + mov ecx, [SCR_X_SIZE] + mov edx, [SCR_Y_SIZE] + inc ecx + inc edx + mov [scr_width], ecx + mov [scr_height], edx + + movzx ebx, byte [ScreenBPP] + cmp ebx, 32 + jne @F + + mov dword [set_hw_cursor], cursor_32 + mov dword [hw_restore], restore_32 + ret +@@: + mov dword [set_hw_cursor], cursor_24 + mov dword [hw_restore], restore_24 + ret +.fail: + xor eax, eax + mov dword [set_hw_cursor], eax + mov dword [hw_restore], eax + ret +endp + +align 4 +proc restore_24 stdcall, x:dword, y:dword + locals + w dd ? + endl + + mov edi, [cur_saved_base] + mov edx, [cur_saved_h] + mov ebx, [cur_saved_interl] + + mov esi, cur_saved_data +@@: + mov ecx, [cur_saved_w] + lea ecx, [ecx+ecx*2] + rep movsb + add edi, ebx + dec edx + jnz @B + ret +endp + +align 4 +proc restore_32 stdcall, x:dword, y:dword + locals + w dd ? + endl + + mov edi, [cur_saved_base] + mov edx, [cur_saved_h] + mov ebx, [cur_saved_interl] + + mov esi, cur_saved_data +@@: + mov ecx, [cur_saved_w] + rep movsd + add edi, ebx + dec edx + jnz @B + ret +endp + +align 4 +proc cursor_24 stdcall, hcursor:dword, x:dword, y:dword + locals + w dd ? + h dd ? + st 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] + mov [x], ecx + sets dl + dec edx + and ecx, edx ;clip x to 0<=x + mov edi, ecx + sub edi, [x] + mov [_dx], edi + + xor edx, edx + sub eax, [esi+CURSOR.hot_y] + mov [y], eax + sets dl + dec edx + and eax, edx ;clip y to 0<=y + mov edi, eax + sub edi, [y] + mov [_dy], edi + + mul ebx + lea esi, [ecx+ecx*2] + add esi, [LFBAddress] + add esi, eax + mov [cur_saved_base],esi + + mov edi, [scr_width] + mov edx, [scr_height] + mov eax, 32 + + sub edi, ecx + cmp edi, eax + cmovg edi, eax + sub edi, [_dx] + + sub edx, [y] + cmp edx, eax + cmovg edx, eax + sub edx, [_dy] + + mov [w], edi + mov [h], edx + mov [cur_saved_w], edi + mov [cur_saved_h], edx + + sub eax, edi + lea eax, [eax+eax*2] + lea edi, [edi+edi*2] + sub ebx, edi + mov [cur_saved_interl], ebx + + mov edi, cur_saved_data +@@: + mov ecx, [w] + lea ecx, [ecx+ecx*2] + rep movsb + add esi, ebx + dec edx + jnz @B + +;draw cursor + mov edx, eax + mov edi, [cur_saved_base] + mov eax, [_dy] + shl eax, 5 + add eax, [_dx] + shl eax, 2 + + mov esi, [hcursor] + mov esi, [esi+CURSOR.base] + add esi, eax +.row: + mov ecx, [w] +.pix: + lodsd + test eax, 0xFF000000 + jz @F + + mov word [edi], ax + shr eax, 16 + mov [edi+2],al +@@: + add edi, 3 + dec ecx + jnz .pix + + add esi, edx + add edi, ebx + dec [h] + jnz .row + ret +endp + +align 4 +proc cursor_32 stdcall, hcursor:dword, x:dword, y:dword + locals + w dd ? + h dd ? + st 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] + mov [x], ecx + sets dl + dec edx + and ecx, edx ;clip x to 0<=x + mov edi, ecx + sub edi, [x] + mov [_dx], edi + + xor edx, edx + sub eax, [esi+CURSOR.hot_y] + mov [y], eax + sets dl + dec edx + and eax, edx ;clip y to 0<=y + mov edi, eax + sub edi, [y] + mov [_dy], edi + + mul ebx + lea esi, [eax+ecx*4] + add esi, [LFBAddress] + mov [cur_saved_base],esi + + mov edi, [scr_width] + mov edx, [scr_height] + mov eax, 32 + + sub edi, ecx + cmp edi, eax + cmovg edi, eax + sub edi, [_dx] + + sub edx, [y] + cmp edx, eax + cmovg edx, eax + sub edx, [_dy] + + mov [w], edi + mov [h], edx + mov [cur_saved_w], edi + mov [cur_saved_h], edx + + sub eax, edi + shl eax, 2 + shl edi, 2 + sub ebx, edi + mov [cur_saved_interl], ebx + + mov edi, cur_saved_data +@@: + mov ecx, [w] + rep movsd + add esi, ebx + dec edx + jnz @B + +;draw cursor + mov edx, eax + mov edi, [cur_saved_base] + mov eax, [_dy] + shl eax, 5 + add eax, [_dx] + shl eax, 2 + + mov esi, [hcursor] + mov esi, [esi+CURSOR.base] + add esi, eax +.row: + mov ecx, [w] +.pix: + lodsd + test eax, 0xFF000000 + jz @F + mov [edi], eax +@@: + add edi, 4 + dec ecx + jnz .pix + add esi, edx + add edi, ebx + dec [h] + jnz .row + ret +endp + +align 4 +def_arrow: + file 'arrow.cur' +