summaryrefslogtreecommitdiff
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
parentbe3d9f2cf2a8cfe670eac6df255db55ff9205c49 (diff)
first prototype of compositing window manager
-rw-r--r--driver/mouse.c10
-rw-r--r--driver/vesa.c9
-rw-r--r--grubiso/boot/grub/grub.cfg12
-rw-r--r--kernel/interrupts.c2
-rw-r--r--kernel/kernel.c1
-rw-r--r--kernel/kernel.h3
-rw-r--r--kernel/scheduler.c3
-rw-r--r--kernel/smp.c2
-rw-r--r--kernel/vmem.c17
-rw-r--r--userspace/Makefile2
-rw-r--r--video/compositor.c236
-rw-r--r--video/compositor.h4
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);