summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Baumann <mail@andreasbaumann.cc>2017-06-30 16:45:12 +0200
committerAndreas Baumann <mail@andreasbaumann.cc>2017-06-30 16:45:12 +0200
commitc1bbac52d78b2e3e93fa43a5a7b3907073493216 (patch)
tree13ec009562358d01b1845dd08135f4ac8d384551
parent915dd4b023d0826166d4887100dbed64d46821a9 (diff)
downloadabaos-c1bbac52d78b2e3e93fa43a5a7b3907073493216.tar.gz
abaos-c1bbac52d78b2e3e93fa43a5a7b3907073493216.tar.bz2
text widget has a constant buffer and owns the string to draw now
(passing a const char * from a local stack context is not really a good idea!) added more efficiet draw method for characters in vga driver protected desktop for now against too often redraws (boolean global variable needs_redraw, this is later a soffisticated set-of-areas-to -redraw algorithm)
-rw-r--r--src/Makefile2
-rw-r--r--src/drivers/video/vga.c27
-rw-r--r--src/gui/desktop.c17
-rw-r--r--src/gui/desktop.h3
-rw-r--r--src/gui/text_widget.c7
-rw-r--r--src/gui/text_widget.h4
-rw-r--r--src/kernel/kernel.c12
7 files changed, 56 insertions, 16 deletions
diff --git a/src/Makefile b/src/Makefile
index bcb0da7..a6781ba 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -1,6 +1,6 @@
CC := gcc
INCLUDES = -I. -Ilibc -Ihardware -Idrivers -Idrivers/hdi -Idrivers/hdi/ps2 -Ikernel -Igui
-CFLAGS := -std=c99 -m32 -ffreestanding -O0 -g -Wall -Werror $(INCLUDES)
+CFLAGS := -std=c99 -m32 -ffreestanding -O0 -g -Wall $(INCLUDES)
LD := ld
NASMFLAGS := -f elf32
NASM := nasm
diff --git a/src/drivers/video/vga.c b/src/drivers/video/vga.c
index bcd4366..647456b 100644
--- a/src/drivers/video/vga.c
+++ b/src/drivers/video/vga.c
@@ -254,6 +254,7 @@ bool vga_set_mode( vga_t *vga, const vga_mode_t mode )
vga->mode.segment = get_frame_buffer_segment( vga );
vga_use_z_buffer( vga, false );
+ memset( vga->zbuffer, 0, sizeof( vga->zbuffer ) );
return true;
}
@@ -325,12 +326,12 @@ void vga_set_pixel( vga_t *vga, const int x, const int y, const vga_color_t colo
void vga_draw_rectangle( vga_t *vga, const int x, const int y, const int w, const int h, const vga_color_t color )
{
if( !params_ok( vga, x, y ) ) {
- kernel_panic( "Pixel coordinates are out of bounds: (%d, %d), resolution is only (%d, %d)",
+ kernel_panic( "Rectangle start coordinates are out of bounds: (%d, %d), resolution is only (%d, %d)",
x, y, vga->mode.x, vga->mode.y );
}
if( !params_ok( vga, x + w, y + h ) ) {
- kernel_panic( "Pixel coordinates are out of bounds: (%d, %d), resolution is only (%d, %d)",
+ kernel_panic( "Rectangle end coordinates are out of bounds: (%d, %d), resolution is only (%d, %d)",
x + w, y + h, vga->mode.x, vga->mode.y );
}
@@ -365,15 +366,35 @@ void vga_draw_char( vga_t *vga, const unsigned char c, const int x, const int y,
// for now, the 34 entry, character height is 16, assuming A-Z
const unsigned char *bmap = &vga_font.Bitmap[(c-32)*16];
+ uint8_t fg_color_idx = get_color_index( foreground );
+ uint8_t bg_color_idx = get_color_index( background );
+ // should be dynamic and vga_font.Width
+ uint8_t data[8];
+
+ for( int yy = 0; yy < vga_font.Height; yy++ ) {
+ memset( data, bg_color_idx, sizeof( data ) );
+ for( int xx = 0; xx < vga_font.Width; xx++ ) {
+ if( bmap[yy] & mask[xx] ) {
+ data[7-xx] = fg_color_idx;
+ }
+ }
+ uint8_t *addr = vga->base_addr + vga->mode.x * ( y + yy ) + x;
+ memcpy( addr, data, 8 );
+ }
+
+// amazingly slow
+/*
for( int xx = 0; xx < vga_font.Width; xx++ ) {
for( int yy = 0; yy < vga_font.Height; yy++ ) {
if( bmap[yy] & mask[xx] ) {
vga_set_pixel( vga, x + 10 - xx, y + yy, foreground );
} else {
- vga_set_pixel( vga, x + 10 - xx, y + yy, background );
+// drawing only what's needed, the background is done by the widget
+// vga_set_pixel( vga, x + 10 - xx, y + yy, background );
}
}
}
+*/
}
void vga_wait_for_retrace( vga_t *vga )
diff --git a/src/gui/desktop.c b/src/gui/desktop.c
index 6592b52..ad4aad9 100644
--- a/src/gui/desktop.c
+++ b/src/gui/desktop.c
@@ -28,6 +28,7 @@ void desktop_init( desktop_t *desktop, const int w, const int h, const vga_color
desktop->mouse_x = w / 2;
desktop->mouse_y = h / 2;
+ desktop->needs_redrawing = true;
desktop->base.base.vtable = (widget_vtable_t *)&desktop_vtable;
desktop->base.vtable = (composite_widget_vtable_t *)&desktop_vtable;
@@ -38,6 +39,10 @@ void desktop_draw( void *obj, graphics_context_t *context )
{
desktop_t *desktop = obj;
+ if( !desktop->needs_redrawing ) {
+ return;
+ }
+
vga_clear_screen( context, desktop->base.base.background_color );
composite_widget_draw( obj, context );
@@ -56,16 +61,26 @@ void desktop_draw( void *obj, graphics_context_t *context )
vga_set_pixel( context, desktop->mouse_x, desktop->mouse_y + i, VGA_COLOR_WHITE );
}
}
+
+ desktop->needs_redrawing = false;
}
void desktop_on_mouse_down( void *obj, const int x, const int y )
{
+ desktop_t *desktop = obj;
+
composite_widget_on_mouse_down( obj, x, y );
+
+ desktop->needs_redrawing = true;
}
void desktop_on_mouse_up( void *obj, const int x, const int y )
{
+ desktop_t *desktop = obj;
+
composite_widget_on_mouse_up( obj, x, y );
+
+ desktop->needs_redrawing = true;
}
void desktop_on_mouse_move( void *obj, const int old_x, const int old_y, const int x, const int y )
@@ -76,4 +91,6 @@ void desktop_on_mouse_move( void *obj, const int old_x, const int old_y, const i
desktop->mouse_y = y;
composite_widget_on_mouse_move( obj, old_x, old_y, x, y );
+
+ desktop->needs_redrawing = true;
}
diff --git a/src/gui/desktop.h b/src/gui/desktop.h
index a8db094..a9d1946 100644
--- a/src/gui/desktop.h
+++ b/src/gui/desktop.h
@@ -5,6 +5,8 @@
#define MAX_NOF_WIDGET_CHILDREN 100
+#include <stdbool.h>
+
typedef struct {
composite_widget_vtable_t base;
} desktop_vtable_t;
@@ -14,6 +16,7 @@ typedef struct {
desktop_vtable_t *vtable;
int mouse_x;
int mouse_y;
+ bool needs_redrawing;
} desktop_t;
void desktop_init( desktop_t *widget, const int w, const int h, const vga_color_t background_color );
diff --git a/src/gui/text_widget.c b/src/gui/text_widget.c
index eea2613..db237af 100644
--- a/src/gui/text_widget.c
+++ b/src/gui/text_widget.c
@@ -24,9 +24,7 @@ void text_widget_init( text_widget_t *widget, widget_t *parent, const int x, con
widget_init( &widget->base, parent, x, y, w, h, background_color );
- // TODO: const for now, caller has to preserve the text
- // maybe with memory manager in place we can do this with a strdup
- widget->s = s;
+ text_widget_set_text( widget, s );
widget->base.vtable = (widget_vtable_t *)&text_widget_vtable;
widget->vtable = &text_widget_vtable;
@@ -61,7 +59,6 @@ void text_widget_set_text( void *obj, const char *s )
{
text_widget_t *widget = obj;
- // TODO: see above
- widget->s = s;
+ strlcpy( widget->s, s, TEXT_WIDGET_MAX_TEXT_SIZE );
}
diff --git a/src/gui/text_widget.h b/src/gui/text_widget.h
index 4b00b4f..7e87a3c 100644
--- a/src/gui/text_widget.h
+++ b/src/gui/text_widget.h
@@ -3,6 +3,8 @@
#include "widget.h"
+#define TEXT_WIDGET_MAX_TEXT_SIZE 100
+
typedef struct {
widget_vtable_t base;
void (*set_text)( void *obj, const char *s );
@@ -11,7 +13,7 @@ typedef struct {
typedef struct {
widget_t base;
text_widget_vtable_t *vtable;
- const char *s;
+ char s[TEXT_WIDGET_MAX_TEXT_SIZE];
} text_widget_t;
void text_widget_init( text_widget_t *widget, widget_t *parent, const int x, const int y, const int w, const int h, const vga_color_t background_color, const char *s );
diff --git a/src/kernel/kernel.c b/src/kernel/kernel.c
index aacfcbd..9bd3d98 100644
--- a/src/kernel/kernel.c
+++ b/src/kernel/kernel.c
@@ -139,7 +139,7 @@ void kernel_main( void )
// for now we are only interested in interrupts,
// so we let the main thread sleep instead of
// burning CPU..
-// kernel_halt( );
+ kernel_halt( );
switch( global_context.mode ) {
case MODE_TEXT:
@@ -152,7 +152,8 @@ void kernel_main( void )
// wait for VGA retrace, assume drawing the desktop
// is fast enough to finish in time (so we don't recheck
- // for retrace)
+ // for retrace), it Z-buffering, this is done in vga_refresh
+ // directly, no need to do it here
// vga_wait_for_retrace( &global_context.vga );
// as vga_t is equals to the graphical context for now
@@ -238,6 +239,7 @@ static void handle_keyboard_event( keyboard_event_t *event, void *context )
((composite_widget_vtable_t *)global_context->desktop.vtable)->add_child( &global_context->desktop, (widget_t *)&global_context->window2 );
char s[100];
+
char *p = s;
for( char c = ' '; c <= '~'; c++ ) {
*p++ = c;
@@ -248,7 +250,7 @@ static void handle_keyboard_event( keyboard_event_t *event, void *context )
((composite_widget_vtable_t *)global_context->desktop.vtable)->add_child( &global_context->desktop, (widget_t *)&global_context->window3 );
text_widget_init( &global_context->widget3, (widget_t *)&global_context->window3, 1, 1, global_context->window3.base.base.w - 2, global_context->window3.base.base.h - 2, VGA_COLOR_RED, s );
-// ((composite_widget_vtable_t *)global_context->window3.vtable)->add_child( (composite_widget_t *)&global_context->window3, (widget_t *)&global_context->widget3 );
+ ((composite_widget_vtable_t *)global_context->window3.vtable)->add_child( (composite_widget_t *)&global_context->window3, (widget_t *)&global_context->widget3 );
mouse_set_resolution( mouse, vga->mode.x, vga->mode.y );
}
@@ -257,7 +259,7 @@ static void handle_keyboard_event( keyboard_event_t *event, void *context )
vga_use_z_buffer( &global_context->vga, true );
// draw on mode switch
- ((widget_vtable_t *)global_context->desktop.vtable)->draw( &global_context->desktop, &global_context->vga );
+// ((widget_vtable_t *)global_context->desktop.vtable)->draw( &global_context->desktop, &global_context->vga );
global_context->mode = MODE_GRAPHICS;
break;
@@ -336,9 +338,7 @@ static void handle_mouse_event( mouse_event_t *event, void *context )
// alternative way of redrawing on mouse event
// on qemu looses the mouse..
-// interrupts_disable( );
// ((widget_vtable_t *)desktop->vtable)->draw( &global_context->desktop, &global_context->vga );
-// interrupts_enable( );
break;
}