summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.md1
-rw-r--r--kernel/kernel.h2
-rw-r--r--kernel/ringbuffer.c21
-rw-r--r--kernel/scheduler.c4
-rw-r--r--kernel/scheduler.h3
-rw-r--r--kernel/syscalls.c22
-rw-r--r--userspace/files/icons.ppmbin6220801 -> 6220801 bytes
-rw-r--r--userspace/init.c24
-rw-r--r--userspace/newcalls.h9
-rw-r--r--userspace/xterm/terminal.c17
-rw-r--r--userspace/xterm/vesa.c6
-rw-r--r--userspace/xterm/xterm.c53
-rw-r--r--video/compositor.c387
-rw-r--r--video/compositor.h3
14 files changed, 441 insertions, 111 deletions
diff --git a/README.md b/README.md
index f244e8e..7ab4ade 100644
--- a/README.md
+++ b/README.md
@@ -89,6 +89,7 @@ FoolOS was/is tested/developed on the following emulators/machines
Todos
-----
+two buffers for programms , never lock both. lock is syscall?
port as secondary user.. ? zlib libpng
https://wiki.osdev.org/Text_Mode_Cursor
diff --git a/kernel/kernel.h b/kernel/kernel.h
index 0194ef3..2393719 100644
--- a/kernel/kernel.h
+++ b/kernel/kernel.h
@@ -32,7 +32,7 @@ REFERENCES
//#define LOG_SYSCALLS
#define HIDE_FIXME
-#define FOOLOS_APIC_FREQ 25 // how many apic ticks per second
+#define FOOLOS_APIC_FREQ 60 // how many apic ticks per second
#define MAX_MOUNTS 10
diff --git a/kernel/ringbuffer.c b/kernel/ringbuffer.c
index 3526f4d..f11e02b 100644
--- a/kernel/ringbuffer.c
+++ b/kernel/ringbuffer.c
@@ -1,14 +1,15 @@
#include "ringbuffer.h"
#include "kmalloc.h"
#include "log.h"
+#include "asm_x86.h"
ringbuffer ringbuffer_init(uint32_t size)
{
ringbuffer f;
f.data=kballoc(size);
f.size=size*4096;
- f.front=f.size-1;
- f.back=f.size-1;
+ f.front=0;
+ f.back=0;
return f;
}
@@ -19,14 +20,12 @@ void ringbuffer_free(ringbuffer *f)
bool ringbuffer_full(ringbuffer* f)
{
- if((f->back-1+f->size)%f->size==f->front)return true;
- return false;
+ return((f->back+1)%f->size==f->front);
}
bool ringbuffer_empty(ringbuffer* f)
{
- if(f->front==f->back)return true;
- return false;
+ return(f->front==f->back);
}
bool ringbuffer_has(ringbuffer* f)
@@ -34,8 +33,6 @@ bool ringbuffer_has(ringbuffer* f)
return !ringbuffer_empty(f);
}
-//
-
bool ringbuffer_put(ringbuffer* f,uint8_t c)
{
if(ringbuffer_full(f))
@@ -45,8 +42,7 @@ bool ringbuffer_put(ringbuffer* f,uint8_t c)
}
f->data[f->back]=c;
- f->back--;
- f->back+=f->size;
+ f->back++;
f->back%=f->size;
return true;
@@ -57,11 +53,8 @@ uint8_t ringbuffer_get(ringbuffer* f)
if(ringbuffer_empty(f))return 0; // indistinguishable from value 0 :( // TODO
uint8_t c = f->data[f->front];
-
- f->front--;
- f->front+=f->size;
+ f->front++;
f->front%=f->size;
-
return c;
}
diff --git a/kernel/scheduler.c b/kernel/scheduler.c
index 59d26d1..5a65b7e 100644
--- a/kernel/scheduler.c
+++ b/kernel/scheduler.c
@@ -497,7 +497,7 @@ volatile uint32_t task_get_parent(uint32_t pid)
return task_list[cpu][idx].parent;
}
-volatile int task_add_win(uint32_t pid)
+volatile int task_add_win(uint32_t pid,ringbuffer *r)
{
uint32_t cpu=smp_get(SMP_APIC_ID);
uint32_t idx=task_idx(pid);
@@ -505,7 +505,7 @@ volatile int task_add_win(uint32_t pid)
struct pdirectory *vmem=x86_get_page_directory();//task_list[cpu][idx].vmem;
vmem_add_framebuffer(vmem);
klog("add win to compositor");
- compositor_add_window(vmem,pid);
+ compositor_add_window(vmem,pid,r);
return 0;
}
diff --git a/kernel/scheduler.h b/kernel/scheduler.h
index 71d5646..1b260d8 100644
--- a/kernel/scheduler.h
+++ b/kernel/scheduler.h
@@ -1,5 +1,6 @@
#include <stdint.h>
#include <stdbool.h>
+#include "ringbuffer.h"
// http://hosted.cjmovie.net/TutMultitask.htm
volatile uint32_t scheduler_run(uint32_t oldesp,uint32_t preference);
@@ -20,4 +21,4 @@ uint32_t task_runs(uint32_t pid);
uint32_t task_idx(uint32_t pid);
void task_exit(uint32_t pid);
void task_set_name(uint32_t pid, char *name);
-volatile int task_add_win(uint32_t pid);
+volatile int task_add_win(uint32_t pid,ringbuffer *);
diff --git a/kernel/syscalls.c b/kernel/syscalls.c
index e73f89c..aa27ed8 100644
--- a/kernel/syscalls.c
+++ b/kernel/syscalls.c
@@ -31,6 +31,7 @@
//TODO move to process.c and implement per process //
static fd fds[MAX_PID][MAX_FD];
+static ringbuffer invl[MAX_PID];
//static uint32_t opendir_pos[MAX_PID][MAX_FD];
//static char opendir_name[MAX_PID][MAX_FD][256];
static int tty[MAX_PID]; // keep track of /dev/tty fd for each process :P
@@ -445,6 +446,7 @@ uint32_t syscall_fork(int none1, int none2, int none3, int pid)
open_fd[newpid][i]=true;
}
tty[newpid]=tty[pid];
+ invl[newpid]=invl[pid];
// fds[newpid][0]=fd_from_ringbuffer(); // TODO fix
// open_fd[newpid][0]=true;
@@ -593,9 +595,22 @@ uint32_t syscall_tcsetattr(int fd, struct termios *termios_p, uint32_t none, uin
return 0;
}
-uint32_t syscall_gui_rect(uint32_t p1, uint32_t p2, uint32_t p3, uint32_t pid)
+uint32_t syscall_gui_rect(uint32_t xy, uint32_t wh, uint32_t none, uint32_t pid)
{
+// klog("pid %d x y %d %d w h %d %d",pid,xy>>16,xy&0xffff,wh>>16,wh&0xffff);
+
+ ringbuffer_put(&invl[pid],xy&0x000000ff);
+ ringbuffer_put(&invl[pid],(xy&0x0000ff00)>>8);
+ ringbuffer_put(&invl[pid],(xy&0x00ff0000)>>16);
+ ringbuffer_put(&invl[pid],(xy&0xff000000)>>24);
+
+ ringbuffer_put(&invl[pid],wh&0x000000ff);
+ ringbuffer_put(&invl[pid],(wh&0x0000ff00)>>8);
+ ringbuffer_put(&invl[pid],(wh&0x00ff0000)>>16);
+ ringbuffer_put(&invl[pid],(wh&0xff000000)>>24);
+
compositor_wake();
+
return 1;
}
uint32_t syscall_gui_win(uint32_t p1, uint32_t p2, uint32_t p3, uint32_t pid)
@@ -603,9 +618,8 @@ uint32_t syscall_gui_win(uint32_t p1, uint32_t p2, uint32_t p3, uint32_t pid)
uint32_t fdn=nextfd(pid);
fds[pid][fdn]=fd_from_ringbuffer();
tty[pid]=fdn;
-
- task_add_win(pid);
-
+ invl[pid]=ringbuffer_init(4);
+ task_add_win(pid,&invl[pid]);
return 1;
}
diff --git a/userspace/files/icons.ppm b/userspace/files/icons.ppm
index 45ce414..9d0ae35 100644
--- a/userspace/files/icons.ppm
+++ b/userspace/files/icons.ppm
Binary files differ
diff --git a/userspace/init.c b/userspace/init.c
index 4c55a12..e1ab531 100644
--- a/userspace/init.c
+++ b/userspace/init.c
@@ -6,8 +6,28 @@ char *env1[]={"HOME=/home/miguel","PS1=\033[34m$\033[37m","PWD=/home/miguel","PA
int main(int argc, char **argv)
{
- _execve("/bin/xterm",argv1,env1);
- while(1); // never reached hopefully
+ execve("/bin/xterm",argv1,env1);
+ /*
+
+ int pid=fork();
+
+ if(!pid)
+ {
+ execve("/bin/xterm",argv1,env1);
+ }
+ else
+ {
+ while(1)
+ {
+ _gui_win();
+ vesa_init(0);
+ void *tty=terminal_init_vesa();
+ getchar();
+ terminal_put('X');
+ }
+
+ }
+ */
}
/*
diff --git a/userspace/newcalls.h b/userspace/newcalls.h
new file mode 100644
index 0000000..177e100
--- /dev/null
+++ b/userspace/newcalls.h
@@ -0,0 +1,9 @@
+#include <stdio.h>
+#include "../interface/syscalls.h"
+
+/** invalidate screen rectangle */
+// we pack x,y and width,height togehter
+int _gui_inval(uint32_t xy, uint32_t wh)
+{
+ return syscall(SYSCALL_GUI_RECT,xy,wh,0);
+}
diff --git a/userspace/xterm/terminal.c b/userspace/xterm/terminal.c
index 15fbd36..07c21cf 100644
--- a/userspace/xterm/terminal.c
+++ b/userspace/xterm/terminal.c
@@ -86,6 +86,7 @@ typedef struct term_out_struct
void (*update_cursor)(uint32_t col,uint32_t row);
}term_out;
+// NOT USED (TODO?)
typedef struct term_in_struct
{
void (*put_char)(uint8_t c);
@@ -398,13 +399,6 @@ terminal_tty terminal_init(term_out *screen,term_in *input)
term_out tout;
terminal_tty tty;
-terminal_tty* terminal_init_vesa()
-{
- tout.put_char=vesa_console_put_char;
- tout.update_cursor=vesa_update_cursor;
- tty=(terminal_init(&tout,NULL));
- return &tty;
-}
// send one ASCII character to the terminal
void terminal_put(terminal_tty *tty, uint8_t c)
@@ -655,3 +649,12 @@ void terminal_put(terminal_tty *tty, uint8_t c)
tty->screen->update_cursor(tty->x,tty->y);
return;
}
+
+// initialize terminal for vesa
+terminal_tty* terminal_init_vesa()
+{
+ tout.put_char=vesa_console_put_char;
+ tout.update_cursor=vesa_update_cursor;
+ tty=(terminal_init(&tout,NULL));
+ return &tty;
+}
diff --git a/userspace/xterm/vesa.c b/userspace/xterm/vesa.c
index b6cec2f..6d61498 100644
--- a/userspace/xterm/vesa.c
+++ b/userspace/xterm/vesa.c
@@ -4,6 +4,7 @@
#include <stdio.h>
#include <malloc.h>
#include "vesa.h"
+#include "../newcalls.h"
void PutFont(char c, int x,int y, int color_fg,int color_bg);
@@ -62,7 +63,6 @@ void vesa_update_cursor(uint32_t col,uint32_t row)
console_x=col;
console_y=row;
-
vesa_console_put_char(termdata[oldy*80+oldx],termdata_bg[oldy*80+oldx],termdata_fg[oldy*80+oldx],oldx,oldy);
vesa_console_put_char(termdata[row*80+col],termdata_bg[row*80+col],termdata_fg[row*80+col],col,row);
}
@@ -194,6 +194,10 @@ void PutFont(char c, int x,int y, int color_fg,int color_bg)
else PutPixel(posx,posy,color_bg);
}
}
+
+ // invalidate area
+ _gui_inval((x<<16)|(y),(font_width+1<<16)|(font_height+1));
+
/*
for(int y=0;y<vesaYres;y++)
{
diff --git a/userspace/xterm/xterm.c b/userspace/xterm/xterm.c
index b333794..5540ac9 100644
--- a/userspace/xterm/xterm.c
+++ b/userspace/xterm/xterm.c
@@ -8,49 +8,56 @@ char *argv1[]={"xterm","/bin/fsh",0};
int main(int argc, char **argv)
{
+ // we need a window
_gui_win();
+ // basically loads font and sets a few constants
vesa_init(NULL);
+
+ // init tty and set vesa output funcs
void *tty=terminal_init_vesa();
//int xterm_in[2];
int xterm_out[2];
//_pipe(xterm_in);
- _pipe(xterm_out);
+ pipe(xterm_out);
- int pid=_fork();
+ int pid=fork();
- if(!pid)
+ if(!pid) // child
{
int tty_fd=_open("/dev/tty");
//_close(xterm_in[1]);
- _close(xterm_out[0]);
+ close(xterm_out[0]);
- _dup2(tty_fd,0);// stdin
- _dup2(xterm_out[1],1);// stdout
- _dup2(xterm_out[1],2);// stderr
+ dup2(tty_fd,0);// stdin
+ dup2(xterm_out[1],1);// stdout
+ dup2(xterm_out[1],2);// stderr
// replace process with our foolshell or whatever
if(argc==1)_execve(argv1[1],argv1,environ);
- _execve(argv[1],argv,environ);
+ execve(argv[1],argv,environ);
- while(1);
+ printf("unable to execve %s",argv[1]); // never reached
}
-
- //_close(xterm_in[0]);
- _close(xterm_out[1]);
-
- //_dup2(xterm_in[1],0); // compositor writes here.
- //_close(xterm_in[1]);
-
- while(1)
- {
- char buf[1];
-
- _read(xterm_out[0],buf,1); // show what foolshell writes to its stdout/stderr
- terminal_put(tty,buf[0]);
- _gui_rect();
+ else{
+
+ //_close(xterm_in[0]);
+ close(xterm_out[1]);
+
+ //_dup2(xterm_in[1],0); // compositor writes here.
+ //_close(xterm_in[1]);
+
+ // TODO quit if execve fails or child exits...
+ while(1)
+ {
+ char buf[1];
+
+ read(xterm_out[0],buf,1); // show what foolshell writes to its stdout/stderr
+ terminal_put(tty,buf[0]);
+ }
}
+
}
diff --git a/video/compositor.c b/video/compositor.c
index 64c9689..5826c03 100644
--- a/video/compositor.c
+++ b/video/compositor.c
@@ -12,31 +12,58 @@
#include "lib/string/string.h"
-#define MAX_WINDOWS 100
+#define MAX_WINDOWS 50
+#define MAX_ICONS 50
+ringbuffer bg_invl;
+
+// TODO: int16 int32 mixed nonsense
+//
struct window
{
uint32_t pid;
- struct pdirectory *vmem;
+ ringbuffer *invl;
+ struct pdirectory *vmem; // retreive from task manager?
int16_t posx;
int16_t posy;
uint16_t width;
uint16_t height;
- uint32_t color;
uint16_t active;
+ bool draw_border;
+ bool draw_meat;
+};
+
+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;
};
struct window windows[MAX_WINDOWS];
+struct icon icons[MAX_ICONS];
static uint8_t backbuffer [VESA_MAX_WIDTH*VESA_MAX_HEIGHT*4];
-static uint8_t icons [1920*1080*4];
+static uint8_t bgimage [VESA_MAX_WIDTH*VESA_MAX_HEIGHT*4];
+static uint8_t icon_data [1920*1080*4];
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;
static uint16_t vesa_width;
@@ -58,11 +85,12 @@ 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=25;
-static int mouse_icon_active_ly=0;
+static int mouse_icon_active_lx=0;
+static int mouse_icon_active_ly=25;
// costly but beautiful
-static bool option_blending=false; // so disable ! :P
+static bool option_blending=false; // so better disable ! :P// also not allowed to read from vmem! :(
+
// ugly and cheap
static bool option_win_borders=true; // so enable
@@ -72,15 +100,51 @@ 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)
{
- uint32_t *p=dst+y*vesa_pitch+x*vesa_depth;
- *p=color;
+ uint8_t *p=dst+y*vesa_pitch+x*vesa_depth;
+ *p++=color; // waste for 24bit...
+ *p++=color>>8; // waste for 24bit...
+ *p=color>>16; // waste for 24bit...
}
/** retrieves single pixel from src without bound checking */
static uint32_t get_pixel(uint8_t *src, int x,int y)
{
- uint32_t *p=src+y*vesa_pitch+x*vesa_depth;
- return *p;
+ uint32_t col=0;
+
+ uint8_t *p=src+y*vesa_pitch+x*vesa_depth;
+ col=(*p++); // waste for 24bit...
+ col+=(*p++)<<8; // waste for 24bit...
+ col+=(*p)<<16; // waste for 24bit...
+
+ return col;
+}
+
+/**
+ print single pixel to dst without bound checking using alpha value,
+ encoded alpha in the highest octet. 1-opaque 0-transparent
+ no premultiplied alpha. TODO: change maybe for speedup!?
+**/
+static void put_pixel_alpha(uint8_t *dst, int x,int y, uint32_t color)
+{
+ // TODO: do not use hardcoded alpha!
+ uint16_t a=0xaa;
+
+ uint32_t col=get_pixel(dst,x,y);
+
+ // TODO: optimize!!
+ uint8_t dst_b=col&0xff;
+ uint8_t dst_g=(col&0xff00)>>8;
+ uint8_t dst_r=(col&0xff0000)>>16;
+
+ uint8_t src_b=color&0xff;
+ uint8_t src_g=(color&0xff00)>>8;
+ uint8_t src_r=(color&0xff0000)>>16;
+
+ uint8_t out_r=((src_r*(0xff-a))>>8)+((a*dst_r)>>8);
+ uint8_t out_g=((src_g*(0xff-a))>>8)+((a*dst_g)>>8);
+ uint8_t out_b=((src_b*(0xff-a))>>8)+((a*dst_b)>>8);
+
+ put_pixel(dst, x,y,(out_r<<16)+(out_g<<8)+out_b);
}
static void cpy_rect(uint8_t *src, uint16_t src_x, uint16_t src_y,
@@ -88,10 +152,7 @@ static void cpy_rect(uint8_t *src, uint16_t src_x, uint16_t src_y,
uint16_t width, uint16_t height,
bool bnd_chk, uint8_t mult, uint8_t div,
bool transp,
- uint32_t transp_key
-
- )
-
+ uint32_t transp_key, bool alpha)
{
// TODO optimize!
for(int x=0;x<width;x++)
@@ -99,15 +160,59 @@ static void cpy_rect(uint8_t *src, uint16_t src_x, uint16_t src_y,
{
uint32_t val=get_pixel(src,src_x+x,src_y+y);
if(transp&&transp_key==val)continue;
- // TODO : just simple workaround since i do not want to edit the ppm file :P
- if(val==0)val=0xffffff;
- put_pixel(dst,dst_x+x,dst_y+y,val);
+ // TODO: quick workaround for arrow black
+ if(alpha)
+
+ put_pixel_alpha(dst,dst_x+x,dst_y+y,val);
+ else put_pixel(dst,dst_x+x,dst_y+y,val);
+
}
+}
+
+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(struct window *win)
+static void put_win(uint8_t *dst, struct window *win)
{
+
struct pdirectory* mydir;
x86_cli();// do not reschedule us til ready!
@@ -115,14 +220,24 @@ static void put_win(struct window *win)
x86_set_page_directory(win->vmem);
uint32_t *user_vmem=VMEM_USER_FRAMEBUFFER;
- uint32_t userx=0;
- uint32_t usery=0;
- // iterate over complete window area
- for(uint16_t x=win->posx;x<win->posx+win->width;x++)
+ // iterate over invalidated rects
+ while(ringbuffer_has(win->invl))
{
- usery=0;
- for(uint16_t y=win->posy;y<win->posy+win->height;y++)
+ int ry=ringbuffer_get(win->invl)+256*ringbuffer_get(win->invl);
+ int rx=ringbuffer_get(win->invl)+256*ringbuffer_get(win->invl);
+ int rh=ringbuffer_get(win->invl)+256*ringbuffer_get(win->invl);
+ int rw=ringbuffer_get(win->invl)+256*ringbuffer_get(win->invl);
+ if(!win->draw_meat)continue;
+
+ uint32_t userx=rx;
+ uint32_t usery=ry;
+
+ // iterate over rect area
+ for(uint16_t x=win->posx+rx;x<win->posx+rx+rw;x++)
+ {
+ usery=ry;
+ for(uint16_t y=win->posy+ry;y<win->posy+ry+rh;y++)
{
// blending non-active windows (TODO: costly?)
if(!win->active && option_blending)
@@ -141,8 +256,6 @@ static void put_win(struct window *win)
uint8_t src_r=(col&0xff0000)>>16;
a=0x44;
- //we encoded alpha in the highest octet. 1-opaque 0-transparent
- //no premultiplied alpha. TODO: change maybe for speedup!?
uint8_t out_r=((src_r*(0xff-a))>>8)+((a*dst_r)>>8);
uint8_t out_g=((src_g*(0xff-a))>>8)+((a*dst_g)>>8);
@@ -151,16 +264,18 @@ static void put_win(struct window *win)
backbuffer[y*vesa_width+x]=(out_r<<16)+(out_g<<8)+out_b;
*/
+ put_pixel_alpha(dst,x,y,(user_vmem[userx+usery*640]));
}
else
{
- put_pixel(backbuffer,x,y,(user_vmem[userx+usery*640]));
+ put_pixel(dst,x,y,(user_vmem[userx+usery*640]));
}
usery++;
}
userx++;
}
+ }
//if(win->vmem)
//{
x86_set_page_directory(mydir);
@@ -169,25 +284,50 @@ static void put_win(struct window *win)
//draw boundaries
- if(option_win_borders)
+ if(option_win_borders&&win->draw_border)
{
+ win->draw_border=false;
for(uint16_t x=win->posx;x<win->posx+win->width;x++)
{
- put_pixel(backbuffer,x,win->posy,0xffffff); //TOP
- put_pixel(backbuffer,x,win->posy+win->height-1,0xffffff); //BOTTOM
+ put_pixel(dst,x,win->posy,0xffffff); //TOP
+ put_pixel(dst,x,win->posy+win->height-1,0xffffff); //BOTTOM
}
for(uint16_t y=win->posy;y<win->posy+win->height;y++)
{
- put_pixel(backbuffer,win->posx,y,0xffffff); //LEFT
- put_pixel(backbuffer,win->posx+win->width-1,y,0xffffff); //RIGHT
+ put_pixel(dst,win->posx,y,0xffffff); //LEFT
+ put_pixel(dst,win->posx+win->width-1,y,0xffffff); //RIGHT
}
}
//
}
+static void put_bg(uint8_t *dst)
+{
+ while(ringbuffer_has(&bg_invl))
+ {
+ int ry=ringbuffer_get(&bg_invl)+256*ringbuffer_get(&bg_invl);
+ int rx=ringbuffer_get(&bg_invl)+256*ringbuffer_get(&bg_invl);
+ int rh=ringbuffer_get(&bg_invl)+256*ringbuffer_get(&bg_invl);
+ int rw=ringbuffer_get(&bg_invl)+256*ringbuffer_get(&bg_invl);
+
+cpy_rect(bgimage,rx,ry, // from
+ dst,rx,ry, // to
+ rw,rh, // icon dimensions
+ false,
+ 0, 0, // scaling not implemented yet anyway, not sure how to use them :P
+ false, // transparency color key
+ 0xffffff // color key of transp
+ ,false
+ );
-static void put_mouse()
+ }
+}
+static void put_mouse(uint8_t *dst,bool before)
{
+
+static int last_put_mouse_x=0;
+static int last_put_mouse_y=0;
+
int iconx=mouse_icon_lx;
int icony=mouse_icon_ly;
@@ -197,13 +337,31 @@ if(mouse_k&1)
icony=mouse_icon_active_ly;
}
-cpy_rect(icons,iconx,icony, // from
- backbuffer, mouse_x,mouse_y, // to
+if(before)
+{
+cpy_rect(bgimage,last_put_mouse_x,last_put_mouse_y, // from
+ dst, last_put_mouse_x,last_put_mouse_y, // to
mouse_icon_width,mouse_icon_height, // icon dimensions
false,
0, 0, // scaling not implemented yet anyway, not sure how to use them :P
- true, // transparency color key
+ false, // transparency color key
0xffffff // color key of transp
+ ,false
+ );
+return;
+}
+
+last_put_mouse_x=mouse_x;
+last_put_mouse_y=mouse_y;
+
+cpy_rect(icon_data,iconx,icony, // from
+ dst, mouse_x,mouse_y, // to
+ mouse_icon_width,mouse_icon_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
+ ,false
);
}
@@ -224,7 +382,7 @@ void compositor_del_window(uint32_t addr)
}
}
-void compositor_add_window(uint32_t addr,uint32_t pid)
+void compositor_add_window(uint32_t addr,uint32_t pid,ringbuffer *r)
{
klog("window added");
if (next_window>=MAX_WINDOWS)kpanic("max number of windows reached. increase MAX_WINDOWS");
@@ -238,12 +396,14 @@ void compositor_add_window(uint32_t addr,uint32_t pid)
next_y+=100;
windows[0].width=640;
- windows[0].height=480;
+ windows[0].height=400;
- windows[0].color=0xAAAA00AA;
windows[0].active=0;
windows[0].vmem=addr;
windows[0].pid=pid;
+ windows[0].invl=r;
+ windows[0].draw_border=true;
+ windows[0].draw_meat=true;
next_window++;
compositor_mouse_handle(200,200,0);
@@ -252,15 +412,27 @@ void compositor_add_window(uint32_t addr,uint32_t pid)
// TODO : TEXTMODE FALLBACK!
void compositor_init(uint16_t width, uint16_t height, uint16_t depth, uint16_t pitch)
{
+ bg_invl=ringbuffer_init(3);
+
vesa_width=width;
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);
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");
}
void compositor_wake()
@@ -274,27 +446,49 @@ void compositor_wake2()
void compositor_swap_buffers()
{
- if(skip_render||skip_render2)return;
+ //if(skip_render||skip_render2)return;
+ if(skip_render2)return; // force rate
+
skip_render=true;
skip_render2=true;
+ static frames=0;
+ static uint64_t last=0;
+ if(!last)last=timer_get_ms();
+ uint64_t now=timer_get_ms();
+ frames++;
+ if(now-last>3000)
+ {
+ klog("fps: %d",frames*1000/(now-last));
+
+ last=now;
+ frames=0;
+ }
+
+
+
static bool first=true;
-// if(!first)return;
-// klog("swap");
-// background
-// memcpy(backbuffer,bgimage,vesa_height*vesa_width*4);// TODO optimize? rects only too?
- // compositor_set_background(0);
+ if(first)memcpy(VMEM_FRAMEBUFFER,bgimage,vesa_pitch*vesa_height);// TODO optimize? rects only too??
+ first=false;
+ put_bg(VMEM_FRAMEBUFFER);
+
+ put_mouse(VMEM_FRAMEBUFFER,true);
+
for(int i=next_window-1;i>=0;i--)
{
- put_win(&windows[i]);
+ put_win(VMEM_FRAMEBUFFER,&windows[i]);
}
- put_mouse();
+ for(int i=next_icon-1;i>=0;i--)
+ {
+ // put_icon(backbuffer,&icons[i]);
+ }
+
+ put_mouse(VMEM_FRAMEBUFFER,false);
// TODO optimize? rects only too?
- memcpy(VMEM_FRAMEBUFFER,backbuffer,vesa_height*vesa_width*vesa_depth);
- first=false;
+// memcpy(VMEM_FRAMEBUFFER,backbuffer,vesa_pitch*vesa_height);
}
void compositor_kb_handle(char c)
@@ -310,9 +504,12 @@ 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);
+ static uint8_t lastkey;
+
mouse_x+=diff_x;
mouse_y+=diff_y;
mouse_k=key;
@@ -330,14 +527,62 @@ void compositor_mouse_handle(int16_t diff_x,int16_t diff_y, uint8_t key)
}
int active=-1;
- for(int i=0;i<MAX_WINDOWS;i++)
+ 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];
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->draw_meat=false;
+ uint32_t xy=(w->posx<<16)|(w->posy);
+ uint32_t wh=(640<<16)|(400);
+
+ /*
+ ringbuffer_put(&bg_invl,xy&0x000000ff);
+ ringbuffer_put(&bg_invl,(xy&0x0000ff00)>>8);
+ ringbuffer_put(&bg_invl,(xy&0x00ff0000)>>16);
+ ringbuffer_put(&bg_invl,(xy&0xff000000)>>24);
+
+ ringbuffer_put(&bg_invl,wh&0x000000ff);
+ ringbuffer_put(&bg_invl,(wh&0x0000ff00)>>8);
+ ringbuffer_put(&bg_invl,(wh&0x00ff0000)>>16);
+ ringbuffer_put(&bg_invl,(wh&0xff000000)>>24);
+ */
+
w->posx-=last_mouse_x-mouse_x;
last_mouse_x=mouse_x;
@@ -349,24 +594,51 @@ void compositor_mouse_handle(int16_t diff_x,int16_t diff_y, uint8_t key)
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->draw_border=true;
+
+ }
+ else
+ {
+ w->draw_meat=true;
+ if(lastkey&1)
+ {
+ uint32_t xy=(0<<16)|(0);
+ uint32_t wh=(640<<16)|(400);
+
+ ringbuffer_put(w->invl,xy&0x000000ff);
+ ringbuffer_put(w->invl,(xy&0x0000ff00)>>8);
+ ringbuffer_put(w->invl,(xy&0x00ff0000)>>16);
+ ringbuffer_put(w->invl,(xy&0xff000000)>>24);
+
+ ringbuffer_put(w->invl,wh&0x000000ff);
+ ringbuffer_put(w->invl,(wh&0x0000ff00)>>8);
+ ringbuffer_put(w->invl,(wh&0x00ff0000)>>16);
+ ringbuffer_put(w->invl,(wh&0xff000000)>>24);
+ }
+
}
w->active=true;
+ active_win=true;
active=i;
}
else
{
+
+
w->active=false;
}
}
- if(active!=-1&&active!=0&&(key&1))
+ if(active_win&&active!=-1&&active!=0&&(key&1))
{
struct window temp;
temp=windows[active];
windows[active]=windows[0];
windows[0]=temp;
}
+
+ lastkey=key;
}
// load background image or generate one if (param == 0)
@@ -389,7 +661,7 @@ void compositor_set_background(char *ppm_raw_filename)
uint32_t val=(fd_read(&bg)<<16)+(fd_read(&bg)<<8)+fd_read(&bg);
if(x>=vesa_width)continue;
if(y>=vesa_height)continue;
- put_pixel(icons,x,y,val);
+ put_pixel(icon_data,x,y,val);
i++;
}
}
@@ -405,12 +677,17 @@ void compositor_set_background(char *ppm_raw_filename)
{
for(int y=0;y<vesa_height;y++)
{
+ uint32_t val;
+ if(y%2)
+ {
int diffx=center_x-x;
int diffy=center_y-y;
int dist=diffx*diffx+diffy*diffy;
- int val = 0xff*dist/max_dist;
+ val = 0xaa*dist/max_dist;
+ }
+ else val=0x0;
- put_pixel(backbuffer,x,y,val);
+ put_pixel(bgimage,x,y,val<<8);
}
}
}
diff --git a/video/compositor.h b/video/compositor.h
index a7bbec4..f497d6c 100644
--- a/video/compositor.h
+++ b/video/compositor.h
@@ -1,4 +1,5 @@
#include <stdint.h>
+#include "ringbuffer.h"
void compositor_wake();
void compositor_wake2();
@@ -7,5 +8,5 @@ void compositor_set_background(char *ppm_raw_filename);
void compositor_swap_buffers();
void compositor_mouse_handle(int16_t x,int16_t y, uint8_t key);
void compositor_kb_handle(char c);
-void compositor_add_window(uint32_t addr,uint32_t pid);
+void compositor_add_window(uint32_t addr,uint32_t pid,ringbuffer *);
void compositor_del_window(uint32_t addr);