diff options
| -rw-r--r-- | driver/mouse.c | 10 | ||||
| -rw-r--r-- | driver/vesa.c | 9 | ||||
| -rw-r--r-- | grubiso/boot/grub/grub.cfg | 12 | ||||
| -rw-r--r-- | kernel/interrupts.c | 2 | ||||
| -rw-r--r-- | kernel/kernel.c | 1 | ||||
| -rw-r--r-- | kernel/kernel.h | 3 | ||||
| -rw-r--r-- | kernel/scheduler.c | 3 | ||||
| -rw-r--r-- | kernel/smp.c | 2 | ||||
| -rw-r--r-- | kernel/vmem.c | 17 | ||||
| -rw-r--r-- | userspace/Makefile | 2 | ||||
| -rw-r--r-- | video/compositor.c | 236 | ||||
| -rw-r--r-- | video/compositor.h | 4 |
12 files changed, 278 insertions, 23 deletions
diff --git a/driver/mouse.c b/driver/mouse.c index 0485096..d0f1591 100644 --- a/driver/mouse.c +++ b/driver/mouse.c @@ -3,6 +3,7 @@ #include "mouse.h" #include "ringbuffer.h" +#include "compositor.h" #include "interrupts.h" #include "kernel/kernel.h" #include "log.h" @@ -145,13 +146,10 @@ void mouse_action() if(mouse_x<0)mouse_x=0; if(mouse_y<0)mouse_y=0; - if(mouse_x>800)mouse_x=800; - if(mouse_y>600)mouse_y=600; + if(mouse_x>=1920)mouse_x=1920-1; + if(mouse_y>=1080)mouse_y=1080-1; - //klog("%d / %d / %02x ",mouse_x, mouse_y,mouse_byte[2]); - if (mouse_byte[0] & 1)vesa_put_rect(mouse_x,600-mouse_y,10,10,0x00ffff); - //else vesa_put_rect(mouse_x,600-mouse_y,10,10,0x0000ff); - PutFont('X', mouse_x,600-mouse_y, 0xff0000,0); + compositor_mouse_handle(mouse_x,1080-mouse_y, mouse_byte[0]); } diff --git a/driver/vesa.c b/driver/vesa.c index 848b0bf..7405422 100644 --- a/driver/vesa.c +++ b/driver/vesa.c @@ -137,6 +137,13 @@ uint32_t vesa_init(multiboot_information *inf, foolfont *rawfont) vesaBpp=inf->framebuffer_bpp; vesaAddr=inf->framebuffer_addr; + // virtual screen + vesaXres=640; + vesaYres=480; + vesaPitch=640*4; + vesaBpp=32; + vesaAddr=VMEM_USER_FRAMEBUFFER; + //the only functionallu important init lines! (rest is log) //VbeModeInfoBlock=mode; deffont=rawfont; @@ -193,7 +200,7 @@ void PutPixel(int x,int y, int color) if (x) x = (x*(vesaBpp>>3)); // get bytes (divide by 8) if (y) y = (y*vesaPitch); //uint8_t *cTemp=VbeModeInfoBlock->physbase; - uint8_t *cTemp=VMEM_FRAMEBUFFER; + uint8_t *cTemp=VMEM_USER_FRAMEBUFFER; cTemp[x+y] = (uint8_t)(color & 0xff); cTemp[x+y+1] = (uint8_t)((color>>8) & 0xff); diff --git a/grubiso/boot/grub/grub.cfg b/grubiso/boot/grub/grub.cfg index b9fa2ac..f16c3a0 100644 --- a/grubiso/boot/grub/grub.cfg +++ b/grubiso/boot/grub/grub.cfg @@ -16,21 +16,21 @@ then terminal_output gfxterm fi -menuentry "FoolOS (640x480x32)" { +menuentry "FoolOS (1920x1080x32)" { multiboot /boot/foolos.bin - set gfxpayload=640x480x32 + set gfxpayload=1920x1080x32 module /boot/ext2.img } -menuentry "FoolOS (textmode)" { +menuentry "FoolOS (640x480x32)" { multiboot /boot/foolos.bin - set gfxpayload=text + set gfxpayload=640x480x32 module /boot/ext2.img } -menuentry "FoolOS (1920x1080x32)" { +menuentry "FoolOS (textmode)" { multiboot /boot/foolos.bin - set gfxpayload=1920x1080x32 + set gfxpayload=text module /boot/ext2.img } diff --git a/kernel/interrupts.c b/kernel/interrupts.c index 387b822..e91d3ae 100644 --- a/kernel/interrupts.c +++ b/kernel/interrupts.c @@ -12,6 +12,7 @@ #include "smp.h" #include "apic.h" #include "ringbuffer.h" +#include "compositor.h" /** The size of our interrupts table */ #define INT_MAX 256 // 0-255 @@ -88,6 +89,7 @@ uint32_t interrupt_handler(uint32_t esp, uint32_t irq) break; case INTERRUPT_APIC_TIMER: // frequency is configured in smp.c + compositor_swap_buffers(); esp=scheduler_run(esp,-1); apic_eoi(); break; diff --git a/kernel/kernel.c b/kernel/kernel.c index e37f76f..c6618ce 100644 --- a/kernel/kernel.c +++ b/kernel/kernel.c @@ -136,6 +136,7 @@ void kernel_main(uint32_t eax,uint32_t ebx) klog("Compositor init ..."); compositor_init(cfg_multiboot->framebuffer_width,cfg_multiboot->framebuffer_height,cfg_multiboot->framebuffer_pitch); + compositor_set_background("/home/miguel/bg.ppm"); // -- STD STREAMS -- // klog("Standard Streams init ..."); diff --git a/kernel/kernel.h b/kernel/kernel.h index 1dcfb60..8baa57a 100644 --- a/kernel/kernel.h +++ b/kernel/kernel.h @@ -87,4 +87,7 @@ REFERENCES #define VMEM_FRAMEBUFFER_PAGES (1024*8) #define VMEM_EXT2_RAMIMAGE 0xF8000000 // 8192 pages (32megs) / identity mapped +#define VMEM_USER_FRAMEBUFFER 0xFA000000 +#define VMEM_USER_FRAMEBUFFER_PAGES 300// 4*320*480 bytes per app (one extra?) + #endif diff --git a/kernel/scheduler.c b/kernel/scheduler.c index 23ed7b2..e5cdec7 100644 --- a/kernel/scheduler.c +++ b/kernel/scheduler.c @@ -2,6 +2,7 @@ #include "kernel.h" #include "gdt.h" #include "log.h" +#include "compositor.h" #include "smp.h" #include "mem.h" @@ -263,6 +264,8 @@ volatile int add_task(uint32_t parent_pid,uint32_t vmem, bool thread) uint32_t *stack=task_list[cpu][i].esp; stack[12]=0x1; stack[13]=0; // this task returns pid=0 to the caller + + if(!thread)compositor_add_window(vmem); return task_list[cpu][i].pid; } diff --git a/kernel/smp.c b/kernel/smp.c index f23d15a..cf58b88 100644 --- a/kernel/smp.c +++ b/kernel/smp.c @@ -65,7 +65,7 @@ void run_smp() apic_enable(); klog("Setup the LAPIC Timer on CPU with lapic_id=0x%x ...",apic_id()); - apic_init_timer(1);// freq x HZ + apic_init_timer(5);// freq x HZ klog("Enable Interrupts on CPU with lapic_id=0x%x ...",apic_id()); asm_smp_unlock(); diff --git a/kernel/vmem.c b/kernel/vmem.c index 1eaf291..883d56d 100644 --- a/kernel/vmem.c +++ b/kernel/vmem.c @@ -299,7 +299,7 @@ pdirectory* vmem_kernel_dir() vmem_add_identity(dir,VMEM_KERNEL,VMEM_KERNEL_PAGES,false);//identity map first 32 megs... vmem_add_identity(dir,e1000_addr,32,false);//identity map 32 pages for e1000 - vmem_add_remap(dir,fb_addr,VMEM_FRAMEBUFFER,VMEM_FRAMEBUFFER_PAGES,true);//32megs should be enough for 4k (think about pitch) + vmem_add_remap(dir,fb_addr,VMEM_FRAMEBUFFER,VMEM_FRAMEBUFFER_PAGES,false);//32megs should be enough for 4k (think about pitch) vmem_add_remap(dir,local_apic_addr,VMEM_LAPIC,1,false); //apic addr should be at pagestart, right? TODO: check. vmem_add_remap(dir,io_apic_addr,VMEM_IOAPIC,1,false); @@ -312,6 +312,7 @@ pdirectory* vmem_kernel_dir() vmem_add_alloc(dir,VMEM_USER_ENV,1,true); vmem_add_alloc(dir,VMEM_USER_NEWLIB,1,true); vmem_add_alloc(dir,VMEM_USER_STACK_TOP-4096*VMEM_USER_STACK_PAGES,VMEM_USER_STACK_PAGES,true); + vmem_add_alloc(dir,VMEM_USER_FRAMEBUFFER,VMEM_USER_FRAMEBUFFER_PAGES,true); /// each new process gets a 640x480x32 area return dir; } @@ -336,7 +337,6 @@ void vmem_free_space_dir(pdirectory *dir,bool stack_only) for(int j=0;j<1024;j++) { - if(virt>=VMEM_FRAMEBUFFER&&virt<VMEM_FRAMEBUFFER+VMEM_FRAMEBUFFER_PAGES*4096)continue; // skip framebuffer pls uint32_t src_pd=src_table->m_entries[j]; uint32_t src_phys=pd_entry_get_frame(&src_pd); @@ -367,6 +367,7 @@ pdirectory* vmem_new_space_dir(pdirectory *copy_dir,bool stack_only) if(!stack_only) { + vmem_add_alloc(dir,VMEM_USER_FRAMEBUFFER,VMEM_USER_FRAMEBUFFER_PAGES,true); /// each new process gets a 640x480x32 area vmem_add_alloc(dir,VMEM_USER_PROG,VMEM_USER_PROG_PAGES,true); vmem_add_alloc(dir,VMEM_USER_ENV,1,true); } @@ -391,8 +392,6 @@ pdirectory* vmem_new_space_dir(pdirectory *copy_dir,bool stack_only) for(int j=0;j<1024;j++) { - if(virt>=VMEM_FRAMEBUFFER&&virt<VMEM_FRAMEBUFFER+VMEM_FRAMEBUFFER_PAGES*4096)continue; // skip framebuffer pls - uint32_t src_pd=src_table->m_entries[j]; uint32_t dst_pd=dst_table->m_entries[j]; @@ -401,7 +400,13 @@ pdirectory* vmem_new_space_dir(pdirectory *copy_dir,bool stack_only) if(src_pd) { - if(stack_only&&(virt==VMEM_USER_ENV||(virt>=VMEM_USER_PROG&&virt<VMEM_USER_PROG+VMEM_USER_PROG_PAGES*4096))) + if(stack_only&& + ( + virt==VMEM_USER_ENV + ||(virt>=VMEM_USER_PROG&&virt<VMEM_USER_PROG+VMEM_USER_PROG_PAGES*4096) + ||(virt>=VMEM_USER_FRAMEBUFFER&&virt<VMEM_USER_FRAMEBUFFER+VMEM_USER_FRAMEBUFFER_PAGES*4096) + ) + ) { // threads share this // vmem_add_remap(dir,src_phys,virt,1,true); @@ -429,8 +434,6 @@ pdirectory* vmem_new_space_dir(pdirectory *copy_dir,bool stack_only) else virt+=4096*1024; } - vmem_add_remap(dir,fb_addr,VMEM_FRAMEBUFFER,VMEM_FRAMEBUFFER_PAGES,true);//32megs should be enough for 4k (think about pitch) - return dir; } diff --git a/userspace/Makefile b/userspace/Makefile index 4afb98c..3b7a6b9 100644 --- a/userspace/Makefile +++ b/userspace/Makefile @@ -1,4 +1,4 @@ -IMAGESIZE=10000 #ext2.img size in Kb +IMAGESIZE=20000 #ext2.img size in Kb ####################### diff --git a/video/compositor.c b/video/compositor.c index 6ca6bd2..ba67598 100644 --- a/video/compositor.c +++ b/video/compositor.c @@ -3,25 +3,259 @@ #include "kernel.h" #include "kmalloc.h" #include "log.h" +#include "vmem.h" +#include "asm_x86.h" + +#include "mount.h" +#include "fd.h" #include "lib/string/string.h" 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; + uint16_t width; + uint16_t height; + uint32_t color; + uint16_t active; + struct pdirectory *vmem; +}; + +static uint16_t next_window=0; + +#define MAX_WINDOWS 10 + +struct window windows[MAX_WINDOWS]; static uint16_t vesa_width; static uint16_t vesa_height; static uint16_t vesa_pitch; +static uint16_t mouse_x=100; +static uint16_t mouse_y=100; +static uint16_t mouse_k; + +static void put_pixel(int x,int y, uint32_t color) +{ + vmem[y*vesa_width+x]=color; +} + +static void put_rect(struct window *win) +{ + struct pdirectory* mydir=x86_get_page_directory(); + 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++) + { + 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; + uint8_t dst_g=(backbuffer[y*vesa_width+x]&0xff00)>>8; + uint8_t dst_r=(backbuffer[y*vesa_width+x]&0xff0000)>>16; + + uint8_t src_b=win->color&0xff; + uint8_t src_g=(win->color&0xff00)>>8; + uint8_t src_r=(win->color&0xff0000)>>16; + + //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]; + } + + else + { + backbuffer[y*vesa_width+x]=(out_r<<16)+(out_g<<8)+out_b; + } + + } + else + { + backbuffer[y*vesa_width+x]=0xffffff; + } + + } + } + if(win->vmem) + { + + x86_set_page_directory(mydir); + } +} + +static void put_mouse() +{ + if(mouse_k&1) + { + for(int i=-5;i<5;i++) + for(int j=-5;j<5;j++) + backbuffer[(mouse_y+j)*vesa_width+mouse_x+i]=0x00ff00; + } + else + { + for(int i=-5;i<5;i++) + for(int j=-5;j<5;j++) + backbuffer[(mouse_y+i)*vesa_width+mouse_x+j]=0xff0000; + } +} + +void compositor_add_window(uint32_t addr) +{ + windows[next_window].posx=100; + windows[next_window].posy=100; + + windows[next_window].width=640; + windows[next_window].height=480; + + windows[next_window].color=0xAAAA00AA; + windows[next_window].active=0; + windows[next_window].vmem=addr; + + next_window++; +} + + void compositor_init(uint16_t width, uint16_t height, uint16_t pitch) { vesa_width=width; vesa_height=height; klog("initialized composing window manager to %d x %d",width,height); + + + windows[0].posx=800; + windows[0].posy=500; + + windows[0].width=640; + windows[0].height=480; + + windows[0].color=0xAAAA0000; + windows[0].active=0; + windows[0].vmem=0; + + next_window++; + + /* + windows[1].posx=200; + windows[1].posy=200; + + windows[1].width=640; + windows[1].height=480; + + windows[1].color=0xAA00AA00; + windows[1].active=0; + windows[1].vmem=0; + + windows[2].posx=400; + windows[2].posy=300; + + windows[2].width=640; + windows[2].height=480; + + windows[2].color=0xAA0000AA; + windows[2].active=0; + windows[2].vmem=0; + */ } void compositor_swap_buffers() { - memcpy(VMEM_FRAMEBUFFER,backbuffer,vesa_height*vesa_pitch/4);// TODO optimize? rects only too? + static bool first=true; +// if(!first)return; +// klog("swap"); + memcpy(backbuffer,bgimage,vesa_height*vesa_width*4);// TODO optimize? rects only too? + + for(int i=0;i<next_window;i++) + { + put_rect(&windows[i]); + } + + put_mouse(); + memcpy(VMEM_FRAMEBUFFER,backbuffer,vesa_height*vesa_width*4);// TODO optimize? rects only too? + first=false; } +void compositor_mouse_handle(uint16_t x,uint16_t y, uint8_t key) +{ + static int last_mouse_x; + static int last_mouse_y; + + if(!(key&1)) + { + last_mouse_x=x; + last_mouse_y=y; + } + + mouse_x=x; + mouse_y=y; + mouse_k=key; + int active=-1; + for(int i=0;i<MAX_WINDOWS;i++) + { + + struct window *w=&windows[i]; + if(active==-1&&x>w->posx&&x<w->posx+w->width&&y>w->posy&&y<w->posy+w->height) + { + if(key&1) + { + w->posx-=last_mouse_x-mouse_x; + last_mouse_x=mouse_x; + w->posy-=last_mouse_y-mouse_y; + last_mouse_y=mouse_y; + } + + w->active=true; + active=i; + } + else + { + w->active=false; + } + } +} + +void compositor_set_background(char *ppm_raw_filename) +{ + klog("loading bg..."); + fd bg=mount_file_open(ppm_raw_filename); + + uint32_t i=0; + + for(int y=0;y<vesa_width;y++) + { + for(int x=0;x<vesa_height;x++) + { + bgimage[i]=(fd_read(&bg)<<16)+(fd_read(&bg)<<8)+fd_read(&bg); + backbuffer[i]=bgimage[i]; + i++; + } + } + + klog("finished"); + +} diff --git a/video/compositor.h b/video/compositor.h index cef0c47..f9a8632 100644 --- a/video/compositor.h +++ b/video/compositor.h @@ -1,3 +1,7 @@ #include <stdint.h> void compositor_init(uint16_t width, uint16_t height, uint16_t pitch); +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); |
