diff options
| -rw-r--r-- | Makefile | 27 | ||||
| -rw-r--r-- | README.md | 1 | ||||
| -rw-r--r-- | asm/asm_start.h | 7 | ||||
| -rw-r--r-- | asm/asm_start.s | 2 | ||||
| -rw-r--r-- | driver/timer.c | 13 | ||||
| -rw-r--r-- | grubiso/boot/grub/grub.cfg | 2 | ||||
| -rw-r--r-- | kernel/interrupts.c | 27 | ||||
| -rw-r--r-- | kernel/kernel.c | 21 | ||||
| -rw-r--r-- | kernel/mem.c | 14 | ||||
| -rw-r--r-- | kernel/scheduler.c | 14 | ||||
| -rw-r--r-- | kernel/smp.c | 27 | ||||
| -rw-r--r-- | kernel/smp.h | 2 | ||||
| -rw-r--r-- | kernel/vmem.c | 5 | ||||
| -rw-r--r-- | linker.ld | 1 | ||||
| -rw-r--r-- | userspace/fsh.c | 6 | ||||
| -rw-r--r-- | userspace/pain2.c | 44 | ||||
| -rw-r--r-- | userspace/put_pixel.h | 33 | ||||
| -rw-r--r-- | video/compositor.c | 125 | ||||
| -rw-r--r-- | video/compositor.h | 1 |
19 files changed, 240 insertions, 132 deletions
@@ -10,7 +10,7 @@ GIT_REVISION=$(shell git rev-parse HEAD) QEMU=/home/miguel/git/EXT/qemu-3.0.0/i386-softmmu/qemu-system-i386 -QEMU=qemu-system-i386 +#QEMU=qemu-system-i386 #use our cross compiler CC=i686-foolos-gcc @@ -137,8 +137,8 @@ all: tags $(FOOLOS_ISO) #$(FOOLOS) # tags # $(FOOLOS_VDI) new: clean all newrun: clean run -run: run-qemu -debug: run-qemu-debug +run: qemu-run +debug: qemu-debug ########## INCLUDES ################### @@ -188,7 +188,7 @@ $(KERNEL_IMG): $(ASM_OBJECTS) $(OBJECTS) # ~/opt/bochs-2.6.8/bin/bochs -q -f bochs/bochsrc -rc bochs/bochsdebug # run in qemu -run-qemu: all +qemu-run: all #qemu-system-i386 -enable-kvm disk.img -smp 4 -s #qemu-system-i386 -enable-kvm -s -kernel foolos.img -smp 4 -initrd userspace/ext2.img echo XDOTOOL HACK...&& sleep 0.2 && xdotool search --name "QEMU" windowsize 100 100 && echo XDOTOOL HACK END. & @@ -199,26 +199,23 @@ run-qemu: all -m 1024 #-net dump,file=./netfool -run-qemu-16: all - #qemu-system-i386 -enable-kvm disk.img -smp 4 -s - #qemu-system-i386 -enable-kvm -s -kernel foolos.img -smp 4 -initrd userspace/ext2.img - echo XDOTOOL HACK...&& sleep 0.2 && xdotool search --name "QEMU" windowsize 100 100 && echo XDOTOOL HACK END. & - qemu-system-i386 -enable-kvm $(FOOLOS_ISO) -smp 16 -serial stdio -run-qemu-debug: all +qemu-debug: all + echo XDOTOOL HACK...&& sleep 0.2 && xdotool search --name "QEMU" windowsize 100 100 && echo XDOTOOL HACK END. & + $(QEMU) -enable-kvm $(FOOLOS_ISO) -smp 4 -serial stdio \ + -net nic,model=e1000 \ + -net tap,ifname=tap0,script=no,downscript=no \ + -vga virtio \ + -m 1024 # qemu -enable-kvm -s -S ~/temp/FoolOs/disk.img # qemu -enable-kvm -s -singlestep disk.img # qemu-system-i386 -enable-kvm -s -S -kernel foolos.img -smp 4 -initrd userspace/ext2.img - echo XDOTOOL HACK...&& sleep 0.2 && xdotool search --name "QEMU" windowsize 100 100 && echo XDOTOOL HACK END. & - $(QEMU) -s -S -enable-kvm $(FOOLOS_ISO) -smp 4 -serial stdio \ - -net nic,model=e1000 \ - -net tap,ifname=tap0,script=no,downscript=no #-net dump,file=./netfool \ monitor: echo XDOTOOL HACK...&& sleep 0.2 && xdotool search --name "QEMU" windowsize 100 100 && echo XDOTOOL HACK END. & qemu-system-i386 -s -S $(FOOLOS_ISO) -smp 4 -monitor stdio # -serial stdio #-enable-kvm -smp 1 -stop-qemu: +qemu-kill: killall qemu-system-i386 @@ -37,6 +37,7 @@ Features * PCI Bus scanning * Ethernet E1000 PCI Driver * VESA Framebuffer with fallback to a text-only terminal +* Composite Window Manager * C-library for Userspace (Newlib) * Simple Network Stack (ARP, IPv4, ICMP, UDP) * Simple FoolShell diff --git a/asm/asm_start.h b/asm/asm_start.h index 3315d50..8390b8a 100644 --- a/asm/asm_start.h +++ b/asm/asm_start.h @@ -27,6 +27,11 @@ * * http://wiki.osdev.org/Bare_Bones */ +extern uint32_t kernel_start[]; +extern uint32_t kernel_end[]; + + + /** This will be called by a multiboot compilant boot-loader (i.e. grub2). * Calls kernel_main() passing through eax and ebx: * * eax - magic number @@ -37,3 +42,5 @@ void _start(); /** 16-bit entry point for application processors */ void _start_smp(); +static uint32_t get_kernel_start(){return kernel_start;} +static uint32_t get_kernel_end(){return kernel_end;} diff --git a/asm/asm_start.s b/asm/asm_start.s index 6ed43ca..7758354 100644 --- a/asm/asm_start.s +++ b/asm/asm_start.s @@ -1,7 +1,5 @@ .global _start .global _start_smp -.global stack_top -.global stack_bottom # Fill Multiboot Haeder, init stack and call kernel_main passing two params: # eax - magic number diff --git a/driver/timer.c b/driver/timer.c index 1c1fc05..6f0977c 100644 --- a/driver/timer.c +++ b/driver/timer.c @@ -159,20 +159,21 @@ static uint32_t timer_interrupt(uint32_t esp) uint64_t timer_init() { uint64_t epoch_time=get_rtc_time(); - task_system_clock_start=epoch_time*25; // since pit ticks 25times a second - asm_pit_rate_40ms(); //tick at 25hz - fixme("pit rate does only seem to work occasionally.. 1/25 seconds???" ); + + task_system_clock_start=epoch_time*100; // since pit ticks 100 times a second + asm_pit_rate_10ms(); //tick at 100hz + interrupt_register(INTERRUPT_PIT_TIMER,&timer_interrupt); - return epoch_time; + return epoch_time; } uint64_t timer_get_ms() { - return (asm_pit_get_ticks()+task_system_clock_start)*40; + return (asm_pit_get_ticks()+task_system_clock_start)*10; } uint64_t timer_get_uptime_ms() { - return asm_pit_get_ticks()*40; + return asm_pit_get_ticks()*10; } diff --git a/grubiso/boot/grub/grub.cfg b/grubiso/boot/grub/grub.cfg index f16c3a0..ad49f88 100644 --- a/grubiso/boot/grub/grub.cfg +++ b/grubiso/boot/grub/grub.cfg @@ -1,4 +1,4 @@ -set timeout=1 //seconds +set timeout=0 //seconds if loadfont ${prefix}/fonts/unicode.pf2 diff --git a/kernel/interrupts.c b/kernel/interrupts.c index e91d3ae..8bff84b 100644 --- a/kernel/interrupts.c +++ b/kernel/interrupts.c @@ -64,8 +64,9 @@ void interrupt_register(uint32_t irq, uint32_t func_addr) */ uint32_t interrupt_handler(uint32_t esp, uint32_t irq) { - + uint32_t cpu=smp_get(SMP_APIC_ID); uint32_t *stack; + static uint32_t timer=0; if(handlers[irq]!=0) { @@ -73,29 +74,38 @@ uint32_t interrupt_handler(uint32_t esp, uint32_t irq) esp=f(esp); apic_eoi(); } + else if(irq!=INTERRUPT_SYSCALL&&irq!=INTERRUPT_IPI&&irq!=INTERRUPT_APIC_TIMER) { kpanic("unhandled interrupt %d",irq); } - // process IRQ switch(irq) { case INTERRUPT_SYSCALL: stack=esp; task_syscall(stack[11],stack[8],stack[10],stack[9]); //eax,ebx,ecx,edx - esp=scheduler_wake_worker(esp); break; - case INTERRUPT_APIC_TIMER: // frequency is configured in smp.c - compositor_swap_buffers(); - esp=scheduler_run(esp,-1); + + case INTERRUPT_APIC_TIMER: // frequency is configured in smp.c (100hz) + + if(cpu==0) + { + timer++; + if(timer==10){ + compositor_swap_buffers(); + esp=scheduler_run(esp,-1); + timer=0; + } + } + apic_eoi(); break; case INTERRUPT_IPI: // inter process interrupt - esp=scheduler_run(esp,0); + esp=scheduler_run(esp,-1); apic_eoi(); break; @@ -107,7 +117,8 @@ uint32_t interrupt_handler(uint32_t esp, uint32_t irq) // reschedule to kernel worker on these if(irq==INTERRUPT_SYSCALL||irq==INTERRUPT_KEYBOARD||irq==INTERRUPT_MOUSE) { - esp=scheduler_wake_worker(esp); + scheduler_wake_worker(esp); + esp=scheduler_run(esp,-1); } // Ack all to LAPIC, except software syscalls diff --git a/kernel/kernel.c b/kernel/kernel.c index c6618ce..03dae1f 100644 --- a/kernel/kernel.c +++ b/kernel/kernel.c @@ -13,6 +13,7 @@ #include "vmem.h" //-- clean below headers --// +#include "asm_start.h" #include "compositor.h" #include "sysfs.h" #include "pci.h" @@ -40,12 +41,6 @@ #include "driver/vesa.h" #include "asm_pit.h" -//ugly? -extern uint32_t kernel_end[]; -extern uint32_t kernel_start[]; - -//TODO: we fear overrun of the initial buffer! -// /* F00L 0S Entry point (called directly from asm/multiboot.asm */ void kernel_main(uint32_t eax,uint32_t ebx) { @@ -62,9 +57,10 @@ void kernel_main(uint32_t eax,uint32_t ebx) klog("======================================"); uint32_t *top_kernel_vmem=VMEM_KERNEL+VMEM_KERNEL_PAGES*4096; - klog("The Kernel was loaded at: 0x%08X - 0x%08X",kernel_start,kernel_end); + klog("The Kernel was loaded at: 0x%08X - 0x%08X",get_kernel_start(),get_kernel_end()); klog("0x00000000 - 0x%08X will get identity mapped", VMEM_KERNEL_PAGES*4096); if(kernel_end>=top_kernel_vmem)kpanic("kernel to big. increase VMEM_KERNEL_PAGES"); + fixme("fear overrun of the initial buffer!"); // -- DISABLE LEGACY PIC -- // klog("Remapping & Disabling Programmable Interrupt Controller (PIC) ..."); @@ -106,7 +102,6 @@ void kernel_main(uint32_t eax,uint32_t ebx) fixme("do not disable anymore on context switching!"); fixme("write convenneint management funcs as: mapCPU, mapKErnel, map USerspace.."); fixme("move stack and guard with empty pages!"); - vmem_init(cfg_multiboot,&cfg_acpi,e1000_addr); struct pdirectory_struct *dir=vmem_kernel_dir(); @@ -157,10 +152,12 @@ void kernel_main(uint32_t eax,uint32_t ebx) klog("Unix Time = %u seconds",unixtime); // -- E1000 INIT (TODO: only if present!) --/ - klog("E1000 init ..."); - fixme("do not hardcode address and allow paging somehwere else"); - e1000_init(e1000_addr); + if(e1000_addr) + { + klog("E1000 init ..."); + e1000_init(e1000_addr); + } klog("Symmetric Multi Processing (SMP) start ... "); - smp_start_aps(&cfg_acpi); + smp_bsp(); } diff --git a/kernel/mem.c b/kernel/mem.c index d8ac66a..2d5d9f9 100644 --- a/kernel/mem.c +++ b/kernel/mem.c @@ -3,19 +3,14 @@ #include "mem.h" #include <stdint.h> #include "multiboot.h" +#include "asm_start.h" #define PMMNGR_BLOCKS_PER_BYTE 8 #define PMMNGR_BLOCK_SIZE 4096 #define PMMNGR_MAX_BLOCKS 1048576 // 4096*1048576 = 2^32 bytes (maxium addressable memory ~4GB) #define PMMNGR_MAP_SIZE PMMNGR_MAX_BLOCKS/PMMNGR_BLOCKS_PER_BYTE/4 -// defined in linker.ld and asm_start.s -extern uint32_t kernel_start[]; -extern uint32_t kernel_end[]; -extern uint32_t stack_top[]; -extern uint32_t stack_bottom[]; - -// sysfs inpue +// sysfs input test! uint32_t sysfs_in=128; //memory map bit array. Each bit represents a 4KB memory block, @@ -155,8 +150,11 @@ uint32_t mem_get_free_blocks_count() uint32_t mem_init(multiboot_information *info) { klog("markers in kernel binary:"); + + uint32_t kernel_start=get_kernel_start(); + uint32_t kernel_end=get_kernel_end(); + klog("kernel loaded at: 0x%08X- 0x%08X",kernel_start,kernel_end); - klog("initial stack at: 0x%08X- 0x%08X",stack_top,stack_bottom); fixme("check if kernel/ramimage size/pos does not exceed first 32mb (better vmem dynamically) limits!"); fixme("communicate pages to vmmem to identity map in kernel!"); diff --git a/kernel/scheduler.c b/kernel/scheduler.c index e5cdec7..ff46889 100644 --- a/kernel/scheduler.c +++ b/kernel/scheduler.c @@ -176,7 +176,7 @@ volatile uint32_t scheduler_run(uint32_t oldesp,uint32_t preference) for(int i=0;i<MAX_TASKS;i++) { int idx=(last_task[cpu]+1+i)%MAX_TASKS; // schedule round robin style - if(preference==-1&&idx==0)continue; +// if(preference==-1&&idx==0)continue; if(idx==preference||idx==2)continue;// skip sleeper and preferred tasks here. @@ -229,6 +229,8 @@ void scheduler_func() volatile int add_task(uint32_t parent_pid,uint32_t vmem, bool thread) { + static bool first=true; + uint32_t parent=task_runs(parent_pid); uint32_t cpu=smp_get(SMP_APIC_ID); @@ -265,7 +267,11 @@ volatile int add_task(uint32_t parent_pid,uint32_t vmem, bool thread) stack[12]=0x1; stack[13]=0; // this task returns pid=0 to the caller - if(!thread)compositor_add_window(vmem); + if(!thread&&first) + { + compositor_add_window(vmem); + //first=false; + } return task_list[cpu][i].pid; } @@ -277,7 +283,8 @@ uint32_t scheduler_wake_worker(uint32_t oldesp) { uint32_t cpu=smp_get(SMP_APIC_ID); task_list[cpu][0].syscall=false; // wake (syscall misused) - return scheduler_run(oldesp,0); + return 0; +// return scheduler_run(oldesp,0); } void scheduler_wake_all() @@ -484,5 +491,6 @@ void task_exit(uint32_t pid) task_list[cpu][i].active=false; } + compositor_del_window(task_list[cpu][idx].vmem); vmem_free_space_dir(task_list[cpu][idx].vmem,task_list[cpu][idx].thread); } diff --git a/kernel/smp.c b/kernel/smp.c index cf58b88..1b06352 100644 --- a/kernel/smp.c +++ b/kernel/smp.c @@ -16,8 +16,6 @@ #include "vesa.h" #include "syscalls.h" -void run_smp(); - // set cpu private value void smp_set(uint32_t offset, uint32_t value) { @@ -55,17 +53,12 @@ void smp_main_generic(bool bsp) asm volatile("jmp run_smp"); } -void smp_main() -{ - smp_main_generic(false); -} - void run_smp() { apic_enable(); klog("Setup the LAPIC Timer on CPU with lapic_id=0x%x ...",apic_id()); - apic_init_timer(5);// freq x HZ + apic_init_timer(100);// freq x HZ klog("Enable Interrupts on CPU with lapic_id=0x%x ...",apic_id()); asm_smp_unlock(); @@ -79,18 +72,12 @@ void run_smp() while(1)asm("hlt"); // wait for scheduler to kick in } -// this will start all our application processors! -void smp_start_aps(acpi_information *pros) +void smp_main() { - /* - for(int i=0;i<pros->processors;i++) - { - if(pros->boot==i)continue; // skib bsp + smp_main_generic(false); +} - uint8_t dest=pros->local_apic_id[i]; - klog("starting cpu %d (destination apic id: 0x%x) ",i,dest); - apic_sipi(dest,0x7); // start on 0x7000 - } -*/ - smp_main_generic(true); +void smp_bsp() +{ + smp_main_generic(true); } diff --git a/kernel/smp.h b/kernel/smp.h index 862c903..eb247b4 100644 --- a/kernel/smp.h +++ b/kernel/smp.h @@ -17,7 +17,7 @@ #include "acpi.h" -void smp_start_aps(acpi_information *); +void smp_bsp(); void smp_set(uint32_t offset, uint32_t value); uint32_t smp_get(uint32_t offset); diff --git a/kernel/vmem.c b/kernel/vmem.c index 883d56d..f6592b3 100644 --- a/kernel/vmem.c +++ b/kernel/vmem.c @@ -26,7 +26,7 @@ //! page sizes are 4kb #define PAGE_SIZE 4096 -uint32_t e1000_addr; +static uint32_t e1000_addr; //! page table entry typedef uint32_t pt_entry; @@ -44,10 +44,10 @@ typedef struct pdirectory_struct { pd_entry m_entries[PAGES_PER_DIR]; }pdirectory; -static uint32_t kernel_pages; static uint32_t fb_addr; static uint32_t local_apic_addr; static uint32_t io_apic_addr; + static uint32_t mod_start; static uint32_t mod_end; @@ -319,6 +319,7 @@ pdirectory* vmem_kernel_dir() void vmem_free_space_dir(pdirectory *dir,bool stack_only) { + fixme("free kmalloc too!"); fixme("stack_only version too!"); klog("free page directory at: 0x%X",dir); @@ -14,7 +14,6 @@ SECTIONS asm/asm_smp.o *(.multiboot) } - /* 0x00007E00 0x0007FFFF 480.5 KiB RAM (guaranteed free for use) Conventional memory diff --git a/userspace/fsh.c b/userspace/fsh.c index 81c2bce..d456d1b 100644 --- a/userspace/fsh.c +++ b/userspace/fsh.c @@ -229,6 +229,7 @@ bool process(char *buf) { int pid=_fork(); + if(pid==0) { if(token[0][0]=='/')sprintf(buf,"%s",token[0]); @@ -238,7 +239,10 @@ bool process(char *buf) exit(1); } - if(token[1]==NULL||strcmp(token[1],"&"))_wait(pid); + int last=0; + for(last=0;token[last+1]!=NULL;last++); + printf("last: %s\n",token[last]); + if(strcmp(token[last],"&"))_wait(pid); } return true; diff --git a/userspace/pain2.c b/userspace/pain2.c new file mode 100644 index 0000000..840b6b6 --- /dev/null +++ b/userspace/pain2.c @@ -0,0 +1,44 @@ +#include "put_pixel.h" + +#include <stdlib.h> +#include <stdio.h> + +#define dimx 640 +#define dimy 480 + +/* +void doscolor(int color,int color2) +{ + int i=0; + + for (int y = 0; y < dimy; y++) + for (int x = 0; x < dimx; x++) + { + { + if(x%2&&y%2)put_pixel(x,y,color); + else put_pixel(x,y,color2); + } + } +} +*/ + +int main(int argc,char **argv) +{ + for(int i=0;i<atoi(argv[1]);i++) + { + for(int i=0;i<100;i++) + { + put_rect(0,0,640,480,0xff0000); + put_rect(100+i,100+i,100,100,0x0000ff); + } + + for(int i=100;i>0;i--) + { + put_rect(0,0,640,480,0xff0000); + put_rect(100+i,100+i,100,100,0x0000ff); + } + } + + return EXIT_SUCCESS; +} + diff --git a/userspace/put_pixel.h b/userspace/put_pixel.h index f879772..445e890 100644 --- a/userspace/put_pixel.h +++ b/userspace/put_pixel.h @@ -1,33 +1,44 @@ #include <stdint.h> -#define VESA_FRAMEBUFFER 0xf6000000 +#define VESA_FRAMEBUFFER 0xfa000000 #define VESA_PITCH 2560 #define VESA_BPP 4 //https://forum.osdev.org/viewtopic.php?t=10018&p=64358 // TODO: what will happen in 24bit mode? +/* volatile int c; int delay() { c++; } -void put_pixel(int x,int y, uint32_t color) -{ - //do not write memory outside the screen buffer, check parameters against the VBE mode info - //if (x<0 || x>vesaXres|| y<0 || y>vesaYres) return; - //if (x) x = (x*(VESA_BPP>>3)); // get bytes (divide by 8) - //if (y) y = (y*VESA_PITCH); - //uint8_t *cTemp=VbeModeInfoBlock->physbase; +*/ +void put_rect(int x,int y, int w, int h,uint32_t col) +{ + // start uint8_t *p=VESA_FRAMEBUFFER+y*VESA_PITCH+x*VESA_BPP; uint32_t *pix=p; - *pix=color; -// for(int i=0;i<100;i++)delay(); + for(int yy=y; yy<y+h; yy++) // iter over lines + { + for(int xx=x; xx<x+w; xx++) // single line + { + *pix=col; + pix++; + } + pix+=640-w; + + } } - +void put_pixel(int x,int y, uint32_t color) +{ + uint8_t *p=VESA_FRAMEBUFFER+y*VESA_PITCH+x*VESA_BPP; + uint32_t *pix=p; + *pix=color; +} void put_pixel_old(int x,int y, int color) { diff --git a/video/compositor.c b/video/compositor.c index 924664b..e5aa325 100644 --- a/video/compositor.c +++ b/video/compositor.c @@ -11,14 +11,16 @@ #include "lib/string/string.h" +#define MAX_WINDOWS 100 + static uint32_t backbuffer[VESA_MAX_WIDTH*VESA_MAX_HEIGHT]; static uint32_t bgimage[VESA_MAX_WIDTH*VESA_MAX_HEIGHT]; static uint32_t *vmem=VMEM_FRAMEBUFFER; struct window { - uint16_t posx; - uint16_t posy; + int16_t posx; + int16_t posy; uint16_t width; uint16_t height; uint32_t color; @@ -26,14 +28,12 @@ struct window struct pdirectory *vmem; }; +struct window windows[MAX_WINDOWS]; + static uint16_t next_window=0; static uint16_t next_x=50; static uint16_t next_y=50; -#define MAX_WINDOWS 100 - -struct window windows[MAX_WINDOWS]; - static uint16_t vesa_width; static uint16_t vesa_height; static uint16_t vesa_pitch; @@ -47,32 +47,26 @@ static void put_pixel(int x,int y, uint32_t color) vmem[y*vesa_width+x]=color; } -static void put_rect(struct window *win) +static void put_win(struct window *win) { - struct pdirectory* mydir=x86_get_page_directory(); - if(win->vmem) - { - x86_set_page_directory(win->vmem); - } + struct pdirectory* mydir=x86_get_page_directory(); -uint32_t *user_vmem=VMEM_USER_FRAMEBUFFER; -uint32_t userx=0; -uint32_t usery=0; + if(win->vmem) + { + x86_set_page_directory(win->vmem); + } + uint32_t *user_vmem=VMEM_USER_FRAMEBUFFER; + uint32_t userx=0; + uint32_t usery=0; - for(uint16_t x=win->posx;x<win->posx+win->width;x++) - { - backbuffer[(win->posy-1)*vesa_width+x]=0xffffff; - backbuffer[(win->posy+win->height)*vesa_width+x]=0xffffff; - } + // iterate over complete window area for(uint16_t x=win->posx;x<win->posx+win->width;x++) { usery=0; - userx++; for(uint16_t y=win->posy;y<win->posy+win->height;y++) { - usery++; if(!win->active) { uint8_t dst_b=backbuffer[y*vesa_width+x]&0xff; @@ -82,31 +76,43 @@ uint32_t usery=0; uint8_t src_b=win->color&0xff; uint8_t src_g=(win->color&0xff00)>>8; uint8_t src_r=(win->color&0xff0000)>>16; + uint16_t a; - //we encoded alpha in the highest octet. 1-opaque 0-transparent - //user premultiplied alpha please! - uint16_t a=(0xff-((win->color&0xff000000)>>24)); - - uint8_t out_r=src_r+((a*dst_r)>>8); - uint8_t out_g=src_g+((a*dst_g)>>8); - uint8_t out_b=src_b+((a*dst_b)>>8); - - if(win->vmem) - { - if(userx<640&&usery<480)backbuffer[y*vesa_width+x]=user_vmem[userx+usery*640]; - } - + if(win->vmem) + { + uint32_t col=0xff0000; + col=user_vmem[userx+usery*640]; + src_b=col&0xff; + src_g=(col&0xff00)>>8; + src_r=(col&0xff0000)>>16; + a=0x44; + } else { - backbuffer[y*vesa_width+x]=(out_r<<16)+(out_g<<8)+out_b; + // just for testing + src_b=win->color&0xff; + src_g=(win->color&0xff00)>>8; + src_r=(win->color&0xff0000)>>16; + + a=(0xff-((win->color&0xff000000)>>24)); } + //we encoded alpha in the highest octet. 1-opaque 0-transparent + //no premultiplied alpha. TODO: change maybe? + // + + uint8_t out_r=((src_r*(0xff-a))>>8)+((a*dst_r)>>8); + uint8_t out_g=((src_g*(0xff-a))>>8)+((a*dst_g)>>8); + uint8_t out_b=((src_b*(0xff-a))>>8)+((a*dst_b)>>8); + + backbuffer[y*vesa_width+x]=(out_r<<16)+(out_g<<8)+out_b; + } else { if(win->vmem) { - if(userx<640&&usery<480)backbuffer[y*vesa_width+x]=~(user_vmem[userx+usery*640]); + backbuffer[y*vesa_width+x]=(user_vmem[userx+usery*640]); } else { @@ -114,13 +120,29 @@ uint32_t usery=0; } } + usery++; } + userx++; } if(win->vmem) { x86_set_page_directory(mydir); - } + } + + //draw boundaries + for(uint16_t x=win->posx;x<win->posx+win->width;x++) + { + backbuffer[(win->posy)*vesa_width+x]=0xffffff; //TOP + backbuffer[(win->posy+win->height-1)*vesa_width+x]=0xffffff; //BOTTOM + //backbuffer[(win->posy+win->height-3)*vesa_width+x]=0xffffff; //BOTTOM + } + for(uint16_t y=win->posy;y<win->posy+win->height;y++) + { + backbuffer[(y)*vesa_width+(win->posx)]=0xffffff; //LEFT + backbuffer[(y)*vesa_width+win->posx+win->width-1]=0xffffff; //RIGHT + } + // } static void put_mouse() @@ -139,6 +161,22 @@ static void put_mouse() } } +void compositor_del_window(uint32_t addr) +{ + for(int i=0;i<next_window;i++) + { + if(windows[i].vmem==(void *)addr) + { + if(i!=next_window-1) + { + windows[i]=windows[next_window-1]; + } + + next_window--; + } + } +} + void compositor_add_window(uint32_t addr) { if (next_window>=MAX_WINDOWS)kpanic("max number of windows reached. increase MAX_WINDOWS"); @@ -161,7 +199,6 @@ void compositor_add_window(uint32_t addr) next_window++; } - void compositor_init(uint16_t width, uint16_t height, uint16_t pitch) { vesa_width=width; @@ -178,7 +215,7 @@ void compositor_swap_buffers() for(int i=next_window-1;i>=0;i--) { - put_rect(&windows[i]); + put_win(&windows[i]); } put_mouse(); @@ -212,8 +249,15 @@ void compositor_mouse_handle(uint16_t x,uint16_t y, uint8_t key) { w->posx-=last_mouse_x-mouse_x; last_mouse_x=mouse_x; + w->posy-=last_mouse_y-mouse_y; last_mouse_y=mouse_y; + + if(w->posx<0)w->posx=0; + if(w->posy<0)w->posy=0; + if(w->posx+w->width>=1920)w->posx=1920-640; + if(w->posy+w->height>=1080)w->posy=1080-480; + } w->active=true; @@ -253,5 +297,4 @@ void compositor_set_background(char *ppm_raw_filename) } klog("finished"); - } diff --git a/video/compositor.h b/video/compositor.h index f9a8632..b8710b6 100644 --- a/video/compositor.h +++ b/video/compositor.h @@ -5,3 +5,4 @@ void compositor_set_background(char *ppm_raw_filename); void compositor_swap_buffers(); void compositor_mouse_handle(uint16_t x,uint16_t y, uint8_t key); void compositor_add_window(uint32_t addr); +void compositor_del_window(uint32_t addr); |
