summaryrefslogtreecommitdiff
path: root/video/compositor.c
diff options
context:
space:
mode:
authorMiguel <m.i@gmx.at>2018-10-19 13:30:01 +0200
committerMiguel <m.i@gmx.at>2018-10-19 13:30:01 +0200
commitc9c26727a11c37f61bc51662c3ca498737ce523f (patch)
tree0032f002df36292e1b07c6add5c73a0b050a76c3 /video/compositor.c
parent45ce8728224caa44d31dca3117992b193fa3cd98 (diff)
compositor stuff
Diffstat (limited to 'video/compositor.c')
-rw-r--r--video/compositor.c247
1 files changed, 83 insertions, 164 deletions
diff --git a/video/compositor.c b/video/compositor.c
index e7fd15f..4a7a5cc 100644
--- a/video/compositor.c
+++ b/video/compositor.c
@@ -1,4 +1,9 @@
-// TODO OPTIMIZE //
+// TODO : TEXTMODE FALLBACK!
+// TODO : OPTIMIZE FOR SPEED!
+// TODO : /dev/mouse (how does it work in linux in vim etc?)
+// TODO : check what is active,happens ONLY on
+// refresh screen! (mouse handling)?
+
#include "compositor.h"
#include "scheduler.h"
#include "syscalls.h"
@@ -16,89 +21,80 @@
#define MAX_WINDOWS 50
#define MAX_PID 200
+#define MAX_INVAL 100 // max pending invalidation rectangles per process
#define MAX_ICONS 50
void load_bmp(uint8_t *dst,char *filename);
+ringbuffer bg_invl;
+static uint32_t *vmem=VMEM_FRAMEBUFFER;
+
static uint8_t backbuffer[VESA_MAX_WIDTH*VESA_MAX_HEIGHT*4];
static uint8_t wallpaper [VESA_MAX_WIDTH*VESA_MAX_HEIGHT*4];
static uint8_t icon_data [VESA_MAX_WIDTH*VESA_MAX_HEIGHT*4];
-ringbuffer bg_invl;
+/** struct holding invalidated screen rect */
+struct inval
+{
+ uint16_t x;
+ uint16_t y;
+ uint16_t w;
+ uint16_t h;
+};
-// TODO: int16 int32 mixed nonsense !
+/** struct holding window data */
struct window
{
- uint32_t pid;
-
- struct pdirectory *vmem; // retreive from task manager?
uint8_t *fb;
- int16_t posx;
+ // position signed to check for overflows.
+ int16_t posx;
int16_t posy;
uint16_t width;
uint16_t height;
- uint16_t active;
+ uint32_t pid; // owning process id
- bool draw_border;
- bool draw_meat;
- bool on_close;
+ bool active; // mouseover
+ bool draw_meat; // redraw content?
+ bool draw_border; // show borders
+ bool on_close; // close button mouseover
+ // set on init
bool borderless; // never show borders
bool fixed; // can not be moved
+ struct pdirectory *vmem; // retreive from task manager?
};
-struct icon
-{
- int16_t posx;
- int16_t posy;
- uint16_t active;
-
- uint32_t iconx;
- uint32_t icony;
-
- char command[64];
- uint16_t width;
- uint16_t height;
-};
-
+static uint16_t next_window=0;
struct window windows[MAX_WINDOWS];
struct window *pid_to_win[MAX_PID];
-struct icon icons[MAX_ICONS];
-
-static uint16_t next_window=0;
-static uint16_t next_x=50;
-static uint16_t next_y=50;
-
-static uint16_t next_icon=0;
-static uint16_t next_icon_x;
-static uint16_t next_icon_y;
-static uint32_t *vmem=VMEM_FRAMEBUFFER;
+struct inval invalid[MAX_PID];
+uint8_t invalid_cnt[MAX_PID];
+// fraembuffer info
static uint16_t vesa_width;
static uint16_t vesa_height;
static uint16_t vesa_depth;
static uint16_t vesa_pitch;
-// initial mouse state
-static int mouse_x=100;
-static int mouse_y=100;
-
+// mouse state
+static int mouse_x;
+static int mouse_y;
static int last_mouse_x;
static int last_mouse_y;
+static int mouse_k=0;
-static uint16_t mouse_k=0;
-
-// icon
+// icons
static int mouse_icon_width=25;
static int mouse_icon_height=25;
static int mouse_icon_lx=0;
static int mouse_icon_ly=0;
static int mouse_icon_active_lx=0;
static int mouse_icon_active_ly=25;
+
static int X_icon_width=25;
static int X_icon_height=25;
static int X_icon_lx=0;
@@ -107,13 +103,13 @@ static int X_icon_active_lx=0;
static int X_icon_active_ly=75;
// costly but beautiful
-static bool option_blending=false; // so better disable ! :P// also not allowed to read from vmem! :(
+static bool option_blending=false; // so better disable!
// ugly and cheap
static bool option_win_borders=true; // so enable
+// framerate control
static bool skip_render;
-static bool skip_render2;
/** print single pixel to dst without bound checking */
static void put_pixel(uint8_t *dst, int x,int y, uint32_t color,uint16_t pitch,uint8_t depth,bool alpha)
@@ -129,13 +125,11 @@ static void put_pixel(uint8_t *dst, int x,int y, uint32_t color,uint16_t pitch,u
static uint32_t get_pixel(uint8_t *src, int x,int y,uint16_t pitch,uint8_t depth,bool alpha)
{
uint32_t col=0;
-
uint8_t *p=src+y*pitch+x*depth;
col=(*p++);
col+=(*p++)<<8;
col+=(*p++)<<16;
if(alpha)col+=(*p)<<24;
-
return col;
}
@@ -172,7 +166,6 @@ static void cpy_rect(uint8_t *src, uint16_t src_pitch, uint16_t src_x, uint16
bool transp,
uint32_t transp_key, bool alpha)
{
- // TODO optimize!
for(int x=0;x<width;x++)
for(int y=0;y<height;y++)
{
@@ -182,58 +175,15 @@ static void cpy_rect(uint8_t *src, uint16_t src_pitch, uint16_t src_x, uint16
}
}
-/*
-static void add_icon(char *cmd)
-{
- strcpy(icons[next_icon].command,cmd);
- icons[next_icon].posx=next_icon_x;
- icons[next_icon].posy=next_icon_y;
- icons[next_icon].active=false;
- icons[next_icon].width=120;
- icons[next_icon].height=120;
-
- icons[next_icon].iconx=next_icon*120+25;
- icons[next_icon].icony=0;
- next_icon_x+=130;
-
- next_icon++;
-}
-
-static void put_icon(uint8_t *dst, struct icon *ico)
-{
-if(ico->active)
-cpy_rect(icon_data,ico->iconx,ico->icony, // from
- dst, ico->posx,ico->posy, // to
- ico->width,ico->height, // icon dimensions
- false,
- 2, 0, // scaling not implemented yet anyway, not sure how to use them :P
- true, // transparency color key
- 0xff00ff // color key of transp
- ,false
- );
-else
-cpy_rect(icon_data,ico->iconx,ico->icony, // from
- dst, ico->posx,ico->posy, // to
- ico->width,ico->height, // icon dimensions
- false,
- 0, 0, // scaling not implemented yet anyway, not sure how to use them :P
- true, // transparency color key
- 0xff00ff // color key of transp
- ,true
- );
-}
-*/
-
static void put_win(uint8_t *dst, struct window *win)
{
struct pdirectory* mydir;
- x86_cli();// do not reschedule us til ready!
+ //x86_cli();// do not reschedule us til ready!
mydir=x86_get_page_directory();
x86_set_page_directory(win->vmem);
-
cpy_rect(win->fb,win->width*4,0,0, // from
dst,vesa_pitch,win->posx,win->posy, // to
win->width,win->height, // icon dimensions
@@ -321,7 +271,7 @@ cpy_rect(icon_data,vesa_pitch,iconx,icony, // from
//if(win->vmem)
//{
x86_set_page_directory(mydir);
- x86_sti();
+// x86_sti();
//}
//draw boundaries
@@ -346,7 +296,6 @@ cpy_rect(icon_data,vesa_pitch,iconx,icony, // from
}
static void put_bg(uint8_t *dst)
{
-
cpy_rect(wallpaper,vesa_pitch,0,0 , // from
dst,vesa_pitch,0,0, // to
vesa_width,vesa_height, // icon dimensions
@@ -356,8 +305,8 @@ static void put_bg(uint8_t *dst)
0xffffff // color key of transp
,false
);
-
}
+
static void put_mouse(uint8_t *dst)
{
@@ -398,14 +347,11 @@ void compositor_del_window(uint32_t addr)
{
windows[i]=windows[next_window-1];
}
-
next_window--;
}
}
}
-
-// TODO : TEXTMODE FALLBACK!
void compositor_init(uint16_t width, uint16_t height,uint16_t depth, uint16_t pitch, uint8_t *fb)
{
bg_invl=ringbuffer_init(3);
@@ -414,27 +360,19 @@ void compositor_init(uint16_t width, uint16_t height,uint16_t depth, uint16_t pi
vesa_height=height;
vesa_depth=depth/8;
vesa_pitch=pitch;
- int icon_count=5;
- next_icon_x=width/2-icon_count*130/2;
- next_icon_y=height-130;
- klog("initialized composing window manager to %d x %d x %d" ,width,height,depth);
+ mouse_x=vesa_width/2;
+ mouse_y=vesa_height/2;
+
+ // check pitch ...
uint16_t expected_pitch=width*depth/8;
klog("expected pitch = %d , actual pitch = %d",expected_pitch,pitch);
if(expected_pitch!=pitch)kpanic("sorry we need to fix this. padding not supported now");
- /*
- add_icon("vim");
- add_icon("vim");
- add_icon("vim");
- add_icon("vim");
- add_icon("vim");
- add_icon("vim");
- */
-
load_bmp(wallpaper,"/home/miguel/wallpaper.bmp");
load_bmp(icon_data,"/home/miguel/ico.bmp");
- compositor_mouse_handle(200,200,0);
+
+ klog("initialized composing window manager to %d x %d x %d" ,width,height,depth);
}
void compositor_wake()
@@ -444,8 +382,8 @@ void compositor_wake()
void compositor_paint()
{
- if(skip_render)return; // forced max rate
-
+ // forced max rate
+ if(skip_render)return;
skip_render=true;
//FPS: TODO write to bar!
@@ -460,19 +398,29 @@ void compositor_paint()
last=now;
frames=0;
}
-
- // // //
- put_bg(backbuffer);
+
+ //wallpaper
+ //put_bg(backbuffer);
for(int i=next_window-1;i>=0;i--)
{
put_win(backbuffer,&windows[i]);
}
+
put_mouse(backbuffer);
+ // TODO: only rects
memcpy(VMEM_FRAMEBUFFER,backbuffer,vesa_pitch*vesa_height);
}
+void check_win_pos(struct window *w)
+{
+ if(w->posx<0)w->posx=0;
+ if(w->posy<0)w->posy=0;
+ if(w->posx+w->width>=vesa_width)w->posx=vesa_width-w->width-1;
+ if(w->posy+w->height>=vesa_height)w->posy=vesa_height-w->height-1;
+}
+
void compositor_kb_handle(char c)
{
for(int i=0;i<MAX_WINDOWS;i++)
@@ -486,7 +434,6 @@ void compositor_kb_handle(char c)
}
}
-// TODO: check what is active ONLY on refresh screen!
void compositor_mouse_handle(int16_t diff_x,int16_t diff_y, uint8_t key)
{
// klog("%d %d %d",diff_x,diff_y,key);
@@ -494,7 +441,6 @@ void compositor_mouse_handle(int16_t diff_x,int16_t diff_y, uint8_t key)
if(!(key&2)&&(lastkey&2)) // right mouse click
{
- lastkey=key;
klog("tell init to spawn new foolshell");
fd_write(get_tty(1),'0'); // tell init to spawn new xterm
}
@@ -519,37 +465,6 @@ void compositor_mouse_handle(int16_t diff_x,int16_t diff_y, uint8_t key)
int active=-1;
bool active_win=false;
- for(int i=0;i<next_icon;i++)
- {
-
- struct icon *w=&icons[i];
- if(active==-1&&mouse_x>w->posx&&mouse_x<w->posx+w->width&&mouse_y>w->posy&&mouse_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;
-
- if(w->posx<0)w->posx=0;
- if(w->posy<0)w->posy=0;
- if(w->posx+w->width>=vesa_width)w->posx=vesa_width-640;
- if(w->posy+w->height>=vesa_height)w->posy=vesa_height-480;
- */
- }
-
- w->active=true;
- active=i;
- }
- else
- {
- w->active=false;
- }
- }
-
for(int i=0;i<next_window;i++)
{
struct window *w=&windows[i];
@@ -581,12 +496,9 @@ void compositor_mouse_handle(int16_t diff_x,int16_t diff_y, uint8_t key)
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>=vesa_width)w->posx=vesa_width-640;
- if(w->posy+w->height>=vesa_height)w->posy=vesa_height-400;
+ check_win_pos(w);
- w->draw_border=true;
+ w->draw_border=true;
}
else
@@ -680,20 +592,27 @@ void load_bmp(uint8_t *dst,char *filename)
{
{
uint32_t val=(fd_read(&dat)<<24)+(fd_read(&dat))+(fd_read(&dat)<<8)+(fd_read(&dat)<<16);
-// klog("0x%08x",val);
+// klog("0x%08x",val);
if(x>=vesa_width)continue;
if(h-y-1>=vesa_height)continue;
put_pixel(dst,x,h-y-1,val,vesa_pitch,4,true);
}
}
-
}
void compositor_invalidate(uint32_t pid,uint16_t x, uint16_t y, uint16_t w, uint16_t h,uint32_t *fb)
{
- if(fb!=0)pid_to_win[pid]->fb=fb;
// klog("pid %d invalidating %dx%d rect at %d %d with fb addr 0x%08x",pid,w,h,x,y,fb);
+ if(fb!=0)pid_to_win[pid]->fb=fb;
+ if(invalid_cnt[pid]>=MAX_INVAL)return;//invalidation buffer is full.
+
+ invalid[invalid_cnt[pid]].x=x;
+ invalid[invalid_cnt[pid]].y=y;
+ invalid[invalid_cnt[pid]].w=w;
+ invalid[invalid_cnt[pid]].h=h;
+ invalid_cnt[pid]++;
+
}
int compositor_create_window(uint32_t pid,uint16_t x, uint16_t y,uint16_t w,uint16_t h,uint16_t flags)
@@ -705,12 +624,10 @@ int compositor_create_window(uint32_t pid,uint16_t x, uint16_t y,uint16_t w,uint
pid_to_win[windows[0].pid]=&windows[next_window];
// auto position
- if(x==0xffff)
+ if(x==0xffff&&y==0xffff)
{
- next_x+=100;
- next_y+=100;
- windows[0].posx=next_x;
- windows[0].posy=next_y;
+ windows[0].posx=mouse_x-(w/2);
+ windows[0].posy=mouse_y-(h/2);
}
else
{
@@ -721,6 +638,8 @@ int compositor_create_window(uint32_t pid,uint16_t x, uint16_t y,uint16_t w,uint
windows[0].width=w;
windows[0].height=h;
+ check_win_pos(&windows[0]);
+
windows[0].active=0;
windows[0].fb=0;
@@ -737,12 +656,12 @@ int compositor_create_window(uint32_t pid,uint16_t x, uint16_t y,uint16_t w,uint
pid_to_win[windows[0].pid]=&windows[0];
next_window++;
- compositor_mouse_handle(0,0,0);
+ //compositor_mouse_handle(0,0,0);
return 0;// ok
}
void compositor_destroy_window(uint32_t pid)
{
- klog("destroying win for pid %d",pid);
+ klog("NOT IMPL: destroying win for pid %d",pid);
}