aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Auvolat <alex@adnab.me>2015-03-11 14:35:54 +0100
committerAlex Auvolat <alex@adnab.me>2015-03-11 14:35:54 +0100
commit5e9251bd48acafff575ed1c740e4dc05ec175508 (patch)
tree00f95aafd4e0399bcb1858f24b7e79b06a216f30
parent052ca1dc143b1df2800f9c4e43daf80c96fb472e (diff)
downloadkogata-5e9251bd48acafff575ed1c740e4dc05ec175508.tar.gz
kogata-5e9251bd48acafff575ed1c740e4dc05ec175508.zip
Add simple drawing code & font loading.
-rw-r--r--res/fonts/Makefile5
-rw-r--r--res/fonts/default.c10
-rw-r--r--src/common/include/proto/fb.h14
-rw-r--r--src/kernel/dev/vesa.c31
-rw-r--r--src/lib/include/draw.h62
-rw-r--r--src/lib/include/proto/font_file.h14
-rw-r--r--src/lib/libkogata/Makefile2
-rw-r--r--src/lib/libkogata/draw.c317
-rw-r--r--src/sysbin/giosrv/main.c3
-rw-r--r--src/sysbin/login/main.c42
10 files changed, 467 insertions, 33 deletions
diff --git a/res/fonts/Makefile b/res/fonts/Makefile
index e1daf03..c4de63d 100644
--- a/res/fonts/Makefile
+++ b/res/fonts/Makefile
@@ -1,5 +1,8 @@
+CC=gcc
+CFLAGS=-I../../src/lib/include -std=c11
+
%.bf: %.c
- gcc -o $<.bin $<
+ $(CC) $(CFLAGS) -o $<.bin $<
./$<.bin > $@
rm $<.bin
diff --git a/res/fonts/default.c b/res/fonts/default.c
index 374c191..43fddce 100644
--- a/res/fonts/default.c
+++ b/res/fonts/default.c
@@ -1,6 +1,8 @@
#include <stdlib.h>
#include <stdio.h>
+#include <proto/font_file.h>
+
char font_data[256][16] = {
/* 0x00 */ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
/* 0x01 */ {0x00, 0x00, 0x7e, 0x81, 0xa5, 0x81, 0x81, 0xbd, 0x99, 0x81, 0x81, 0x7e, 0x00, 0x00, 0x00, 0x00},
@@ -260,6 +262,13 @@ char font_data[256][16] = {
/* 0xff */ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
};
+ascii_bitmap_font_header h = {
+ .magic = ASCII_BITMAP_FONT_MAGIC,
+ .cw = 8,
+ .ch = 16,
+ .nchars = 256,
+};
+
int main() {
FILE *f = fopen("default.bf", "wb");
if (f == 0) {
@@ -267,6 +276,7 @@ int main() {
exit(1);
}
+ fwrite(&h, 1, sizeof(h), f);
fwrite(font_data, 256, 16, f);
return 0;
diff --git a/src/common/include/proto/fb.h b/src/common/include/proto/fb.h
index dab9643..710ecb1 100644
--- a/src/common/include/proto/fb.h
+++ b/src/common/include/proto/fb.h
@@ -5,12 +5,14 @@
#include <stdint.h>
#include <stddef.h>
-#define FB_MM_RGB16 1 // 2 bytes (16 bits) per pixel, blue 0-4, green 5-9, red 10-14
-#define FB_MM_BGR16 2 // 2 bytes (16 bits) per pixel, red 0-4, green 5-9, blue 10-14
-#define FB_MM_RGB24 3 // 3 bytes (24 bits) per pixel, blue 0-7, green 8-15, red 16-23
-#define FB_MM_BGR24 4 // 3 bytes (24 bits) per pixel, red 0-7, green 8-15, blue 16-23
-#define FB_MM_RGB32 5 // 4 bytes (32 bits) per pixel, blue 0-7, green 8-15, red 16-23
-#define FB_MM_BGR32 6 // 4 bytes (32 bits) per pixel, red 0-7, green 8-15, blue 16-23
+#define FB_MM_RGB15 1 // 15 bits per pixel, blue 0-4, green 5-9, red 10-14
+#define FB_MM_BGR15 2 // 15 bits per pixel, red 0-4, green 5-9, blue 10-14
+#define FB_MM_RGB16 3 // 2 bytes (16 bits) per pixel, blue 0-4, green 5-9, red 10-14
+#define FB_MM_BGR16 4 // 2 bytes (16 bits) per pixel, red 0-4, green 5-9, blue 10-14
+#define FB_MM_RGB24 5 // 3 bytes (24 bits) per pixel, blue 0-7, green 8-15, red 16-23
+#define FB_MM_BGR24 6 // 3 bytes (24 bits) per pixel, red 0-7, green 8-15, blue 16-23
+#define FB_MM_RGB32 7 // 4 bytes (32 bits) per pixel, blue 0-7, green 8-15, red 16-23
+#define FB_MM_BGR32 8 // 4 bytes (32 bits) per pixel, red 0-7, green 8-15, blue 16-23
#define FB_MM_GREY8 10 // 1 byte (8 bits) per pixel greyscale
typedef struct {
diff --git a/src/kernel/dev/vesa.c b/src/kernel/dev/vesa.c
index a039d01..f77b230 100644
--- a/src/kernel/dev/vesa.c
+++ b/src/kernel/dev/vesa.c
@@ -243,9 +243,9 @@ fs_node_ops_t vesa_fs_ops = {
static struct fb_memory_model {
int bpp, rp, gp, bp, rs, gs, bs, mm;
} fb_memory_models[8] = {
- { 15, 10, 5, 0, 5, 5, 5, FB_MM_RGB16 },
+ { 15, 10, 5, 0, 5, 5, 5, FB_MM_RGB15 },
+ { 15, 0, 5, 10, 5, 5, 5, FB_MM_BGR15 },
{ 16, 10, 5, 0, 5, 5, 5, FB_MM_RGB16 },
- { 15, 0, 5, 10, 5, 5, 5, FB_MM_BGR16 },
{ 16, 0, 5, 10, 5, 5, 5, FB_MM_BGR16 },
{ 24, 16, 8, 0, 8, 8, 8, FB_MM_RGB24 },
{ 24, 0, 8, 16, 8, 8, 8, FB_MM_BGR24 },
@@ -443,12 +443,29 @@ void vesa_clear(vesa_driver_t *d) {
int tly = (mode->info.height / 2) - (kogata_logo.height / 2);
int tlx = (mode->info.width / 2) - (kogata_logo.width / 2);
- int mbpp = (mode->info.bpp / 8);
- for (unsigned l = 0; l < kogata_logo.height; l++) {
- memcpy(region + (tly + l) * mode->info.pitch + tlx * mbpp,
- buffer + kogata_logo.width * l * kogata_logo.bytes_per_pixel,
- kogata_logo.width * kogata_logo.bytes_per_pixel);
+ if (mode->info.bpp == 24) {
+ for (unsigned l = 0; l < kogata_logo.height; l++) {
+ memcpy(region + (tly + l) * mode->info.pitch + tlx * 3,
+ buffer + kogata_logo.width * l * kogata_logo.bytes_per_pixel,
+ kogata_logo.width * kogata_logo.bytes_per_pixel);
+ }
+ } else if (mode->info.bpp == 32) {
+ for (unsigned l = 0; l < kogata_logo.height; l++) {
+ uint32_t *p = (uint32_t*)(region + (tly + l) * mode->info.pitch + tlx * 4);
+ uint8_t *r = (uint8_t*)(buffer + kogata_logo.width * l * kogata_logo.bytes_per_pixel);
+ for (unsigned c = 0; c < kogata_logo.width; c++) {
+ p[c] = r[3*c] | (r[3*c+1] << 8) | (r[3*c+2] <<16);
+ }
+ }
+ } else if (mode->info.bpp == 15 || mode->info.bpp == 16) {
+ for (unsigned l = 0; l < kogata_logo.height; l++) {
+ uint16_t *p = (uint16_t*)(region + (tly + l) * mode->info.pitch + tlx * 2);
+ uint8_t *r = (uint8_t*)(buffer + kogata_logo.width * l * kogata_logo.bytes_per_pixel);
+ for (unsigned c = 0; c < kogata_logo.width; c++) {
+ p[c] = (r[3*c]/8) | ((r[3*c+1]/8) << 5) | ((r[3*c+2]/8) <<10);
+ }
+ }
}
end:
diff --git a/src/lib/include/draw.h b/src/lib/include/draw.h
new file mode 100644
index 0000000..893c5a3
--- /dev/null
+++ b/src/lib/include/draw.h
@@ -0,0 +1,62 @@
+#pragma once
+
+#include <syscall.h>
+#include <proto/fb.h>
+
+// ---- Generic drawing functions
+
+// ---- Data structures
+
+typedef struct {
+ fb_info_t geom;
+
+ fd_t fd;
+ uint8_t* data;
+} fb_t;
+
+typedef struct font font_t;
+
+typedef uint32_t color_t; // a color is always linked to a FB on which it is to be applied
+
+// ---- Buffer creation
+
+fb_t *g_fb_from_file(fd_t file, fb_info_t *geom);
+fb_t *g_fb_from_mem(uint8_t* region, fb_info_t *geom);
+
+void g_delete_fb(fb_t *fb);
+
+// ---- Color manipulation
+
+color_t g_color_rgb(fb_t *f, uint8_t r, uint8_t g, uint8_t b);
+
+// ---- Drawing primitives
+
+void g_plot(fb_t *fb, int x, int y, color_t c);
+
+void g_hline(fb_t *fb, int x, int y, int w, color_t c); // horizontal line
+void g_vline(fb_t *fb, int x, int y, int h, color_t c); // vertical line
+void g_line(fb_t *fb, int x1, int y1, int x2, int y2, color_t c);
+
+void g_rect(fb_t *fb, int x, int y, int w, int h, color_t c);
+void g_fillrect(fb_t *fb, int x, int y, int w, int h, color_t c);
+void g_rect_r(fb_t *fb, fb_region_t reg, color_t c);
+void g_fillrect_r(fb_t *fb, fb_region_t reg, color_t c);
+
+void g_circle(fb_t *fb, int cx, int cy, int r, color_t c);
+void g_fillcircle(fb_t *fb, int cx, int cy, int r, color_t c);
+
+void g_blit(fb_t *dst, int x, int y, fb_t *src);
+void g_blit_region(fb_t *dst, int x, int y, fb_t *src, fb_region_t reg);
+
+// ---- Text manipulation
+
+font_t *g_load_font(const char* fontname);
+void g_free_font(font_t *f);
+
+int g_text_width(font_t *f, const char* text);
+int g_text_height(font_t *f, const char* text);
+
+void g_write(fb_t *fb, int x, int y, const char* text, font_t *font, color_t c);
+
+
+/* vim: set ts=4 sw=4 tw=0 noet :*/
diff --git a/src/lib/include/proto/font_file.h b/src/lib/include/proto/font_file.h
new file mode 100644
index 0000000..e57c0ab
--- /dev/null
+++ b/src/lib/include/proto/font_file.h
@@ -0,0 +1,14 @@
+#pragma once
+
+#include <stdint.h>
+#include <stddef.h>
+
+#define ASCII_BITMAP_FONT_MAGIC 0xD184C274
+
+typedef struct {
+ uint32_t magic;
+ uint16_t cw, ch;
+ uint32_t nchars;
+} ascii_bitmap_font_header;
+
+/* vim: set ts=4 sw=4 tw=0 noet :*/
diff --git a/src/lib/libkogata/Makefile b/src/lib/libkogata/Makefile
index 48c6bc2..a8df419 100644
--- a/src/lib/libkogata/Makefile
+++ b/src/lib/libkogata/Makefile
@@ -1,5 +1,5 @@
OBJ = start.o malloc.o debug.o syscall.o user_region.o \
- mainloop.o gip.o
+ mainloop.o gip.o draw.o
LIB = ../../common/libkogata/libkogata.lib ../../common/libalgo/libalgo.lib ../../common/libc/libc.lib
diff --git a/src/lib/libkogata/draw.c b/src/lib/libkogata/draw.c
new file mode 100644
index 0000000..22ad8ba
--- /dev/null
+++ b/src/lib/libkogata/draw.c
@@ -0,0 +1,317 @@
+#include <syscall.h>
+#include <malloc.h>
+#include <string.h>
+#include <printf.h>
+
+#include <proto/font_file.h>
+
+#include <user_region.h>
+
+#include <draw.h>
+
+fb_t *g_fb_from_file(fd_t file, fb_info_t *geom) {
+ fb_t *ret = (fb_t*)malloc(sizeof(fb_t));
+ if (ret == 0) return 0;
+
+ memcpy(&ret->geom, geom, sizeof(fb_info_t));
+ ret->fd = file;
+
+ ret->data = (uint8_t*)region_alloc(geom->height * geom->pitch, "Framebuffer");
+ if (ret->data == 0) goto error;
+
+ bool map_ok = mmap_file(file, 0, ret->data, geom->height * geom->pitch, MM_READ | MM_WRITE);
+ if (!map_ok) goto error;
+
+ return ret;
+
+error:
+ if (ret && ret->data) region_free(ret->data);
+ if (ret) free(ret);
+ return 0;
+}
+
+fb_t *g_fb_from_mem(uint8_t* data, fb_info_t *geom) {
+ fb_t *ret = (fb_t*)malloc(sizeof(fb_t));
+ if (ret == 0) return 0;
+
+ memcpy(&ret->geom, geom, sizeof(fb_info_t));
+ ret->fd = 0;
+ ret->data = data;
+
+ return ret;
+}
+
+void g_delete_fb(fb_t *fb) {
+ if (fb->fd != 0) {
+ munmap(fb->data);
+ region_free(fb->data);
+ }
+ free(fb);
+}
+
+// ---- Color management
+
+color_t g_color_rgb(fb_t *f, uint8_t r, uint8_t g, uint8_t b) {
+ int m = f->geom.memory_model;
+ if (m == FB_MM_RGB24 || m == FB_MM_RGB32) return (r << 16) | (g << 8) | b;
+ if (m == FB_MM_BGR24 || m == FB_MM_BGR32) return (b << 16) | (g << 8) | r;
+ if (m == FB_MM_GREY8) return ((r + g + b) / 3) & 0xFF;
+ if (m == FB_MM_RGB16 || m == FB_MM_RGB15) return ((r >> 3) << 10) | ((g >> 3) << 5) | (b >> 3);
+ if (m == FB_MM_BGR16 || m == FB_MM_BGR15) return ((b >> 3) << 10) | ((g >> 3) << 5) | (r >> 3);
+ return 0; // unknown?
+}
+
+// ---- Plot
+
+inline void g_plot24(uint8_t* p, color_t c) {
+ p[0] = c & 0xFF;
+ p[1] = (c >> 8) & 0xFF;
+ p[2] = (c >> 16) & 0xFF;
+}
+
+void g_plot(fb_t *fb, int x, int y, color_t c) {
+ if (fb->geom.bpp == 8) {
+ fb->data[y * fb->geom.pitch + x] = (c & 0xFF);
+ } else if (fb->geom.bpp == 15 || fb->geom.bpp == 16) {
+ uint16_t *p = (uint16_t*)(fb->data + y * fb->geom.pitch + 2 * x);
+ *p = (c & 0xFFFF);
+ } else if (fb->geom.bpp == 24) {
+ g_plot24(fb->data + y * fb->geom.pitch + 3 * x, c);
+ } else if (fb->geom.bpp == 32) {
+ uint32_t *p = (uint32_t*)(fb->data + y * fb->geom.pitch + 4 * x);
+ *p = c;
+ }
+}
+
+void g_hline(fb_t *fb, int x, int y, int w, color_t c) {
+ if (fb->geom.bpp == 8) {
+ for (int u = x; u < x + w; u++) {
+ fb->data[y * fb->geom.pitch + u] = (c & 0xFF);
+ }
+ } else if (fb->geom.bpp == 15 || fb->geom.bpp == 15) {
+ for (int u = x; u < x + w; u++) {
+ uint16_t *p = (uint16_t*)(fb->data + y * fb->geom.pitch + 2 * u);
+ *p = (c & 0xFFFF);
+ }
+ } else if (fb->geom.bpp == 24) {
+ for (int u = x; u < x + w; u++) {
+ g_plot24(fb->data + y * fb->geom.pitch + 3 * u, c);
+ }
+ } else if (fb->geom.bpp == 32) {
+ for (int u = x; u < x + w; u++) {
+ uint32_t *p = (uint32_t*)(fb->data + y * fb->geom.pitch + 4 * u);
+ *p = c;
+ }
+ }
+}
+
+void g_vline(fb_t *fb, int x, int y, int h, color_t c) {
+ if (fb->geom.bpp == 8) {
+ for (int v = y; v < y + h; v++) {
+ fb->data[v * fb->geom.pitch + x] = (c & 0xFF);
+ }
+ } else if (fb->geom.bpp == 15 || fb->geom.bpp == 15) {
+ for (int v = y; v < y + h; v++) {
+ uint16_t *p = (uint16_t*)(fb->data + v * fb->geom.pitch + 2 * x);
+ *p = (c & 0xFFFF);
+ }
+ } else if (fb->geom.bpp == 24) {
+ for (int v = y; v < y + h; v++) {
+ g_plot24(fb->data + v * fb->geom.pitch + 3 * x, c);
+ }
+ } else if (fb->geom.bpp == 32) {
+ for (int v = y; v < y + h; v++) {
+ uint32_t *p = (uint32_t*)(fb->data + v * fb->geom.pitch + 4 * x);
+ *p = c;
+ }
+ }
+}
+
+void g_line(fb_t *fb, int x1, int y1, int x2, int y2, color_t c) {
+ // TODO
+}
+
+void g_rect(fb_t *fb, int x, int y, int w, int h, color_t c) {
+ g_hline(fb, x, y, w, c);
+ g_hline(fb, x, y+h-1, w, c);
+ g_vline(fb, x, y, h, c);
+ g_vline(fb, x+w-1, y, h, c);
+}
+
+void g_fillrect(fb_t *fb, int x, int y, int w, int h, color_t c) {
+ if (fb->geom.bpp == 8) {
+ for (int v = y; v < y + h; v++) {
+ for (int u = x; u < x + w; u++) {
+ fb->data[v * fb->geom.pitch + u] = (c & 0xFF);
+ }
+ }
+ } else if (fb->geom.bpp == 15 || fb->geom.bpp == 15) {
+ for (int v = y; v < y + h; v++) {
+ for (int u = x; u < x + w; u++) {
+ uint16_t *p = (uint16_t*)(fb->data + v * fb->geom.pitch + 2 * u);
+ *p = (c & 0xFFFF);
+ }
+ }
+ } else if (fb->geom.bpp == 24) {
+ for (int v = y; v < y + h; v++) {
+ for (int u = x; u < x + w; u++) {
+ g_plot24(fb->data + v * fb->geom.pitch + 3 * u, c);
+ }
+ }
+ } else if (fb->geom.bpp == 32) {
+ for (int v = y; v < y + h; v++) {
+ for (int u = x; u < x + w; u++) {
+ uint32_t *p = (uint32_t*)(fb->data + v * fb->geom.pitch + 4 * u);
+ *p = c;
+ }
+ }
+ }
+}
+
+void g_rect_r(fb_t *fb, fb_region_t reg, color_t c) {
+ g_rect(fb, reg.x, reg.y, reg.w, reg.h, c);
+}
+
+void g_fillrect_r(fb_t *fb, fb_region_t reg, color_t c) {
+ g_fillrect(fb, reg.x, reg.y, reg.w, reg.h, c);
+}
+
+void g_circle(fb_t *fb, int cx, int cy, int r, color_t c) {
+ // TODO
+}
+
+void g_fillcircle(fb_t *fb, int cx, int cy, int r, color_t c) {
+ // TODO
+}
+
+void g_blit(fb_t *dst, int x, int y, fb_t *src) {
+ fb_region_t r;
+
+ r.x = 0;
+ r.y = 0;
+ r.w = src->geom.width;
+ r.h = src->geom.height;
+
+ g_blit_region(dst, x, y, src, r);
+}
+
+void g_blit_region(fb_t *dst, int x, int y, fb_t *src, fb_region_t reg) {
+ if (src->geom.memory_model == dst->geom.memory_model) {
+ for (uint32_t i = 0; i < reg.h; i++) {
+ memcpy(
+ dst->data + (y + i) * dst->geom.pitch + x * (dst->geom.bpp / 8),
+ src->data + (reg.y + i) * src->geom.pitch + reg.x * (src->geom.bpp / 8),
+ reg.w * (src->geom.bpp / 8));
+ }
+ } else {
+ dbg_printf("Unsupported blit between different memory models.\n");
+ }
+}
+
+// ---- Text manipulation
+
+#define FONT_ASCII_BITMAP 1
+// more font types to come
+
+typedef struct font {
+ int type;
+ union {
+ struct {
+ uint8_t* data;
+ uint8_t cw, ch; // width, height of a character
+ uint32_t nchars;
+ } ascii_bitmap;
+ };
+} font_t;
+
+font_t *g_load_ascii_bitmap_font(fd_t f) {
+ font_t *font = 0;
+
+ ascii_bitmap_font_header h;
+
+ size_t s = read(f, 0, sizeof(h), (char*)&h);
+ if (s != sizeof(h)) goto error;
+
+ if (h.magic != ASCII_BITMAP_FONT_MAGIC) goto error;
+ if (h.cw != 8) goto error;
+
+ font = malloc(sizeof(font_t));
+ if (font == 0) goto error;
+ memset(font, 0, sizeof(font_t));
+
+
+ font->type = FONT_ASCII_BITMAP;
+ font->ascii_bitmap.cw = h.cw;
+ font->ascii_bitmap.ch = h.ch;
+ font->ascii_bitmap.nchars = h.nchars;
+
+
+ font->ascii_bitmap.data = (uint8_t*)malloc(h.ch * h.nchars);
+ if (font->ascii_bitmap.data == 0) goto error;
+
+ size_t rd = read(f, sizeof(h), h.ch * h.nchars, (char*)font->ascii_bitmap.data);
+ if (rd != h.ch * h.nchars) goto error;
+
+ return font;
+
+error:
+ if (font && font->ascii_bitmap.data) free(font->ascii_bitmap.data);
+ if (font) free(font);
+ close(f);
+ return 0;
+}
+
+font_t *g_load_font(const char* fontname) {
+ char buf[128];
+
+ snprintf(buf, 128, "sys:/fonts/%s.bf", fontname);
+ fd_t f = open(buf, FM_READ);
+ if (f != 0) return g_load_ascii_bitmap_font(f);
+
+ return 0;
+}
+
+void g_free_font(font_t *f) {
+ if (f->type == FONT_ASCII_BITMAP) {
+ free(f->ascii_bitmap.data);
+ }
+
+ free(f);
+}
+
+int g_text_width(font_t *font, const char* text) {
+ if (font->type == FONT_ASCII_BITMAP) {
+ return font->ascii_bitmap.cw * strlen(text);
+ }
+ return 0;
+}
+
+int g_text_height(font_t *font, const char* text) {
+ if (font->type == FONT_ASCII_BITMAP) {
+ return font->ascii_bitmap.ch;
+ }
+ return 0;
+}
+
+void g_write(fb_t *fb, int x, int y, const char* text, font_t *font, color_t c) {
+ if (font->type == FONT_ASCII_BITMAP) {
+ while (*text != 0) {
+ uint8_t id = (uint8_t)*text;
+ if (id < font->ascii_bitmap.nchars) {
+ uint8_t *d = font->ascii_bitmap.data + (id * font->ascii_bitmap.ch);
+ for (int r = 0; r < font->ascii_bitmap.ch; r++) {
+ for (int j = 0; j < 8; j++) {
+ if (d[r] & (0x80 >> j)) {
+ g_plot(fb, x + j, y + r, c);
+ }
+ }
+ }
+ }
+ text++;
+ x += font->ascii_bitmap.cw;
+ }
+ }
+}
+
+
+/* vim: set ts=4 sw=4 tw=0 noet :*/
diff --git a/src/sysbin/giosrv/main.c b/src/sysbin/giosrv/main.c
index fcb9360..b38d1c7 100644
--- a/src/sysbin/giosrv/main.c
+++ b/src/sysbin/giosrv/main.c
@@ -103,14 +103,17 @@ void disable_features(gip_handler_t *h, gip_msg_header *p) {
void query_mode(gip_handler_t *h, gip_msg_header *p) {
// TODO
+ gip_reply_fail(h, p);
}
void set_mode(gip_handler_t *h, gip_msg_header *p) {
// TODO
+ gip_reply_fail(h, p);
}
void unknown_msg(gip_handler_t *h, gip_msg_header *p) {
// TODO
+ gip_reply_fail(h, p);
}
void fd_error(gip_handler_t *h) {
diff --git a/src/sysbin/login/main.c b/src/sysbin/login/main.c
index eac19e7..294ad76 100644
--- a/src/sysbin/login/main.c
+++ b/src/sysbin/login/main.c
@@ -4,14 +4,12 @@
#include <debug.h>
#include <gip.h>
+#include <draw.h>
typedef struct {
fb_info_t mode;
-
- size_t fb_size;
- void* map;
-
fd_t fd;
+ fb_t *fb;
uint32_t sv_features, cl_features;
} loginc_t;
@@ -63,10 +61,13 @@ void c_buffer_info(gip_handler_t *s, gip_msg_header *p, gip_buffer_info_msg *m)
loginc_t *c = (loginc_t*)s->data;
- if (c->fd != 0) close(c->fd);
- if (c->map != 0) {
- munmap(c->map);
- region_free(c->map);
+ if (c->fb != 0) {
+ g_delete_fb(c->fb);
+ c->fb = 0;
+ }
+ if (c->fd != 0) {
+ close(c->fd);
+ c->fd = 0;
}
c->fd = use_token(&m->tok);
@@ -76,19 +77,24 @@ void c_buffer_info(gip_handler_t *s, gip_msg_header *p, gip_buffer_info_msg *m)
dbg_printf("[login] Got buffer on FD %d, %dx%dx%d\n",
c->fd, c->mode.width, c->mode.height, c->mode.bpp);
- c->fb_size = c->mode.pitch * c->mode.height;
-
- c->map = region_alloc(c->fb_size, "Framebuffer");
- if (c->map != 0) {
- bool ok = mmap_file(c->fd, 0, c->map, c->fb_size, MM_READ | MM_WRITE);
- if (ok) {
- memset(c->map, 0, c->fb_size);
+ c->fb = g_fb_from_file(c->fd, &m->geom);
+ if (c->fb != 0) {
+ color_t black = g_color_rgb(c->fb, 0, 0, 0);
+ color_t grey = g_color_rgb(c->fb, 128, 128, 128);
+ g_fillrect(c->fb, 0, 0, m->geom.width, m->geom.height, black);
+ g_fillrect(c->fb, 50, 50, 50, 50, grey);
+
+ font_t *f = g_load_font("default");
+ if (f != 0) {
+ g_write(c->fb, 50, 100, "Hello, world!", f, grey);
+ g_free_font(f);
} else {
- dbg_printf("[login] Could not mmap buffer.\n");
- region_free(c->map);
- c->map = 0;
+ dbg_printf("Could not load font 'default'\n");
}
+ } else {
+ dbg_printf("Could not open framebuffer file %d\n", c->fd);
}
+
}
}