summaryrefslogtreecommitdiff
path: root/video/compositor.c
diff options
context:
space:
mode:
authorMiguel <m.i@gmx.at>2018-09-29 01:51:16 +0200
committerMiguel <m.i@gmx.at>2018-09-29 01:51:16 +0200
commit34c4a90794e78b97e4bd24f09c457d5e171e53f4 (patch)
tree5e6b7c163fc0d95d7b4fcf4e8a26e53ec35d7ab3 /video/compositor.c
parentbe3d9f2cf2a8cfe670eac6df255db55ff9205c49 (diff)
first prototype of compositing window manager
Diffstat (limited to 'video/compositor.c')
-rw-r--r--video/compositor.c236
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");
+
+}