summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.md2
-rw-r--r--driver/mouse.c1
-rw-r--r--fs/stdstreams.c5
-rw-r--r--interface/syscalls.c54
-rw-r--r--interface/syscalls.h34
-rw-r--r--kernel/interrupts.c2
-rw-r--r--kernel/kernel.c5
-rw-r--r--kernel/scheduler.c13
-rw-r--r--kernel/scheduler.h1
-rw-r--r--kernel/smp.c1
-rw-r--r--kernel/syscalls.c39
-rw-r--r--userspace/Makefile12
-rw-r--r--userspace/fsh.c1
-rw-r--r--userspace/init.c41
-rw-r--r--userspace/newcalls.h9
-rw-r--r--userspace/pain/pain1.c2
-rw-r--r--userspace/pain2.c4
-rw-r--r--userspace/pain3.c5
-rw-r--r--userspace/xterm/rect.c22
-rw-r--r--userspace/xterm/vesa.c126
-rw-r--r--userspace/xterm/vesa.h1
-rw-r--r--userspace/xterm/xterm.c25
-rw-r--r--video/compositor.c445
-rw-r--r--video/compositor.h76
-rw-r--r--xxx/vesa.c (renamed from driver/vesa.c)0
-rw-r--r--xxx/vesa.h (renamed from driver/vesa.h)0
26 files changed, 474 insertions, 452 deletions
diff --git a/README.md b/README.md
index f9af063..2635262 100644
--- a/README.md
+++ b/README.md
@@ -89,6 +89,8 @@ FoolOS was/is tested/developed on the following emulators/machines
Todos
-----
+break out reusable parts. use typedefs
+
two buffers for programms , never lock both. lock is syscall?
port as secondary user.. ? zlib libpng
diff --git a/driver/mouse.c b/driver/mouse.c
index 14782f7..c292d97 100644
--- a/driver/mouse.c
+++ b/driver/mouse.c
@@ -10,7 +10,6 @@
#include "interrupts.h"
#include "kernel/kernel.h"
#include "log.h"
-#include "driver/vesa.h"
#include "asm_x86.h"
static volatile uint8_t mouse_cycle;
diff --git a/fs/stdstreams.c b/fs/stdstreams.c
index e5a2a08..4c4d36d 100644
--- a/fs/stdstreams.c
+++ b/fs/stdstreams.c
@@ -3,7 +3,6 @@
#include "fd.h"
#include "terminal.h"
#include "screen.h"
-#include "vesa.h"
#include "kmalloc.h"
@@ -32,8 +31,8 @@ fd fd_from_fb_term()
terminal_tty *tty1=mem+sizeof(term_out);
fifo *fif=tty1+sizeof(terminal_tty);
- screen->put_char=vesa_console_put_char;
- screen->update_cursor=vesa_update_cursor;
+// screen->put_char=vesa_console_put_char;
+// screen->update_cursor=vesa_update_cursor;
*tty1=terminal_init(screen,NULL);
diff --git a/interface/syscalls.c b/interface/syscalls.c
index c9964fd..42fba62 100644
--- a/interface/syscalls.c
+++ b/interface/syscalls.c
@@ -14,40 +14,47 @@
// TODO ? all funct not preceeded with underscore should go as #defines
// inside headers! for newlib we define both here now ... //
+// TODO: do we want all the wrappers here?
+// TODO: how does the underscored and non-underscored versions work in gcc-linux
+// lookup : ELF symbol interposion!
-// BASICS //
+// FIRST SOME TRIVIAL BASICS //
+// They do not even call the kernel at all //
-// everybody is root
+/** everybody is root in Fool Os */
uid_t getuid(void)
{
return 0;
}
-// everybody is root
+/** everybody is root in Fool Os */
uid_t getgid(void)
{
return 0;
}
-// everybody is root
+/** everybody is root in Fool Os */
char *getlogin(void)
{
return "root";
}
-// the hostname is hard
+/** The hostname is hardcoded here.
+ * Just recompile if you want to change this ;)
+ */
int gethostname(char *name, size_t len)
{
- strcpy(name,"foolcomp");
+ strcpy(name,"foolbox");
return 0; //success
}
-// no sync needed for our ram-image so far (maye once w use DMA?)
+/** no sync required by our ram-image **/
void sync(void)
{
}
-// set working directory - we simply save this in PWD environment var
+/** set working directory.
+ * We save it in PWD environment var */
int chdir(const char *path)
{
char buf[256];
@@ -56,14 +63,14 @@ int chdir(const char *path)
return 0; // assume success
}
-// get working dir (see chdir)
+/** get working dir (see chdir) */
char* getwd(char *buf)
{
return strcpy(buf,getenv("PWD"));
}
-// HELPER for flushing stdout down the toilet when main exits //
-// newlib does not do this ? TODO: check what the standard says. //
+/** HELPER for flushing stdout down the toilet when main exits.
+ newlib does not do this ? TODO: check what the standard says. */
void _flushing()
{
fflush(stdout);
@@ -71,12 +78,12 @@ void _flushing()
// C NEWLIB //
-// here we have a few posix syscalls required by newlib
+// here we have a few posix syscalls, mostly required by newlib
// (we use version newlib-3.0.0.20180802)
// https://sourceware.org/newlib/libc.html#Syscalls
// just check liunx man-pages, how they SHOULD work.
-// holds environment variables
+/** holds environment variables */
extern char **environ;
// terminate caller
@@ -250,7 +257,6 @@ int gettimeofday(struct timeval *tv, void *tz)
return syscall(SYSCALL_GETTIMEOFDAY,tv,tz,0);
}
-// not sure if required by newlib ? ///
int _lstat(const char *file, struct stat *st)
{
return syscall(SYSCALL_LSTAT,file,st,0);
@@ -260,14 +266,14 @@ int lstat(const char *file, struct stat *st)
return syscall(SYSCALL_LSTAT,file,st,0);
}
-// like fork but keeps runin' on same memory so we have multithreading
+/** works like fork() but keeps running mostly on the same memory so we
+ * have multithreading as well. */
int _clone(void)
{
return syscall(SYSCALL_CLONE,0,0,0);
}
// DIRENT //
-
DIR *opendir(const char *name)
{
DIR *dir=malloc(sizeof(struct dirent));
@@ -333,26 +339,26 @@ int dup(int oldfd)
// PRIMITIVE GUI SYSCALLS //
-// create window for running process
-int _gui_win()
+/** create window for running process */
+int _gui_win(uint32_t xy, uint32_t wh,uint32_t f)
{
- return syscall(SYSCALL_GUI_WIN,0,0,0);
+ return syscall(SYSCALL_GUI_WIN,xy,wh,f);
}
-// swap buffers
-int _gui_rect()
+/** invalidate screen rectangle and set user framebuffer addy
+ * we pack x,y and width,height togehter */
+int _gui_inval(uint32_t xy, uint32_t wh, uint32_t addr)
{
- return syscall(SYSCALL_GUI_RECT,0,0,0);
+ return syscall(SYSCALL_GUI_RECT,xy,wh,addr);
}
////////////////////////////////////////// move along fool ///////////
//
// ALL calls under this lines are just stubs to let some 3rd party stuff
-// compile and fail silently on runtime where applicable.
+// compile and fail silently during runtime where applicable.
//
/////
-
long fpathconf(int fd, int name)
{
return syscall(SYSCALL_UNIMPLEMENTED,"fpathconf",0,0);
diff --git a/interface/syscalls.h b/interface/syscalls.h
index 604e150..668a3d2 100644
--- a/interface/syscalls.h
+++ b/interface/syscalls.h
@@ -1,3 +1,19 @@
+/**
+ * @file
+ *
+ * Fool OS System Calls
+ * ====================
+ *
+ * This is THE way for user programms to communicate with the kernel.
+ *
+ * The kernel exhibits a set of a few posix-style calls and some other
+ * non-standard foolish calls invented by myself.
+ *
+ * TODO: DOCUMENT each call!
+ * reentrant? limitations? posix compilance? implemented fully?
+ */
+
+
#define SYSCALL_EXIT 60
#define SYSCALL_CLOSE 66
#define SYSCALL_EXECVE 64
@@ -20,14 +36,14 @@
#define SYSCALL_READDIR 63
#define SYSCALL_KILL 73
#define SYSCALL_POLL 80
-#define SYSCALL_CLONE 83
-#define SYSCALL_PIPE 84
-#define SYSCALL_DUP2 86
-#define SYSCALL_GUI_RECT 87
-#define SYSCALL_GUI_WIN 88
-#define SYSCALL_SELECT 89
-#define SYSCALL_TCGETATTR 90
-#define SYSCALL_TCSETATTR 91
-#define SYSCALL_OPENDIR 92
+#define SYSCALL_CLONE 83
+#define SYSCALL_PIPE 84
+#define SYSCALL_DUP2 86
+#define SYSCALL_GUI_RECT 87
+#define SYSCALL_GUI_WIN 88
+#define SYSCALL_SELECT 89
+#define SYSCALL_TCGETATTR 90
+#define SYSCALL_TCSETATTR 91
+#define SYSCALL_OPENDIR 92
#define SYSCALL_UNIMPLEMENTED 200
diff --git a/kernel/interrupts.c b/kernel/interrupts.c
index 702112c..9ff9cd3 100644
--- a/kernel/interrupts.c
+++ b/kernel/interrupts.c
@@ -111,7 +111,7 @@ uint32_t interrupt_handler(uint32_t esp, uint32_t irq)
if(cpu==0) // thi
{
// limit compositor to APIC_TIMER freq.(60hz?)
- if(irq==INTERRUPT_APIC_TIMER)compositor_wake2();
+ if(irq==INTERRUPT_APIC_TIMER)compositor_wake();
}
esp=scheduler_run(esp,-1); // just schedule to next task
diff --git a/kernel/kernel.c b/kernel/kernel.c
index a630f94..a259446 100644
--- a/kernel/kernel.c
+++ b/kernel/kernel.c
@@ -38,7 +38,6 @@
#include "fs/elf.h"
#include "kmalloc.h"
-#include "driver/vesa.h"
#include "asm_pit.h"
/** F00L 0S Entry point (called directly from asm/multiboot.asm)
@@ -147,8 +146,8 @@ void kernel_main(uint32_t eax,uint32_t ebx)
// -- COMPOSITOR (TODO: text-mode fallback) -- //
klog("Compositor init ...");
compositor_init(cfg_multiboot->framebuffer_width,cfg_multiboot->framebuffer_height,
- cfg_multiboot->framebuffer_bpp,cfg_multiboot->framebuffer_pitch);
- compositor_set_background("/home/miguel/icons.ppm");
+ cfg_multiboot->framebuffer_bpp,cfg_multiboot->framebuffer_pitch,
+ VMEM_FRAMEBUFFER);
// -- KB DRIVER -- //
klog("Keyboard init ...");
diff --git a/kernel/scheduler.c b/kernel/scheduler.c
index 9fe4f74..e5c279b 100644
--- a/kernel/scheduler.c
+++ b/kernel/scheduler.c
@@ -319,7 +319,7 @@ void task_syscall_worker()
{
keyboard_worker();
mouse_worker();
- compositor_swap_buffers();
+ compositor_paint();
}
__asm__("int $0x81"); // we are ready! force reschedule
@@ -498,6 +498,7 @@ volatile uint32_t task_get_parent(uint32_t pid)
return task_list[cpu][idx].parent;
}
+/*
volatile int task_add_win(uint32_t pid,ringbuffer *r)
{
uint32_t cpu=smp_get(SMP_APIC_ID);
@@ -506,9 +507,10 @@ volatile int task_add_win(uint32_t pid,ringbuffer *r)
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,r);
+ compositor_create_window(pid,0,0,640,400,0);
return 0;
}
+*/
int task_set_esp(uint32_t pid, uint32_t esp)
{
@@ -566,7 +568,12 @@ void task_exit(uint32_t pid)
task_list[cpu][i].active=false;
}
- compositor_del_window(task_list[cpu][idx].vmem);
vmem_free_space_dir(task_list[cpu][idx].vmem,task_list[cpu][idx].thread);
}
+uint32_t scheduler_get_vmem(uint32_t pid)
+{
+ uint32_t cpu=smp_get(SMP_APIC_ID);
+ uint32_t idx=task_runs(pid);
+ return task_list[cpu][idx].vmem;
+}
diff --git a/kernel/scheduler.h b/kernel/scheduler.h
index 7650f01..7761bb4 100644
--- a/kernel/scheduler.h
+++ b/kernel/scheduler.h
@@ -23,3 +23,4 @@ void task_exit(uint32_t pid);
void task_set_name(uint32_t pid, char *name);
volatile int task_add_win(uint32_t pid,ringbuffer *);
int task_set_esp(uint32_t pid, uint32_t esp);
+uint32_t scheduler_get_vmem(uint32_t pid);
diff --git a/kernel/smp.c b/kernel/smp.c
index a57b4b9..02b0263 100644
--- a/kernel/smp.c
+++ b/kernel/smp.c
@@ -13,7 +13,6 @@
#include "asm_pit.h"
#include "asm_smp.h"
#include "apic.h"
-#include "vesa.h"
#include "syscalls.h"
// set cpu private value
diff --git a/kernel/syscalls.c b/kernel/syscalls.c
index 083fbf1..ccda5f0 100644
--- a/kernel/syscalls.c
+++ b/kernel/syscalls.c
@@ -4,7 +4,6 @@
#include "lib/printf/printf.h"
#include "fs/ext2.h"
#include "kernel.h"
-#include "driver/vesa.h"
#include "fifo.h"
#include "fd.h"
#include "fs/elf.h"
@@ -27,9 +26,13 @@
#include "stdstreams.h"
#include "sys/unistd.h"
+
+// TODO oh maan, dyamically allocate some nice structures and think about reentrancy
+// and smp !!
+//TODO move to process.c or somehting..and implement per process //
+
#define MAX_PID 200
-//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];
@@ -69,7 +72,7 @@ int nextfd(int pid)
return i;
}
}
- return -1;
+ kpanic("ran out of filedescirptors for pid : %d",pid);
}
/** errno helper */
void set_errno(int no)
@@ -405,7 +408,6 @@ int syscall_execve(const char *name, char *const argv[], char *const env[], int
if(!entry_global)
{
- kpanic("no entry point!"); // TODO: rem
set_errno(ENOENT);
return -1;
}
@@ -488,6 +490,7 @@ uint32_t syscall_exit(int status, uint32_t none1, uint32_t none2,int pid)
}
}
+ compositor_destroy_window(pid);
task_exit(pid);
__asm__("int $0x81"); // please schedule us away once and for all
return 0;
@@ -597,32 +600,20 @@ uint32_t syscall_tcsetattr(int fd, struct termios *termios_p, uint32_t none, uin
return 0;
}
-uint32_t syscall_gui_rect(uint32_t xy, uint32_t wh, uint32_t none, uint32_t pid)
+uint32_t syscall_gui_rect(uint32_t xy, uint32_t wh, uint32_t fb, 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;
+ compositor_invalidate(pid,xy>>16,xy&0xffff,wh>>16,wh&0xffff,fb);
+ return 0; // can not fail
}
-uint32_t syscall_gui_win(uint32_t p1, uint32_t p2, uint32_t p3, uint32_t pid)
+
+uint32_t syscall_gui_win(uint32_t xy, uint32_t wh, uint32_t flags, uint32_t pid)
{
+ //create a ringbuffer for virtual per process /dev/tty (for fool-terms and similar)//
uint32_t fdn=nextfd(pid);
fds[pid][fdn]=fd_from_ringbuffer();
tty[pid]=fdn;
- invl[pid]=ringbuffer_init(1);
- task_add_win(pid,&invl[pid]);
- return 1;
+
+ return compositor_create_window(pid,xy>>16,xy&0xffff,wh>>16,wh&0xffff,flags);
}
/** Generics . prep before we reenable interrupts*/
diff --git a/userspace/Makefile b/userspace/Makefile
index 8d9cf8e..16d67ac 100644
--- a/userspace/Makefile
+++ b/userspace/Makefile
@@ -1,7 +1,8 @@
-IMAGESIZE=80000 #ext2.img size in Kb
#######################
+IMAGESIZE=80000 #ext2.img size in Kb
+
GIT_REVISION=$(shell git rev-parse HEAD)
CC=i686-foolos-gcc
@@ -32,9 +33,14 @@ include ../Makefile.common
all: ext2.img
-ext2.img: $(PROGS)
- make -C fonts
+xterm:
+ @echo "building fool-term"
make -C xterm
+
+
+ext2.img: $(PROGS) xterm
+ make -C xterm
+ make -C fonts
make -C cpp
make -C ncurses
make -C pain
diff --git a/userspace/fsh.c b/userspace/fsh.c
index 17a3942..b81912e 100644
--- a/userspace/fsh.c
+++ b/userspace/fsh.c
@@ -87,7 +87,6 @@ int main(int argc, char **argv)
while(1)
{
- _gui_rect();
char c=fgetc(stdin);
if(c=='\b')
diff --git a/userspace/init.c b/userspace/init.c
index e432ef9..0fb23d2 100644
--- a/userspace/init.c
+++ b/userspace/init.c
@@ -1,46 +1,35 @@
-/** xinit
- *
- * TODO: console version
- *
- * */
-
-#define LAUNCH_COUNT 0
-static char *env1[]={"HOME=/home/miguel","PS1=\033[34m$\033[37m","PWD=/home/miguel","PATH=/bin","TERM=fool-term",0};
+ /*
+ * @file
+ *
+ * This is the FoolOS Init process running on pid=1.
+ *
+ * I just spawns a `fool-term` each time an character arrives
+ * on its '/dev/tty' (controlling terminal of this process)
+ *
+ */
+
+static char *env1[]={"HOME=/home/miguel","PS1=$","PWD=/home/miguel","PATH=/bin","TERM=fool-term",0};
static char *argv1[]={"xterm","/bin/fsh",0};
-/*
-
-char *argv1[][4]={
- {"/bin/xterm","xterm","/bin/fsh",0},
- {"/bin/xterm","xterm","/bin/fsh",0},
- {"/bin/xterm","xterm","/bin/fsh",0},
-};
-*/
-
void fork_and_exec()
{
int pid=fork();
- if(!pid) //child
+
+ if(!pid)
{
+ // execve in child
execve("/bin/xterm",argv1,env1);
}
}
int main(int argc, char **argv)
{
- int pid=fork();
-
- for(int i=0;i<LAUNCH_COUNT;i++)
- {
- fork_and_exec();
- }
-
int tty_fd=_open("/dev/tty");
while(1)
{
char buf[1];
- read(tty_fd,buf,1); //
+ read(tty_fd,buf,1);
fork_and_exec();
}
}
diff --git a/userspace/newcalls.h b/userspace/newcalls.h
deleted file mode 100644
index 177e100..0000000
--- a/userspace/newcalls.h
+++ /dev/null
@@ -1,9 +0,0 @@
-#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/pain/pain1.c b/userspace/pain/pain1.c
index a3fb03a..2c23000 100644
--- a/userspace/pain/pain1.c
+++ b/userspace/pain/pain1.c
@@ -192,7 +192,7 @@ int main(int argc, char **argv)
_gui_win();
read_png_file(argv[1]);
process_file();
- _gui_rect();
+ _gui_inval(0,0,640,480);
while(1);
// write_png_file(argv[2]);
diff --git a/userspace/pain2.c b/userspace/pain2.c
index 3c62463..50dc716 100644
--- a/userspace/pain2.c
+++ b/userspace/pain2.c
@@ -33,14 +33,14 @@ int main(int argc,char **argv)
{
put_rect(0,0,640,480,0xff0000);
put_rect(i,i,100,100,0x0000ff);
- _gui_rect();
+ _gui_inval(0,0,640,400);
}
for(int i=380;i>0;i-=80)
{
put_rect(0,0,640,480,0xff0000);
put_rect(i,i,100,100,0x0000ff);
- _gui_rect();
+ _gui_inval(0,0,640,400);
}
}
diff --git a/userspace/pain3.c b/userspace/pain3.c
index bd1aa8b..7114ada 100644
--- a/userspace/pain3.c
+++ b/userspace/pain3.c
@@ -6,6 +6,7 @@
#define dimx 640
#define dimy 480
+
/*
void doscolor(int color,int color2)
{
@@ -32,14 +33,14 @@ int main(int argc,char **argv)
{
put_rect(0,0,640,480,0xffff00);
put_rect(i,i,100,100,0x00ffff);
- _gui_rect();
+ _gui_inval(0,0,640,480);
}
for(int i=380;i>0;i-=80)
{
put_rect(0,0,640,480,0xffff00);
put_rect(i,i,100,100,0xffffff);
- _gui_rect();
+ _gui_inval(0,0,640,480);
}
}
diff --git a/userspace/xterm/rect.c b/userspace/xterm/rect.c
index 35711f0..57cea62 100644
--- a/userspace/xterm/rect.c
+++ b/userspace/xterm/rect.c
@@ -1,25 +1,29 @@
#include <stdlib.h>
#include <stdio.h>
-#include "../put_pixel.h"
+#include "vesa.h"
extern char**environ;
int main(int argc, char **argv)
{
// we need a window
- _gui_win();
+ _gui_win(0|0,300<<16|300,0);
+ uint8_t *fb=malloc(4*300*300);
// basically loads font and sets a few constants
- vesa_init(NULL);
+ vesa_init(300,300,fb,NULL);
while(1)
{
- int x = rand()%600;
+ int x = rand()%300;
int y = rand()%300;
- int width=10;
- int height=10;
- int col = rand()% 0x00ffff;
- put_rect( x, y, width,height,col);
- _gui_inval((x<<16)|(y),(width<<16)|height);
+ int col = rand()% 0x0000ff;
+
+ int width=1;
+ int height=1;
+
+ //put_rect( x, y, width,height,col);
+ PutPixel(x,y,col|0xff<<24);
+ _gui_inval((x<<16)|(y),(width<<16)|height,fb);
}
}
diff --git a/userspace/xterm/vesa.c b/userspace/xterm/vesa.c
index 6d61498..16c8649 100644
--- a/userspace/xterm/vesa.c
+++ b/userspace/xterm/vesa.c
@@ -4,11 +4,6 @@
#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);
-
-#define VMEM_USER_FRAMEBUFFER 0xf5100000
// framebuffer info
static uint32_t vesaXres;
@@ -34,9 +29,12 @@ static uint8_t termdata[80*24];
static uint8_t termdata_bg[80*24];
static uint8_t termdata_fg[80*24];
+void PutFont(char c, int x,int y, uint32_t color_fg,uint32_t color_bg);
+
// same colors as in screen.h
+/*
static uint32_t cols[] = {
- 0x0, // black
+ 0x0, //black
0x0066cc, //blue
0x009900, //green
0x33ffff, //cyan
@@ -53,6 +51,28 @@ static uint32_t cols[] = {
0xffff00, //yellow
0xffffff, //white
};
+*/
+
+/** solarized theme */
+
+static uint32_t cols[] = {
+ 0x073642, // S_base02
+ 0xdc322f, // S_red
+ 0x859900, // S_green
+ 0xb58900, // S_yellow
+ 0x268bd2, // S_blue
+ 0xd33682, // S_magenta
+ 0x2aa198, // S_cyan
+ 0xeee8d5, // S_base2
+ 0x002b36, // S_base03
+ 0xcb4b16, // S_orange
+ 0x586e75, // S_base01
+ 0x657b83, // S_base00
+ 0x839496, // S_base0
+ 0x6c71c4, // S_violet
+ 0x93a1a1, // S_base1
+ 0xfdf6e3, // S_base3
+};
/** update cursor position */
void vesa_update_cursor(uint32_t col,uint32_t row)
@@ -77,34 +97,13 @@ void vesa_console_put_char(uint8_t c,uint8_t color_bg, uint8_t color_fg, uint32_
if(x==console_x&&y==console_y)PutFont(c, x,y, cols[color_fg],cols[color_bg]);
else PutFont(c, x,y, cols[color_bg],cols[color_fg]);
}
-
- //
- // We want to get output to the screen as fast as possible!
- //
- // Our Fool-Boot-Loader did set up VESA already for us.
- // The desired VESA mode is hardcoded in [boot/mbr.asm].
- //
- // The [vesa_init(...)] function requires:
- //
- // * the addresses of the vbeinfo struct
- // * the address of the vbemodeinfo struct (for selected mode).
- // * Fool Font loaded inside ramimage
- //
- // The first two paramters are hardcoded in [boot/mbr.asm],
- // while the last one is set in the Makefile. The font binary
- // is integrated in the kernel image.
- //
- // this function returns the physical base address of
- // our video memory
- //
-uint32_t vesa_init(char *fontname)
+uint32_t vesa_init(int w,int h, int fb, char *fontname)
{
// LOAD FONT
FILE *f;
- //if(fontname==NULL)f=fopen("/doc/fonts/binfont.bin","r");
- //if(fontname==NULL)f=fopen("/doc/fonts/tinyfont.bin","r");
if(fontname==NULL)f=fopen("/doc/fonts/envypn7x13.bin","r");
+ else f=fopen("fontname","r");
fread(&font_width,1,1,f);
fread(&font_height,1,1,f);
@@ -116,13 +115,12 @@ uint32_t vesa_init(char *fontname)
fread(foolfont,1,alloc_bytes,f);
// virtual screen
- vesaXres=640;
- vesaYres=480;
+ vesaXres=w;
+ vesaYres=h;
- vesaPitch=640*4;
+ vesaPitch=vesaXres*4;
vesaBpp=4; //32bit
- vesaAddr=VMEM_USER_FRAMEBUFFER;
- //
+ vesaAddr=fb;//// TODOVMEM_USER_FRAMEBUFFER;
//
console_x=0;
@@ -135,33 +133,15 @@ uint32_t vesa_init(char *fontname)
return vesaAddr;
}
-
-// TODO: what will happen in 24bit mode?
-// TODO: optimize
-void PutPixel(int x,int y, int color)
+void PutPixel(int x,int y, uint32_t color)
{
- /*
- //do not write memory outside the screen buffer, check parameters against the VBE mode info
- if (x<0 || x>vesaXres|| y<0 || y>vesaYres) return;
- 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_USER_FRAMEBUFFER;
-
- cTemp[x+y] = (uint8_t)(color & 0xff);
- cTemp[x+y+1] = (uint8_t)((color>>8) & 0xff);
- cTemp[x+y+2] = (uint8_t)((color>>16) & 0xff);
- */
-
- uint8_t *p=VMEM_USER_FRAMEBUFFER+y*vesaPitch+x*vesaBpp;
+ uint8_t *p=vesaAddr+y*vesaPitch+x*vesaBpp;
uint32_t *pix=p;
*pix=color;
}
-
static bool check_pixel(int idx,int x,int y)
{
-// x=font_width-x-1;
int pixel_index=idx*font_width*font_height+y*font_width+x;
return foolfont[pixel_index/8]&(1<<(7-(pixel_index%8)));
}
@@ -169,48 +149,32 @@ static bool check_pixel(int idx,int x,int y)
/**
* Put character C in column X of row Y using colors fg and bg
*/
-void PutFont(char c, int x,int y, int color_fg,int color_bg)
+void PutFont(char c, int x,int y, uint32_t color_fg,uint32_t color_bg)
{
+ static uint8_t opac=0xbb;
int fnt;
if(c>=0x20&&c<=0x126)fnt=c-0x20;
else return; // any other fonts??
- //x=x*(1+font_width);
- //y=y*(1+font_height);
x=x*(font_width+1);
y=y*(font_height+1);
//fill broder with bg color
- for(int posx=x;posx<x+font_width+1;posx++)PutPixel(posx,y+font_height,color_bg);
- for(int posy=y;posy<y+font_height;posy++)PutPixel(x+font_width,posy,color_bg);
+ for(int posx=x;posx<x+font_width+1;posx++)PutPixel(posx,y+font_height,color_bg|(opac<<24));
+ for(int posy=y;posy<y+font_height;posy++)PutPixel(x+font_width,posy,color_bg|(opac<<24));
// paint letter
for(int posx=x;posx<x+font_width;posx++)
{
- for(int posy=y;posy<y+font_height;posy++)
- {
- //if(deffont[fnt].line[posy-y]&1<<(7-(posx-x)))
- if(check_pixel(fnt,posx-x,posy-y))PutPixel(posx,posy,color_fg);
- else PutPixel(posx,posy,color_bg);
- }
+ for(int posy=y;posy<y+font_height;posy++)
+ {
+ //if(deffont[fnt].line[posy-y]&1<<(7-(posx-x)))
+ if(check_pixel(fnt,posx-x,posy-y))PutPixel(posx,posy,color_fg|(0xff<<24));
+ else PutPixel(posx,posy,color_bg|(opac<<24));
+ }
}
// invalidate area
- _gui_inval((x<<16)|(y),(font_width+1<<16)|(font_height+1));
+ _gui_inval((x<<16)|(y),(font_width+1<<16)|(font_height+1),vesaAddr);
- /*
- for(int y=0;y<vesaYres;y++)
- {
- PutPixel(0,y,0xff);
- PutPixel(100,y,0xff);
- PutPixel(vesaXres-1,y,0xff);
- }
-
- for(int x=0;x<vesaXres;x++)
- {
- PutPixel(x,0,0xff);
- PutPixel(x,100,0xff);
- PutPixel(x,vesaYres-1,0xff);
- }
- */
}
diff --git a/userspace/xterm/vesa.h b/userspace/xterm/vesa.h
index 16a52f1..ac3257e 100644
--- a/userspace/xterm/vesa.h
+++ b/userspace/xterm/vesa.h
@@ -1,2 +1,3 @@
void vesa_update_cursor(uint32_t col,uint32_t row);
void vesa_console_put_char(uint8_t c,uint8_t color_bg, uint8_t color_fg, uint32_t x, uint32_t y);
+uint32_t vesa_init(int w,int h, int fb, char *fontname);
diff --git a/userspace/xterm/xterm.c b/userspace/xterm/xterm.c
index 90b2fe0..8d3ea97 100644
--- a/userspace/xterm/xterm.c
+++ b/userspace/xterm/xterm.c
@@ -1,27 +1,32 @@
#include <stdlib.h>
#include <stdio.h>
-#include "../put_pixel.h"
+#include "vesa.h"
extern char**environ;
+// TODO quit if execve fails or child exits...
+
//default
char *argv1[]={"xterm","/bin/fsh",0};
int main(int argc, char **argv)
{
- // we need a window
- _gui_win();
+ // we need a 640x336 window for a 80x24 terminal using the
+ // default 7x13 pixel font +1 pixel margin so it is 8x14
+ int w=640;
+ int h=336;
+ _gui_win(0<<16|0,w<<16|h,0);
// basically loads font and sets a few constants
- vesa_init(NULL);
+ void *fb=malloc(w*h*4);
+ // 32bit mode so we have 4bytes per pixel. first one holds alpha
+
+ vesa_init(w,h, fb, 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);
int tty_fd=_open("/dev/tty");
@@ -30,7 +35,6 @@ int main(int argc, char **argv)
if(!pid) // child
{
- //_close(xterm_in[1]);
close(xterm_out[0]);
dup2(tty_fd,0);// stdin
@@ -45,13 +49,8 @@ int main(int argc, char **argv)
while(1);
}
else{
- // TODO quit if execve fails or child exits...
- //_close(xterm_in[0]);
close(xterm_out[1]);
-
- //_dup2(xterm_in[1],0); // compositor writes here.
- //_close(xterm_in[1]);
while(1)
{
diff --git a/video/compositor.c b/video/compositor.c
index 2b67385..e7fd15f 100644
--- a/video/compositor.c
+++ b/video/compositor.c
@@ -1,4 +1,6 @@
+// TODO OPTIMIZE //
#include "compositor.h"
+#include "scheduler.h"
#include "syscalls.h"
#include "kernel.h"
#include "kmalloc.h"
@@ -13,17 +15,24 @@
#include "lib/string/string.h"
#define MAX_WINDOWS 50
+#define MAX_PID 200
#define MAX_ICONS 50
+void load_bmp(uint8_t *dst,char *filename);
+
+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;
// TODO: int16 int32 mixed nonsense !
struct window
{
uint32_t pid;
- ringbuffer *invl;
struct pdirectory *vmem; // retreive from task manager?
+ uint8_t *fb;
int16_t posx;
int16_t posy;
@@ -35,6 +44,7 @@ struct window
bool draw_border;
bool draw_meat;
+ bool on_close;
bool borderless; // never show borders
bool fixed; // can not be moved
@@ -55,12 +65,9 @@ struct icon
};
struct window windows[MAX_WINDOWS];
+struct window *pid_to_win[MAX_PID];
struct icon icons[MAX_ICONS];
-static uint8_t backbuffer [VESA_MAX_WIDTH*VESA_MAX_HEIGHT*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;
@@ -92,6 +99,12 @@ 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;
+static int X_icon_ly=50;
+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! :(
@@ -103,23 +116,25 @@ 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)
+static void put_pixel(uint8_t *dst, int x,int y, uint32_t color,uint16_t pitch,uint8_t depth,bool alpha)
{
- 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...
+ uint8_t *p=dst+y*pitch+x*depth;
+ *p++=color;
+ *p++=color>>8;
+ *p++=color>>16;
+ if(alpha)*p=color>>24;
}
/** retrieves single pixel from src without bound checking */
-static uint32_t get_pixel(uint8_t *src, int x,int y)
+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*vesa_pitch+x*vesa_depth;
- col=(*p++); // waste for 24bit...
- col+=(*p++)<<8; // waste for 24bit...
- col+=(*p)<<16; // waste for 24bit...
+ uint8_t *p=src+y*pitch+x*depth;
+ col=(*p++);
+ col+=(*p++)<<8;
+ col+=(*p++)<<16;
+ if(alpha)col+=(*p)<<24;
return col;
}
@@ -129,13 +144,10 @@ static uint32_t get_pixel(uint8_t *src, int x,int y)
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)
+static void put_pixel_alpha(uint8_t *dst, int x,int y, uint32_t color,uint16_t pitch, uint8_t depth,bool alpha)
{
- // TODO: do not use hardcoded alpha!
-
- uint32_t col=get_pixel(dst,x,y);
+ uint32_t col=get_pixel(dst,x,y,vesa_pitch,vesa_depth,false);
- // TODO: optimize!!
uint8_t dst_b=col&0xff;
uint8_t dst_g=(col&0xff00)>>8;
uint8_t dst_r=(col&0xff0000)>>16;
@@ -149,11 +161,12 @@ static void put_pixel_alpha(uint8_t *dst, int x,int y, uint32_t color)
uint8_t out_g=((src_g*(src_a))>>8)+(((0xff-src_a)*dst_g)>>8);
uint8_t out_b=((src_b*(src_a))>>8)+(((0xff-src_a)*dst_b)>>8);
- put_pixel(dst, x,y,(out_r<<16)+(out_g<<8)+out_b);
+ put_pixel(dst, x,y,(out_r<<16)+(out_g<<8)+out_b,vesa_pitch,vesa_depth,false);
}
-static void cpy_rect(uint8_t *src, uint16_t src_x, uint16_t src_y,
- uint8_t *dst, uint16_t dst_x, uint16_t dst_y,
+// TODO fuck transparancey key. we have alfa now
+static void cpy_rect(uint8_t *src, uint16_t src_pitch, uint16_t src_x, uint16_t src_y,
+ uint8_t *dst, uint16_t dst_pitch, uint16_t dst_x, uint16_t dst_y,
uint16_t width, uint16_t height,
bool bnd_chk, uint8_t mult, uint8_t div,
bool transp,
@@ -163,16 +176,13 @@ static void cpy_rect(uint8_t *src, uint16_t src_x, uint16_t src_y,
for(int x=0;x<width;x++)
for(int y=0;y<height;y++)
{
- uint32_t val=get_pixel(src,src_x+x,src_y+y);
- if(transp&&transp_key==val)continue;
- // 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);
-
+ uint32_t val=get_pixel(src,src_x+x,src_y+y,src_pitch,4,true);//32bit and fuck alfa
+ if(alpha) put_pixel_alpha(dst,dst_x+x,dst_y+y,val,dst_pitch,vesa_depth,false);
+ else put_pixel(dst,dst_x+x,dst_y+y,val,dst_pitch,vesa_depth,false);
}
}
+/*
static void add_icon(char *cmd)
{
strcpy(icons[next_icon].command,cmd);
@@ -189,7 +199,6 @@ static void add_icon(char *cmd)
next_icon++;
}
-
static void put_icon(uint8_t *dst, struct icon *ico)
{
if(ico->active)
@@ -213,6 +222,7 @@ cpy_rect(icon_data,ico->iconx,ico->icony, // from
,true
);
}
+*/
static void put_win(uint8_t *dst, struct window *win)
{
@@ -223,63 +233,91 @@ static void put_win(uint8_t *dst, struct window *win)
mydir=x86_get_page_directory();
x86_set_page_directory(win->vmem);
- uint32_t *user_vmem=VMEM_USER_FRAMEBUFFER;
- // iterate over invalidated rects
- while(ringbuffer_has(win->invl))
- {
- 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)
- {
- /*
- 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;
-
- uint16_t a;
-
- uint32_t col=0xff0000;
- col=user_vmem[userx+usery*640];
- uint8_t src_b=col&0xff;
- uint8_t src_g=(col&0xff00)>>8;
- uint8_t src_r=(col&0xff0000)>>16;
- a=0x44;
-
-
- 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);
+cpy_rect(win->fb,win->width*4,0,0, // from
+ dst,vesa_pitch,win->posx,win->posy, // to
+ win->width,win->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
+ );
- backbuffer[y*vesa_width+x]=(out_r<<16)+(out_g<<8)+out_b;
- */
+int iconx=X_icon_lx;
+int icony=X_icon_ly;
+if(win->on_close)
+{
+ iconx=X_icon_active_lx;
+ icony=X_icon_active_ly;
+}
- put_pixel_alpha(dst,x,y,(user_vmem[userx+usery*640]));
- }
- else
- {
- put_pixel(dst,x,y,(user_vmem[userx+usery*640]));
- }
+cpy_rect(icon_data,vesa_pitch,iconx,icony, // from
+ dst, vesa_pitch,win->posx+win->width-X_icon_width,win->posy, // to
+ X_icon_width,X_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
+ ,true
+ );
- usery++;
- }
- userx++;
- }
- }
+ // iterate over invalidated rects
+
+//// while(ringbuffer_has(win->invl))
+//// {
+//// 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)
+//// {
+//// /*
+//// 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;
+////
+//// uint16_t a;
+////
+//// uint32_t col=0xff0000;
+//// col=user_vmem[userx+usery*640];
+//// uint8_t src_b=col&0xff;
+//// uint8_t src_g=(col&0xff00)>>8;
+//// uint8_t src_r=(col&0xff0000)>>16;
+//// a=0x44;
+////
+////
+//// 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);
+////
+//// 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(dst,x,y,(user_vmem[userx+usery*640]));
+//// }
+////
+//// usery++;
+//// }
+//// userx++;
+//// }
+//// }
//if(win->vmem)
//{
x86_set_page_directory(mydir);
@@ -287,19 +325,20 @@ static void put_win(uint8_t *dst, struct window *win)
//}
//draw boundaries
-
if(option_win_borders&&win->draw_border)
{
- win->draw_border=false;
+ uint32_t border_col=0x002b36;
+ if(win->active)border_col=0xfdfd6e3;
+//TODO win->draw_border=false;
for(uint16_t x=win->posx;x<win->posx+win->width;x++)
{
- put_pixel(dst,x,win->posy,0xffffff); //TOP
- put_pixel(dst,x,win->posy+win->height-1,0xffffff); //BOTTOM
+ put_pixel(dst,x,win->posy,border_col,vesa_pitch,vesa_depth,false); //TOP
+ put_pixel(dst,x,win->posy+win->height-1,border_col,vesa_pitch,vesa_depth,false); //BOTTOM
}
for(uint16_t y=win->posy;y<win->posy+win->height;y++)
{
- put_pixel(dst,win->posx,y,0xffffff); //LEFT
- put_pixel(dst,win->posx+win->width-1,y,0xffffff); //RIGHT
+ put_pixel(dst,win->posx,y,border_col,vesa_pitch,vesa_depth,false); //LEFT
+ put_pixel(dst,win->posx+win->width-1,y,border_col,vesa_pitch,vesa_depth,false); //RIGHT
}
}
@@ -307,16 +346,10 @@ static void put_win(uint8_t *dst, struct window *win)
}
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
+ cpy_rect(wallpaper,vesa_pitch,0,0 , // from
+ dst,vesa_pitch,0,0, // to
+ vesa_width,vesa_height, // icon dimensions
false,
0, 0, // scaling not implemented yet anyway, not sure how to use them :P
false, // transparency color key
@@ -324,9 +357,8 @@ cpy_rect(bgimage,rx,ry, // from
,false
);
- }
}
-static void put_mouse(uint8_t *dst,bool before)
+static void put_mouse(uint8_t *dst)
{
static int last_put_mouse_x=0;
@@ -341,31 +373,17 @@ if(mouse_k&1)
icony=mouse_icon_active_ly;
}
-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
- 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
+cpy_rect(icon_data,vesa_pitch,iconx,icony, // from
+ dst, vesa_pitch,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
+ ,true
);
}
@@ -386,35 +404,9 @@ void compositor_del_window(uint32_t addr)
}
}
-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");
-
- windows[next_window]=windows[0];
-
- windows[0].posx=next_x;
- windows[0].posy=next_y;
-
- next_x+=100;
- next_y+=100;
-
- windows[0].width=640;
- windows[0].height=400;
-
- 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(0,0,0);
-}
// TODO : TEXTMODE FALLBACK!
-void compositor_init(uint16_t width, uint16_t height, uint16_t depth, uint16_t pitch)
+void compositor_init(uint16_t width, uint16_t height,uint16_t depth, uint16_t pitch, uint8_t *fb)
{
bg_invl=ringbuffer_init(3);
@@ -431,13 +423,17 @@ void compositor_init(uint16_t width, uint16_t height, uint16_t depth, uint16_t p
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);
}
@@ -445,19 +441,14 @@ void compositor_wake()
{
skip_render=false;
}
-void compositor_wake2()
-{
- skip_render2=false;
-}
-void compositor_swap_buffers()
+void compositor_paint()
{
- //if(skip_render||skip_render2)return;
- if(skip_render2)return; // force rate
+ if(skip_render)return; // forced max rate
skip_render=true;
- skip_render2=true;
+ //FPS: TODO write to bar!
static frames=0;
static uint64_t last=0;
if(!last)last=timer_get_ms();
@@ -466,33 +457,20 @@ void compositor_swap_buffers()
if(now-last>3000)
{
klog("fps: %d",frames*1000/(now-last));
-
last=now;
frames=0;
}
- static bool first=true;
- 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);
+ // // //
+ put_bg(backbuffer);
for(int i=next_window-1;i>=0;i--)
{
- put_win(VMEM_FRAMEBUFFER,&windows[i]);
- }
-
- for(int i=next_icon-1;i>=0;i--)
- {
- // put_icon(backbuffer,&icons[i]);
+ put_win(backbuffer,&windows[i]);
}
+ put_mouse(backbuffer);
- put_mouse(VMEM_FRAMEBUFFER,false);
-
- // TODO optimize? rects only too?
-// memcpy(VMEM_FRAMEBUFFER,backbuffer,vesa_pitch*vesa_height);
+ memcpy(VMEM_FRAMEBUFFER,backbuffer,vesa_pitch*vesa_height);
}
void compositor_kb_handle(char c)
@@ -543,6 +521,7 @@ void compositor_mouse_handle(int16_t diff_x,int16_t diff_y, uint8_t key)
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)
{
@@ -574,6 +553,7 @@ void compositor_mouse_handle(int16_t diff_x,int16_t diff_y, uint8_t key)
for(int i=0;i<next_window;i++)
{
struct window *w=&windows[i];
+ w->on_close=false;
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)
@@ -618,15 +598,15 @@ void compositor_mouse_handle(int16_t diff_x,int16_t diff_y, uint8_t key)
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);
+/// 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);
}
}
@@ -634,6 +614,7 @@ void compositor_mouse_handle(int16_t diff_x,int16_t diff_y, uint8_t key)
w->active=true;
active_win=true;
active=i;
+ if(mouse_x>w->posx+w->width-X_icon_width&&mouse_y<w->posy+X_icon_height)w->on_close=true;
}
else
{
@@ -647,8 +628,12 @@ void compositor_mouse_handle(int16_t diff_x,int16_t diff_y, uint8_t key)
{
struct window temp;
temp=windows[active];
+
windows[active]=windows[0];
+ pid_to_win[windows[0].pid]=&windows[active];
+
windows[0]=temp;
+ pid_to_win[windows[0].pid]=&windows[0];
}
lastkey=key;
@@ -658,7 +643,6 @@ void compositor_mouse_handle(int16_t diff_x,int16_t diff_y, uint8_t key)
/** THIS CAN LOAD WINDOWS ARGB BITMAPS WITH BITMAPINFOHEADER */
void load_bmp(uint8_t *dst,char *filename)
{
-
klog("loading bitmap %s",filename);
fd dat=mount_file_open(filename);
char B=fd_read(&dat); // 0x0
@@ -676,7 +660,7 @@ void load_bmp(uint8_t *dst,char *filename)
fd_read(&dat);
uint32_t off=(fd_read(&dat))+(fd_read(&dat)<<8)+(fd_read(&dat)<<16)+(fd_read(&dat)<<24); //0x0a
- //klog("offset = 0x%08X",off);
+ klog("offset = 0x%08X",off);
// skip next 4 bytes
fd_read(&dat);
@@ -688,72 +672,77 @@ void load_bmp(uint8_t *dst,char *filename)
uint32_t h=(fd_read(&dat))+(fd_read(&dat)<<8)+(fd_read(&dat)<<16)+(fd_read(&dat)<<24); //0x16
klog("width=%d,height=%d",w,h);
- for(int i=0;i<off-0xa;i++)fd_read(&dat); // skip to data
+ for(int i=0;i<off-0x1a;i++)fd_read(&dat); // skip to data
// read the image from left to right line by line
for(int y=0;y<h;y++)
for(int x=0;x<w;x++)
{
{
- uint32_t val=(fd_read(&dat)<<24)+(fd_read(&dat)<<16)+(fd_read(&dat)<<8)+(fd_read(&dat));
+ uint32_t val=(fd_read(&dat)<<24)+(fd_read(&dat))+(fd_read(&dat)<<8)+(fd_read(&dat)<<16);
+// klog("0x%08x",val);
if(x>=vesa_width)continue;
- if(y>=vesa_height)continue;
- put_pixel_alpha(dst,x,y,val);
+ if(h-y-1>=vesa_height)continue;
+ put_pixel(dst,x,h-y-1,val,vesa_pitch,4,true);
}
}
}
-// load background image or generate one if (param == 0)
-void compositor_set_background(char *ppm_raw_filename)
+
+void compositor_invalidate(uint32_t pid,uint16_t x, uint16_t y, uint16_t w, uint16_t h,uint32_t *fb)
{
- // TODO: think about funny things to do with timer and update
- // some generated / or modified bg regularly //
- // uint64_t t=timer_get_ms()/333; //
- klog("loading theme...");
- fd bg=mount_file_open(ppm_raw_filename);
+ 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);
+}
- uint32_t i=0;
+int compositor_create_window(uint32_t pid,uint16_t x, uint16_t y,uint16_t w,uint16_t h,uint16_t flags)
+{
+ klog("pid %d creating %dx%d win at %d %d with flags 0x%02x",pid,w,h,x,y,flags);
+ if (next_window>=MAX_WINDOWS)kpanic("max number of windows reached. increase MAX_WINDOWS");
- // read the image from left to right line by line
- for(int y=0;y<1080;y++)
- for(int x=0;x<1920;x++)
+ windows[next_window]=windows[0];
+ pid_to_win[windows[0].pid]=&windows[next_window];
+
+ // auto position
+ if(x==0xffff)
{
- {
- 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(icon_data,x,y,val);
- put_pixel(bgimage,x,y,val);
- i++;
- }
+ next_x+=100;
+ next_y+=100;
+ windows[0].posx=next_x;
+ windows[0].posy=next_y;
+ }
+ else
+ {
+ windows[0].posx=x;
+ windows[0].posy=y;
}
- klog("finished");
+ windows[0].width=w;
+ windows[0].height=h;
- // generating simple background...
- int center_x=vesa_width/2;
- int center_y=vesa_height/2;
- int max_dist = center_x*center_x+center_y*center_y;
+ windows[0].active=0;
- for(int x=0;x<vesa_width;x++)
- {
- 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;
- val = 0xaa*dist/max_dist;
- }
- else val=0x0;
- //val=0x002b36;
+ windows[0].fb=0;
+ windows[0].vmem=scheduler_get_vmem(pid);
+ windows[0].pid=pid;
-// put_pixel(bgimage,x,y,val);
- }
- }
+ windows[0].draw_border=true;
+ windows[0].draw_meat=true;
+
+ windows[0].on_close=false;
+ windows[0].borderless=flags&1;
+ windows[0].fixed=flags&2;
- load_bmp(bgimage,"/home/miguel/skin.bmp");
+ pid_to_win[windows[0].pid]=&windows[0];
+
+ next_window++;
+ compositor_mouse_handle(0,0,0);
+
+ return 0;// ok
+}
+
+void compositor_destroy_window(uint32_t pid)
+{
+ klog("destroying win for pid %d",pid);
}
diff --git a/video/compositor.h b/video/compositor.h
index e3204a6..334dfa3 100644
--- a/video/compositor.h
+++ b/video/compositor.h
@@ -1,21 +1,81 @@
#include <stdint.h>
-#include "ringbuffer.h"
/**
* @file
*
- * Super Light composting window manager for Fool 0S.
+ * Super Light compositing window manager for Fool 0S.
* Can be run directly on a 32bit or 24bit Framebuffer.
*
+ * pid needed to get vmem directory of process for some calls.
+ * only pne window per pid allowed by now.
*
+ * Internals:
+ *
+ * framebuffer
+ * backbuffer - same format as framebuffer.
+ *
+ * icons and user-land buffers use ARGB.
+ * bitmaps loaded use ARGB.
+ *
+ * TODO: /dev/mouse
+ *
+ * Threads
+ * -------
+ * In general it should be accessed only by one gui thread anyway.
+ */
+
+/**
+ * Initialization of our window manager
+ * some obvious params and the address of the framebuffer.
+ */
+void compositor_init(uint16_t width, uint16_t height,uint16_t bpp, uint16_t pitch, uint8_t *fb);
+
+/**
+ * THE HEAVY WORK
+ *
+ * You can call this any time you want.
+ * It will have no effect unless there
+ * was a call to compositor_wake() before.
*/
+void compositor_paint();
+/**
+ * Call this at e.g. at 60HZ. To force a max refresh rate for
+ * compositor_paint(). Additonal calls to compositor_paint() will
+ * be jus skipped.
+ *
+ * This function just sets one variable so it can be caled
+ * from a interrupt handler (e.g. APIC Timer)
+ */
void compositor_wake();
-void compositor_wake2();
-void compositor_init(uint16_t width, uint16_t height,uint16_t bpp, uint16_t pitch);
-void compositor_set_background(char *ppm_raw_filename);
-void compositor_swap_buffers();
+
+/**
+ * Invalidates an area of the screen. so it will be repainted on the
+ * upcoming frame. can set the address of the user framebuffer
+ * (if changed since last call).
+ */
+void compositor_invalidate(uint32_t pid,uint16_t x, uint16_t y, uint16_t w, uint16_t h,uint32_t *fb);
+
+/**
+ * Window Create
+ *
+ * flag 1 - no decoration
+ * flag 2 - fixed (can not be moved and always in foreground)
+ */
+int compositor_create_window(uint32_t pid,uint16_t x, uint16_t y,uint16_t w,uint16_t h,uint16_t flags);
+
+/**
+ * Window Destroy
+ */
+void compositor_destroy_window(uint32_t pid);
+
+/**
+ * user input mouse
+ */
void compositor_mouse_handle(int16_t x,int16_t y, uint8_t key);
+
+/**
+ * user input keyboard
+ */
void compositor_kb_handle(char c);
-void compositor_add_window(uint32_t addr,uint32_t pid,ringbuffer *);
-void compositor_del_window(uint32_t addr);
+
diff --git a/driver/vesa.c b/xxx/vesa.c
index bd5c53d..bd5c53d 100644
--- a/driver/vesa.c
+++ b/xxx/vesa.c
diff --git a/driver/vesa.h b/xxx/vesa.h
index 63fbd55..63fbd55 100644
--- a/driver/vesa.h
+++ b/xxx/vesa.h