diff options
| author | Miguel <m.i@gmx.at> | 2018-09-29 01:51:16 +0200 |
|---|---|---|
| committer | Miguel <m.i@gmx.at> | 2018-09-29 01:51:16 +0200 |
| commit | 34c4a90794e78b97e4bd24f09c457d5e171e53f4 (patch) | |
| tree | 5e6b7c163fc0d95d7b4fcf4e8a26e53ec35d7ab3 /video/compositor.c | |
| parent | be3d9f2cf2a8cfe670eac6df255db55ff9205c49 (diff) | |
first prototype of compositing window manager
Diffstat (limited to 'video/compositor.c')
| -rw-r--r-- | video/compositor.c | 236 |
1 files changed, 235 insertions, 1 deletions
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"); + +} |
