diff options
| -rw-r--r-- | README.md | 22 | ||||
| -rw-r--r-- | driver/keyboard.c | 1 | ||||
| -rw-r--r-- | driver/mouse.c | 97 | ||||
| -rw-r--r-- | grubiso/boot/grub/grub.cfg | 83 | ||||
| -rw-r--r-- | grubiso/boot/grub_bg.png | bin | 0 -> 470776 bytes | |||
| -rw-r--r-- | kernel/kernel.c | 6 | ||||
| -rw-r--r-- | kernel/kernel.h | 2 | ||||
| -rw-r--r-- | userspace/Makefile | 3 | ||||
| -rw-r--r-- | userspace/files/icons.ppm | bin | 0 -> 6220801 bytes | |||
| -rw-r--r-- | userspace/pain/Makefile | 6 | ||||
| -rw-r--r-- | userspace/pain/pain1.c | 200 | ||||
| -rw-r--r-- | userspace/pain1.c | 48 | ||||
| -rw-r--r-- | userspace/put_pixel.h | 2 | ||||
| -rw-r--r-- | video/compositor.c | 306 | ||||
| -rw-r--r-- | video/compositor.h | 4 |
15 files changed, 525 insertions, 255 deletions
@@ -89,6 +89,8 @@ FoolOS was/is tested/developed on the following emulators/machines Todos ----- +port as secondary user.. ? zlib libpng + https://wiki.osdev.org/Text_Mode_Cursor cnrom civis term pipes! schedulig! DMA! splice (2) @@ -124,7 +126,7 @@ mesa3d, quake,doom, netwookring tcp/ip * EXTRA: switch to DMA where possible!? * EXTRA: Unit Testing -* EXTRA: GUI / Window Manager (update\_rect, etc..) / double buffering / physical, virtual sizE? virtio ? / Cairo library +* EXTRA: GUI / Window Manager (update\_rect, etc..) / double buffering / physical, virtual sizE? virtio ? / Cairo library/ xvfb? /forum.osdev.org/viewtopic.php?t=10018&p=64358 / vsync * EXTRA: qemu tcg , slower other cpus * EXTRA: Crazy & Funny terminal effects while typing (idea) @@ -156,6 +158,8 @@ mesa3d, quake,doom, netwookring tcp/ip 3.Porting Software =================== + I get sources via: apt-get source zlib , etc.. + * ref: Cross Porting Software * ncurses: ../ncurses-6.1/configure --host=i686-foolos --without-tests @@ -172,10 +176,26 @@ mesa3d, quake,doom, netwookring tcp/ip set CFLAGS="-ggdb -O0" to get debug symbols + * zlib-1.2.8 (via apt-get) + CC=i686-foolos-gcc ./configure --prefix=/usr + + * libpng1.6-1.6.28 (via apt-get) + + inside the dir: + + 1) add -foolos* to config.sub + 2) ./configure --prefix=/usr --host=i686-foolos + 3) make + 4) make DESTDIR=/home/miguel/temp/foolos/ install + + Content ======= Third party software and content used some of which is: +(I have likely forgotten most of credit) + +grub newlib ncurses diff --git a/driver/keyboard.c b/driver/keyboard.c index da8fe54..2141622 100644 --- a/driver/keyboard.c +++ b/driver/keyboard.c @@ -26,6 +26,7 @@ int hex_to_dec(char c) return c+10-'a'; } +// TODO: dynamic static void put(uint8_t c) { compositor_kb_handle(c); diff --git a/driver/mouse.c b/driver/mouse.c index c0e71d5..14782f7 100644 --- a/driver/mouse.c +++ b/driver/mouse.c @@ -1,3 +1,6 @@ +//https://wiki.osdev.org/PS/2_Mouse +//TODO: ignore last packet for 4 packets mouse? + #include <stdint.h> #include "mouse.h" @@ -12,16 +15,24 @@ static volatile uint8_t mouse_cycle; static volatile uint8_t mouse_byte[3]; -static volatile int16_t mouse_x; -static volatile int16_t mouse_y; +// data stream coming from the mouse will be waiting inside this buffer static ringbuffer mouse_in; +// called on each interrupt (keep it small) +// just pushes mouse data into the buffer +uint32_t mouse_interrupt(uint32_t esp) +{ + if(!ringbuffer_put(&mouse_in,x86_inb(0x60)))kpanic("full"); + return esp; +} + +// process data in buffer (return true if anything was processed) bool mouse_worker() { if(ringbuffer_full(&mouse_in)) { - klog("mouse buffer full"); + kpanic("mouse buffer full"); // heavy debugging } bool wake=false; @@ -32,7 +43,7 @@ bool mouse_worker() return wake; } - +// void mouse_wait(uint8_t a_type) //unsigned char { uint32_t _time_out=100000; //unsigned int @@ -79,11 +90,6 @@ static void mouse_write(uint8_t a_write) x86_outb(0x60, a_write); } -uint32_t mouse_interrupt(uint32_t esp) -{ - if(!ringbuffer_put(&mouse_in,x86_inb(0x60)))kpanic("full"); - return esp; -} void mouse_init() { @@ -117,44 +123,45 @@ void mouse_init() interrupt_register(INTERRUPT_MOUSE,&mouse_interrupt); } -// called as we filled the 3 bytes, everytime. +// called every time after the 3 bytes have been filled. void mouse_action() { - //klog("mouse %02x / %02x / %02x ",mouse_byte[0], mouse_byte[1],mouse_byte[2]); - //TODO: ignore last packet for 4packets mouse and resync if you get out of sync - - if(mouse_byte[0]&0x80||mouse_byte[0]&0x40) + /* 3rd byte bits have this meaning: + * + * key 0 left button 1 + * key 1 right button 2 + * key 2 middle button 4 + * key 3 always one! 8 + * + * key 4 x-axis sign bit 16 + * key 5 y-axis sign bit 32 + * + * key 6 x-axis overflow 64 + * key 7 y-axis overflow 128 + */ + + int rel_x=0; + int rel_y=0; + + /* ignore overflows? or assume max? */ + + if(mouse_byte[0]&0x80) { - // klog("mouse overflow, skipping packet"); - return; //skip packet on overflow + return; + // klog("x overflow"); } - //OOOMG!!// - if(mouse_byte[1]>127){ - mouse_x-=256; - mouse_x+=mouse_byte[1]; - } - else + if(mouse_byte[0]&0x40) { - mouse_x+=mouse_byte[1]; + return; + // klog("y overflow"); } - if(mouse_byte[2]>127){ - mouse_y-=256; - mouse_y+=mouse_byte[2]; - } - else - { - mouse_y+=mouse_byte[2]; - } + rel_x = mouse_byte[1] - ((mouse_byte[0] << 4) & 0x100); + rel_y = mouse_byte[2] - ((mouse_byte[0] << 3) & 0x100); - if(mouse_x<0)mouse_x=0; - if(mouse_y<0)mouse_y=0; - - if(mouse_x>=1920)mouse_x=1920-1; - if(mouse_y>=1080)mouse_y=1080-1; - - compositor_mouse_handle(mouse_x,1080-mouse_y-1, mouse_byte[0]); + // we pass the state through + compositor_mouse_handle(rel_x,-rel_y,mouse_byte[0]); } void mouse_handler(uint8_t byte)//struct regs *a_r) //struct regs *a_r (not used but just there) @@ -166,12 +173,14 @@ void mouse_handler(uint8_t byte)//struct regs *a_r) //struct regs *a_r (not used case 0: mouse_byte[0]=byte; mouse_cycle++; - if(!(mouse_byte[0]&0x8)) - { - //klog("mouse out of sync, try resync"); - mouse_cycle--; - // kpanic("mouse packets out of sync!?"); // this bit is always 1, otherwise panic! - } + + // this bit is ALWAYS one, otherwise we are out of sync! + if(!(mouse_byte[0]&0x8)) + { +// klog("mouse out of sync (try next packet) ..."); + mouse_cycle--; + } + break; case 1: mouse_byte[1]=byte; diff --git a/grubiso/boot/grub/grub.cfg b/grubiso/boot/grub/grub.cfg index ad49f88..5c27c9e 100644 --- a/grubiso/boot/grub/grub.cfg +++ b/grubiso/boot/grub/grub.cfg @@ -1,4 +1,5 @@ -set timeout=0 //seconds +set timeout=1 //seconds +set default=4 if loadfont ${prefix}/fonts/unicode.pf2 @@ -6,19 +7,28 @@ insmod efi_gop insmod efi_uga insmod vbe insmod font - +insmod png then insmod gfxterm - #set gfxmode=auto + set gfxmode=auto set gfxmode=640x480 set gfxpayload=keep terminal_output gfxterm + background_image /boot/grub_bg.png + set color_normal=white/black + set color_highlight=black/white fi -menuentry "FoolOS (1920x1080x32)" { +menuentry "FoolOS (320x200x32)" { multiboot /boot/foolos.bin - set gfxpayload=1920x1080x32 + set gfxpayload=320x200x32 + module /boot/ext2.img +} + +menuentry "FoolOS (640x400x32)" { + multiboot /boot/foolos.bin + set gfxpayload=640x400x32 module /boot/ext2.img } @@ -28,26 +38,75 @@ menuentry "FoolOS (640x480x32)" { module /boot/ext2.img } -menuentry "FoolOS (textmode)" { +menuentry "FoolOS (800x600x32)" { multiboot /boot/foolos.bin - set gfxpayload=text + set gfxpayload=800x600x32 + module /boot/ext2.img +} + +menuentry "FoolOS (1024x768x32)" { + multiboot /boot/foolos.bin + set gfxpayload=1024x768x32 + module /boot/ext2.img +} + +menuentry "FoolOS (1280x1024x32)" { + multiboot /boot/foolos.bin + set gfxpayload=1280x1024x32 module /boot/ext2.img } -menuentry "FoolOS (2560x1600x32)" { +menuentry "FoolOS (1600x1200x32)" { multiboot /boot/foolos.bin - set gfxpayload=2560x1600x32 + set gfxpayload=1600x1200x32 module /boot/ext2.img } -menuentry "FoolOS (no gfxpayload)" { +menuentry "FoolOS (1280x768x32)" { multiboot /boot/foolos.bin + set gfxpayload=1280x768x32 module /boot/ext2.img } -menuentry "FoolOS (gfxpayload=keep)" { +menuentry "FoolOS (1280x800x32)" { multiboot /boot/foolos.bin - set gfxpayload=keep + set gfxpayload=1280x800x32 + module /boot/ext2.img +} + +menuentry "FoolOS (1400x1050x32)" { + multiboot /boot/foolos.bin + set gfxpayload=1400x1050x32 + module /boot/ext2.img +} + +menuentry "FoolOS (1680x1050x32)" { + multiboot /boot/foolos.bin + set gfxpayload=1680x1050x32 + module /boot/ext2.img +} + +menuentry "FoolOS (1280x720x32)" { + multiboot /boot/foolos.bin + set gfxpayload=1280x720x32 + module /boot/ext2.img +} + +menuentry "FoolOS (1920x1080x32)" { + multiboot /boot/foolos.bin + set gfxpayload=1920x1080x32 + module /boot/ext2.img +} + +menuentry "FoolOS (1920x1080x24)" { + multiboot /boot/foolos.bin + set gfxpayload=1920x1080x24 + module /boot/ext2.img +} + +menuentry "FoolOS (text-mode)" { + multiboot /boot/foolos.bin + set gfxpayload=text module /boot/ext2.img } diff --git a/grubiso/boot/grub_bg.png b/grubiso/boot/grub_bg.png Binary files differnew file mode 100644 index 0000000..a5dce39 --- /dev/null +++ b/grubiso/boot/grub_bg.png diff --git a/kernel/kernel.c b/kernel/kernel.c index a34be42..31f169b 100644 --- a/kernel/kernel.c +++ b/kernel/kernel.c @@ -146,9 +146,9 @@ 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_pitch); - compositor_set_background("/home/miguel/bg.ppm"); - //compositor_set_background(0); + 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"); // -- KB DRIVER -- // klog("Keyboard init ..."); diff --git a/kernel/kernel.h b/kernel/kernel.h index cf21c60..0194ef3 100644 --- a/kernel/kernel.h +++ b/kernel/kernel.h @@ -32,7 +32,7 @@ REFERENCES //#define LOG_SYSCALLS #define HIDE_FIXME -#define FOOLOS_APIC_FREQ 15 // how many apic ticks per second +#define FOOLOS_APIC_FREQ 25 // how many apic ticks per second #define MAX_MOUNTS 10 diff --git a/userspace/Makefile b/userspace/Makefile index 8e3518f..860478a 100644 --- a/userspace/Makefile +++ b/userspace/Makefile @@ -37,6 +37,7 @@ ext2.img: $(PROGS) make -C xterm make -C cpp make -C ncurses + make -C pain @echo "----------------------" @echo "Creating ext2.img ...." @dd if=/dev/zero of=ext2.img bs=1024 count=$(IMAGESIZE) @@ -68,6 +69,7 @@ ext2.img: $(PROGS) @cp xterm/xterm mnt/bin @cp cpp/testcpp mnt/bin @cp ncurses/nc mnt/bin + @cp pain/pain1 mnt/bin # @cp /home/miguel/temp/foolos/usr/bin/* mnt/bin @cp /home/miguel/temp/foolos/usr/bin/worm mnt/bin @cp /home/miguel/temp/foolos/usr/bin/xmas mnt/bin @@ -104,6 +106,7 @@ clean: make -C xterm clean make -C cpp clean make -C ncurses clean + make -C pain clean @echo "Cleaning userspace ..."; rm -f *.o $(PROGS) ext2.img *.d umount: diff --git a/userspace/files/icons.ppm b/userspace/files/icons.ppm Binary files differnew file mode 100644 index 0000000..45ce414 --- /dev/null +++ b/userspace/files/icons.ppm diff --git a/userspace/pain/Makefile b/userspace/pain/Makefile new file mode 100644 index 0000000..bfa31c8 --- /dev/null +++ b/userspace/pain/Makefile @@ -0,0 +1,6 @@ +CC=i686-foolos-gcc + +pain1 : pain1.c + i686-foolos-gcc pain1.c -lpng -lz -o pain1 +clean: + -rm pain1 diff --git a/userspace/pain/pain1.c b/userspace/pain/pain1.c new file mode 100644 index 0000000..a3fb03a --- /dev/null +++ b/userspace/pain/pain1.c @@ -0,0 +1,200 @@ +// http://zarb.org/~gc/html/libpng.html + +#include "../put_pixel.h" + +#include <stdlib.h> +#include <stdio.h> + +#define dimx 640 +#define dimy 480 + +/* + * Copyright 2002-2010 Guillaume Cottenceau. + * + * This software may be freely redistributed under the terms + * of the X11 license. + * + */ + +#include <unistd.h> +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <stdarg.h> + +#define PNG_DEBUG 3 +#include <png.h> + +void abort_(const char * s, ...) +{ + va_list args; + va_start(args, s); + vfprintf(stderr, s, args); + fprintf(stderr, "\n"); + va_end(args); + abort(); +} + +int x, y; + +int width, height; +png_byte color_type; +png_byte bit_depth; + +png_structp png_ptr; +png_infop info_ptr; +int number_of_passes; +png_bytep * row_pointers; + +void read_png_file(char* file_name) +{ + char header[8]; // 8 is the maximum size that can be checked + + /* open file and test for it being a png */ + FILE *fp = fopen(file_name, "rb"); + if (!fp) + abort_("[read_png_file] File %s could not be opened for reading", file_name); + fread(header, 1, 8, fp); + if (png_sig_cmp(header, 0, 8)) + abort_("[read_png_file] File %s is not recognized as a PNG file", file_name); + + + /* initialize stuff */ + png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); + + if (!png_ptr) + abort_("[read_png_file] png_create_read_struct failed"); + + info_ptr = png_create_info_struct(png_ptr); + if (!info_ptr) + abort_("[read_png_file] png_create_info_struct failed"); + + if (setjmp(png_jmpbuf(png_ptr))) + abort_("[read_png_file] Error during init_io"); + + png_init_io(png_ptr, fp); + png_set_sig_bytes(png_ptr, 8); + + png_read_info(png_ptr, info_ptr); + + width = png_get_image_width(png_ptr, info_ptr); + height = png_get_image_height(png_ptr, info_ptr); + color_type = png_get_color_type(png_ptr, info_ptr); + bit_depth = png_get_bit_depth(png_ptr, info_ptr); + + number_of_passes = png_set_interlace_handling(png_ptr); + png_read_update_info(png_ptr, info_ptr); + + + /* read file */ + if (setjmp(png_jmpbuf(png_ptr))) + abort_("[read_png_file] Error during read_image"); + + row_pointers = (png_bytep*) malloc(sizeof(png_bytep) * height); + for (y=0; y<height; y++) + row_pointers[y] = (png_byte*) malloc(png_get_rowbytes(png_ptr,info_ptr)); + + png_read_image(png_ptr, row_pointers); + + fclose(fp); +} + + +void write_png_file(char* file_name) +{ + /* create file */ + FILE *fp = fopen(file_name, "wb"); + if (!fp) + abort_("[write_png_file] File %s could not be opened for writing", file_name); + + + /* initialize stuff */ + png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); + + if (!png_ptr) + abort_("[write_png_file] png_create_write_struct failed"); + + info_ptr = png_create_info_struct(png_ptr); + if (!info_ptr) + abort_("[write_png_file] png_create_info_struct failed"); + + if (setjmp(png_jmpbuf(png_ptr))) + abort_("[write_png_file] Error during init_io"); + + png_init_io(png_ptr, fp); + + + /* write header */ + if (setjmp(png_jmpbuf(png_ptr))) + abort_("[write_png_file] Error during writing header"); + + png_set_IHDR(png_ptr, info_ptr, width, height, + bit_depth, color_type, PNG_INTERLACE_NONE, + PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); + + png_write_info(png_ptr, info_ptr); + + + /* write bytes */ + if (setjmp(png_jmpbuf(png_ptr))) + abort_("[write_png_file] Error during writing bytes"); + + png_write_image(png_ptr, row_pointers); + + + /* end write */ + if (setjmp(png_jmpbuf(png_ptr))) + abort_("[write_png_file] Error during end of write"); + + png_write_end(png_ptr, NULL); + + /* cleanup heap allocation */ + for (y=0; y<height; y++) + free(row_pointers[y]); + free(row_pointers); + + fclose(fp); +} + + +void process_file(void) +{ + if (png_get_color_type(png_ptr, info_ptr) == PNG_COLOR_TYPE_RGB) + abort_("[process_file] input file is PNG_COLOR_TYPE_RGB but must be PNG_COLOR_TYPE_RGBA " + "(lacks the alpha channel)"); + + if (png_get_color_type(png_ptr, info_ptr) != PNG_COLOR_TYPE_RGBA) + abort_("[process_file] color_type of input file must be PNG_COLOR_TYPE_RGBA (%d) (is %d)", + PNG_COLOR_TYPE_RGBA, png_get_color_type(png_ptr, info_ptr)); + + for (y=0; y<height; y++) { + png_byte* row = row_pointers[y]; + for (x=0; x<width; x++) { + png_byte* ptr = &(row[x*4]); + //printf("Pixel at position [ %d - %d ] has RGBA values: %d - %d - %d - %d\n", + // x, y, ptr[0], ptr[1], ptr[2], ptr[3]); + + /* set red value to 0 and green value to the blue one */ + //ptr[0] = 0; + //ptr[1] = ptr[2]; + if(x<dimx&&y<dimy)put_pixel(x,y,ptr[2]|ptr[1]<<8|ptr[0]<<16); + + } + } +} + + +int main(int argc, char **argv) +{ + if (argc != 2) + abort_("Usage: program_name <file_in>"); + + _gui_win(); + read_png_file(argv[1]); + process_file(); + _gui_rect(); + while(1); +// write_png_file(argv[2]); + + return 0; +} diff --git a/userspace/pain1.c b/userspace/pain1.c deleted file mode 100644 index ddceaa5..0000000 --- a/userspace/pain1.c +++ /dev/null @@ -1,48 +0,0 @@ -#include "put_pixel.h" - -#include <stdlib.h> -#include <stdio.h> - -#define dimx 640 -#define dimy 480 - -/* -void doscolor(int color,int color2) -{ - int i=0; - - for (int y = 0; y < dimy; y++) - for (int x = 0; x < dimx; x++) - { - { - if(x%2&&y%2)put_pixel(x,y,color); - else put_pixel(x,y,color2); - } - } -} -*/ - -int main(int argc,char **argv) -{ - _gui_win(); - - for(int i=0;i<2000;i++) - { - for(int i=0;i<380;i+=40) - { - put_rect(0,0,640,480,0x0000ff); - put_rect(640-i,i,100,100,0xff00ff); - _gui_rect(); - } - - for(int i=380;i>0;i-=80) - { - put_rect(0,0,640,480,0x0000ff); - put_rect(640-i,i,100,100,0x00ffff); - _gui_rect(); - } - } - - return EXIT_SUCCESS; -} - diff --git a/userspace/put_pixel.h b/userspace/put_pixel.h index 936026f..563a7e8 100644 --- a/userspace/put_pixel.h +++ b/userspace/put_pixel.h @@ -1,6 +1,6 @@ #include <stdint.h> -#define VESA_FRAMEBUFFER 0xfc000000 +#define VESA_FRAMEBUFFER 0xf5100000 #define VESA_PITCH 2560 #define VESA_BPP 4 diff --git a/video/compositor.c b/video/compositor.c index 645900e..64c9689 100644 --- a/video/compositor.c +++ b/video/compositor.c @@ -1,5 +1,4 @@ #include "compositor.h" - #include "syscalls.h" #include "kernel.h" #include "kmalloc.h" @@ -15,119 +14,147 @@ #define MAX_WINDOWS 100 -static uint32_t backbuffer[VESA_MAX_WIDTH*VESA_MAX_HEIGHT]; -static uint32_t bgimage[VESA_MAX_WIDTH*VESA_MAX_HEIGHT]; -static uint32_t *vmem=VMEM_FRAMEBUFFER; - struct window { - int16_t posx; - int16_t posy; + uint32_t pid; + struct pdirectory *vmem; + + int16_t posx; + int16_t posy; uint16_t width; uint16_t height; + uint32_t color; uint16_t active; - uint32_t pid; - struct pdirectory *vmem; }; struct window windows[MAX_WINDOWS]; -static uint32_t display_width=1920; -static uint32_t display_height=1080; +static uint8_t backbuffer [VESA_MAX_WIDTH*VESA_MAX_HEIGHT*4]; +static uint8_t icons [1920*1080*4]; static uint16_t next_window=0; static uint16_t next_x=50; static uint16_t next_y=50; +static uint32_t *vmem=VMEM_FRAMEBUFFER; + static uint16_t vesa_width; static uint16_t vesa_height; +static uint16_t vesa_depth; static uint16_t vesa_pitch; -static uint16_t mouse_x=100; -static uint16_t mouse_y=100; -static uint16_t mouse_k; +// initial mouse state +static int mouse_x=100; +static int mouse_y=100; + +static int last_mouse_x; +static int last_mouse_y; + +static uint16_t mouse_k=0; + +// icon +static int mouse_icon_width=25; +static int mouse_icon_height=25; +static int mouse_icon_lx=0; +static int mouse_icon_ly=0; +static int mouse_icon_active_lx=25; +static int mouse_icon_active_ly=0; + +// costly but beautiful +static bool option_blending=false; // so disable ! :P +// ugly and cheap +static bool option_win_borders=true; // so enable static bool skip_render; static bool skip_render2; -static void put_pixel(int x,int y, uint32_t color) +/** print single pixel to dst without bound checking */ +static void put_pixel(uint8_t *dst, int x,int y, uint32_t color) { - vmem[y*vesa_width+x]=color; + uint32_t *p=dst+y*vesa_pitch+x*vesa_depth; + *p=color; +} + +/** retrieves single pixel from src without bound checking */ +static uint32_t get_pixel(uint8_t *src, int x,int y) +{ + uint32_t *p=src+y*vesa_pitch+x*vesa_depth; + return *p; +} + +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, + uint16_t width, uint16_t height, + bool bnd_chk, uint8_t mult, uint8_t div, + bool transp, + uint32_t transp_key + + ) + +{ + // TODO optimize! + 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 : just simple workaround since i do not want to edit the ppm file :P + if(val==0)val=0xffffff; + put_pixel(dst,dst_x+x,dst_y+y,val); + } + } static void put_win(struct window *win) { - struct pdirectory* mydir; -// if(win->vmem) - // { - x86_cli();// do not reschedule us til ready! - mydir=x86_get_page_directory(); - x86_set_page_directory(win->vmem); - // } + struct pdirectory* mydir; - uint32_t *user_vmem=VMEM_USER_FRAMEBUFFER; - uint32_t userx=0; - uint32_t usery=0; + x86_cli();// do not reschedule us til ready! + mydir=x86_get_page_directory(); + x86_set_page_directory(win->vmem); + uint32_t *user_vmem=VMEM_USER_FRAMEBUFFER; + uint32_t userx=0; + uint32_t usery=0; - // iterate over complete window area + // iterate over complete window area for(uint16_t x=win->posx;x<win->posx+win->width;x++) { usery=0; for(uint16_t y=win->posy;y<win->posy+win->height;y++) { - if(!win->active) + // 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; - uint8_t src_b=win->color&0xff; - uint8_t src_g=(win->color&0xff00)>>8; - uint8_t src_r=(win->color&0xff0000)>>16; uint16_t a; - if(win->vmem) - { - uint32_t col=0xff0000; - col=user_vmem[userx+usery*640]; - src_b=col&0xff; - src_g=(col&0xff00)>>8; - src_r=(col&0xff0000)>>16; - a=0x44; - } - else - { - // just for testing - src_b=win->color&0xff; - src_g=(win->color&0xff00)>>8; - src_r=(win->color&0xff0000)>>16; - - a=(0xff-((win->color&0xff000000)>>24)); - } + 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; //we encoded alpha in the highest octet. 1-opaque 0-transparent - //no premultiplied alpha. TODO: change maybe? - // + //no premultiplied alpha. TODO: change maybe for speedup!? uint8_t out_r=((src_r*(0xff-a))>>8)+((a*dst_r)>>8); uint8_t out_g=((src_g*(0xff-a))>>8)+((a*dst_g)>>8); 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; + */ } else { - if(win->vmem) - { - backbuffer[y*vesa_width+x]=(user_vmem[userx+usery*640]); - } - else - { - backbuffer[y*vesa_width+x]=0xffffff; - } + put_pixel(backbuffer,x,y,(user_vmem[userx+usery*640])); } usery++; @@ -141,48 +168,44 @@ static void put_win(struct window *win) //} //draw boundaries - /* - for(uint16_t x=win->posx;x<win->posx+win->width;x++) - { - backbuffer[(win->posy)*vesa_width+x]=0xffffff; //TOP - backbuffer[(win->posy+win->height-1)*vesa_width+x]=0xffffff; //BOTTOM - //backbuffer[(win->posy+win->height-3)*vesa_width+x]=0xffffff; //BOTTOM - } - for(uint16_t y=win->posy;y<win->posy+win->height;y++) + + if(option_win_borders) { - backbuffer[(y)*vesa_width+(win->posx)]=0xffffff; //LEFT - backbuffer[(y)*vesa_width+win->posx+win->width-1]=0xffffff; //RIGHT + for(uint16_t x=win->posx;x<win->posx+win->width;x++) + { + put_pixel(backbuffer,x,win->posy,0xffffff); //TOP + put_pixel(backbuffer,x,win->posy+win->height-1,0xffffff); //BOTTOM + } + for(uint16_t y=win->posy;y<win->posy+win->height;y++) + { + put_pixel(backbuffer,win->posx,y,0xffffff); //LEFT + put_pixel(backbuffer,win->posx+win->width-1,y,0xffffff); //RIGHT + } } - */ + // } static void put_mouse() { - if(mouse_k&1) - { - for(int i=0;i<1;i++) - for(int j=0;j<display_height;j++) -// backbuffer[(mouse_y+j)*vesa_width+mouse_x+i]=0x00ff00; - backbuffer[(j)*vesa_width+mouse_x+i]=0x0044ee; - - for(int i=0;i<display_width;i++) - for(int j=0;j<1;j++) -// backbuffer[(mouse_y+j)*vesa_width+mouse_x+i]=0x00ff00; - backbuffer[(mouse_y+j)*vesa_width+i]=0x0044ee; - } - else - { - for(int i=0;i<1;i++) - for(int j=0;j<display_height;j++) -// backbuffer[(mouse_y+j)*vesa_width+mouse_x+i]=0x00ff00; - backbuffer[(j)*vesa_width+mouse_x+i]=0x000099; - - for(int i=0;i<display_width;i++) - for(int j=0;j<1;j++) -// backbuffer[(mouse_y+j)*vesa_width+mouse_x+i]=0x00ff00; - backbuffer[(mouse_y+j)*vesa_width+i]=0x000099; - } +int iconx=mouse_icon_lx; +int icony=mouse_icon_ly; + +if(mouse_k&1) +{ + iconx=mouse_icon_active_lx; + icony=mouse_icon_active_ly; +} + +cpy_rect(icons,iconx,icony, // from + backbuffer, 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 + 0xffffff // color key of transp + ); + } void compositor_del_window(uint32_t addr) @@ -226,11 +249,18 @@ void compositor_add_window(uint32_t addr,uint32_t pid) compositor_mouse_handle(200,200,0); } -void compositor_init(uint16_t width, uint16_t height, uint16_t pitch) +// TODO : TEXTMODE FALLBACK! +void compositor_init(uint16_t width, uint16_t height, uint16_t depth, uint16_t pitch) { vesa_width=width; vesa_height=height; - klog("initialized composing window manager to %d x %d",width,height); + vesa_depth=depth/8; + vesa_pitch=pitch; + + klog("initialized composing window manager to %d x %d x %d" ,width,height,depth); + uint16_t expected_pitch=width*depth/8; + klog("expected pitch = %d , actual pitch = %d",expected_pitch,pitch); + if(expected_pitch!=pitch)kpanic("sorry we need to fix this. padding not supported now"); } void compositor_wake() @@ -252,9 +282,8 @@ void compositor_swap_buffers() // if(!first)return; // klog("swap"); // background - memcpy(backbuffer,bgimage,vesa_height*vesa_width*4);// TODO optimize? rects only too? +// memcpy(backbuffer,bgimage,vesa_height*vesa_width*4);// TODO optimize? rects only too? // compositor_set_background(0); - for(int i=next_window-1;i>=0;i--) { @@ -262,9 +291,12 @@ void compositor_swap_buffers() } put_mouse(); - memcpy(VMEM_FRAMEBUFFER,backbuffer,vesa_height*vesa_width*4);// TODO optimize? rects only too? + + // TODO optimize? rects only too? + memcpy(VMEM_FRAMEBUFFER,backbuffer,vesa_height*vesa_width*vesa_depth); first=false; } + void compositor_kb_handle(char c) { for(int i=0;i<MAX_WINDOWS;i++) @@ -278,29 +310,31 @@ void compositor_kb_handle(char c) } } -void compositor_mouse_handle(uint16_t x,uint16_t y, uint8_t key) +void compositor_mouse_handle(int16_t diff_x,int16_t diff_y, uint8_t key) { +// klog("%d %d %d",diff_x,diff_y,key); + mouse_x+=diff_x; + mouse_y+=diff_y; + mouse_k=key; - //klog("mouse: %d %d",x,y); - static int last_mouse_x; - static int last_mouse_y; + if(mouse_x<0)mouse_x=0; + if(mouse_y<0)mouse_y=0; + + if(mouse_x>=vesa_width-mouse_icon_width)mouse_x=vesa_width-1-mouse_icon_width; + if(mouse_y>=vesa_height-mouse_icon_height)mouse_y=vesa_height-1-mouse_icon_height; if(!(key&1)) { - last_mouse_x=x; - last_mouse_y=y; + last_mouse_x=mouse_x; + last_mouse_y=mouse_y; } - mouse_x=x; - mouse_y=y; - mouse_k=key; - int active=-1; for(int i=0;i<MAX_WINDOWS;i++) { struct window *w=&windows[i]; - if(active==-1&&x>w->posx&&x<w->posx+w->width&&y>w->posy&&y<w->posy+w->height) + if(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) { @@ -312,8 +346,8 @@ void compositor_mouse_handle(uint16_t x,uint16_t y, uint8_t key) if(w->posx<0)w->posx=0; if(w->posy<0)w->posy=0; - if(w->posx+w->width>=1920)w->posx=1920-640; - if(w->posy+w->height>=1080)w->posy=1080-480; + if(w->posx+w->width>=vesa_width)w->posx=vesa_width-640; + if(w->posy+w->height>=vesa_height)w->posy=vesa_height-480; } @@ -335,45 +369,33 @@ void compositor_mouse_handle(uint16_t x,uint16_t y, uint8_t key) } } -// https://stackoverflow.com/questions/3581528/how-is-the-square-root-function-implemented -double sqroot(double n){ - double lo = 0, hi = n, mid; - for(int i = 0 ; i < 10 ; i++){ - mid = (lo+hi)/2; - if(mid*mid == n) return mid; - if(mid*mid > n) hi = mid; - else lo = mid; - } - return mid; -} - +// load background image or generate one if (param == 0) void compositor_set_background(char *ppm_raw_filename) { // TODO: think about funny things to do with timer and update // some generated / or modified bg regularly // // uint64_t t=timer_get_ms()/333; // - if(ppm_raw_filename!=0) - { - klog("loading bg..."); - fd bg=mount_file_open(ppm_raw_filename); + klog("loading theme..."); + fd bg=mount_file_open(ppm_raw_filename); - uint32_t i=0; + uint32_t i=0; - for(int y=0;y<vesa_width;y++) + // read the image from left to right line by line + for(int y=0;y<1080;y++) + for(int x=0;x<1920;x++) + { { - for(int x=0;x<vesa_height;x++) - { - bgimage[i]=(fd_read(&bg)<<16)+(fd_read(&bg)<<8)+fd_read(&bg); - backbuffer[i]=bgimage[i]; - i++; - } + uint32_t val=(fd_read(&bg)<<16)+(fd_read(&bg)<<8)+fd_read(&bg); + if(x>=vesa_width)continue; + if(y>=vesa_height)continue; + put_pixel(icons,x,y,val); + i++; } - - klog("finished"); } - else - { + klog("finished"); + + // generating simple background... int center_x=vesa_width/2; int center_y=vesa_height/2; @@ -388,9 +410,7 @@ void compositor_set_background(char *ppm_raw_filename) int dist=diffx*diffx+diffy*diffy; int val = 0xff*dist/max_dist; - bgimage[x+y*vesa_width]=val; - //backbuffer[x+y*vesa_width]=valr<<16; + put_pixel(backbuffer,x,y,val); } } - } } diff --git a/video/compositor.h b/video/compositor.h index 446cf19..a7bbec4 100644 --- a/video/compositor.h +++ b/video/compositor.h @@ -2,10 +2,10 @@ void compositor_wake(); void compositor_wake2(); -void compositor_init(uint16_t width, uint16_t height, uint16_t pitch); +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(); -void compositor_mouse_handle(uint16_t x,uint16_t y, uint8_t key); +void compositor_mouse_handle(int16_t x,int16_t y, uint8_t key); void compositor_kb_handle(char c); void compositor_add_window(uint32_t addr,uint32_t pid); void compositor_del_window(uint32_t addr); |
