diff options
| author | Miguel <m.i@gmx.at> | 2018-10-19 02:41:53 +0200 |
|---|---|---|
| committer | Miguel <m.i@gmx.at> | 2018-10-19 02:41:53 +0200 |
| commit | 45ce8728224caa44d31dca3117992b193fa3cd98 (patch) | |
| tree | 8d37cfe273e9feeb8376b6205abe29c995e40ac2 | |
| parent | 9bfd9fb6a7c568b56a5ef525a2b76351780bae66 (diff) | |
window manager continued
| -rw-r--r-- | README.md | 2 | ||||
| -rw-r--r-- | driver/mouse.c | 1 | ||||
| -rw-r--r-- | fs/stdstreams.c | 5 | ||||
| -rw-r--r-- | interface/syscalls.c | 54 | ||||
| -rw-r--r-- | interface/syscalls.h | 34 | ||||
| -rw-r--r-- | kernel/interrupts.c | 2 | ||||
| -rw-r--r-- | kernel/kernel.c | 5 | ||||
| -rw-r--r-- | kernel/scheduler.c | 13 | ||||
| -rw-r--r-- | kernel/scheduler.h | 1 | ||||
| -rw-r--r-- | kernel/smp.c | 1 | ||||
| -rw-r--r-- | kernel/syscalls.c | 39 | ||||
| -rw-r--r-- | userspace/Makefile | 12 | ||||
| -rw-r--r-- | userspace/fsh.c | 1 | ||||
| -rw-r--r-- | userspace/init.c | 41 | ||||
| -rw-r--r-- | userspace/newcalls.h | 9 | ||||
| -rw-r--r-- | userspace/pain/pain1.c | 2 | ||||
| -rw-r--r-- | userspace/pain2.c | 4 | ||||
| -rw-r--r-- | userspace/pain3.c | 5 | ||||
| -rw-r--r-- | userspace/xterm/rect.c | 22 | ||||
| -rw-r--r-- | userspace/xterm/vesa.c | 126 | ||||
| -rw-r--r-- | userspace/xterm/vesa.h | 1 | ||||
| -rw-r--r-- | userspace/xterm/xterm.c | 25 | ||||
| -rw-r--r-- | video/compositor.c | 445 | ||||
| -rw-r--r-- | video/compositor.h | 76 | ||||
| -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
@@ -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 |
