summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.md22
-rw-r--r--driver/keyboard.c1
-rw-r--r--driver/mouse.c97
-rw-r--r--grubiso/boot/grub/grub.cfg83
-rw-r--r--grubiso/boot/grub_bg.pngbin0 -> 470776 bytes
-rw-r--r--kernel/kernel.c6
-rw-r--r--kernel/kernel.h2
-rw-r--r--userspace/Makefile3
-rw-r--r--userspace/files/icons.ppmbin0 -> 6220801 bytes
-rw-r--r--userspace/pain/Makefile6
-rw-r--r--userspace/pain/pain1.c200
-rw-r--r--userspace/pain1.c48
-rw-r--r--userspace/put_pixel.h2
-rw-r--r--video/compositor.c306
-rw-r--r--video/compositor.h4
15 files changed, 525 insertions, 255 deletions
diff --git a/README.md b/README.md
index 1f41779..f244e8e 100644
--- a/README.md
+++ b/README.md
@@ -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
new file mode 100644
index 0000000..a5dce39
--- /dev/null
+++ b/grubiso/boot/grub_bg.png
Binary files differ
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
new file mode 100644
index 0000000..45ce414
--- /dev/null
+++ b/userspace/files/icons.ppm
Binary files differ
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);