kernmsg app works again

This commit is contained in:
uosfz 2026-05-07 15:34:12 +02:00
parent 52cbddab08
commit 3da9b12e76
Signed by: uosfz
SSH key fingerprint: SHA256:FlktuluyhTQg3jHZNLKwxOOC5hbfrUXM0tz3IA3lGJo
4 changed files with 79 additions and 32 deletions

View file

@ -51,6 +51,7 @@ KERNEL_SOURCES := \
src/app.c \
src/app_calculator.c \
src/app_squares.c \
src/app_kernmsg.c \
src/font.c \
$(KERNEL_SOURCES_$(ARCH)) \
# end of kernel sources list

View file

@ -45,6 +45,7 @@ struct Component *app_component_new_canvas(unsigned width, unsigned height);
void app_component_redraw(void *self, struct Component *cpnt);
void app_canvas_draw_rect(void *self, struct Component *canvas, struct color col, const struct rect *rect);
void app_canvas_draw_text(void *self, struct Component *canvas, const char *text, int x, int y, struct color fg, struct color bg);
// called from bootstrap processor once he's done initializing
void app_init_global(void);

View file

@ -156,6 +156,29 @@ void app_canvas_draw_rect(void *self, struct Component *canvas, struct color col
tex_fill_region(&canvas->data.canvas.tex, col, rect);
}
void app_canvas_draw_texture(void *self, struct Component *canvas, const struct tex *tex, int x, int y) {
struct rect src_rect = RECT_XYWH(x, y, tex->width, tex->height);
tex_blit(&canvas->data.canvas.tex, tex, NULL, &src_rect);
}
void app_canvas_draw_glyph(void *self, struct Component *canvas, uint32_t glyph, int x, int y, struct color fg, struct color bg) {
struct app_instance *ins = app_find(self);
ASSERT(ins != NULL);
if (!font_load_glyph_with_color(&app_font, glyph, &ins->fontbuf, fg, bg)) {
ASSERT(font_load_glyph_with_color(&app_font, UNICODE_REPLACEMENT_CHARACTER, &ins->fontbuf, fg, bg));
}
app_canvas_draw_texture(self, canvas, &ins->fontbuf, x, y);
}
void app_canvas_draw_text(void *self, struct Component *canvas, const char *text, int x, int y, struct color fg, struct color bg) {
const uint8_t *uc = (const uint8_t *)text;
uint32_t glyph;
while ((glyph = utf8_next_asserted(&uc)) != 0) {
app_canvas_draw_glyph(self, canvas, glyph, x, y, fg, bg);
x += font_width(&app_font);
}
}
static struct app_instance *app_find(void *app) {
if (app_root->app == app) {
@ -497,6 +520,7 @@ void app_key_event_listener(struct key_event event) {
extern struct app_template app_calculator_template;
extern struct app_template app_squares_template;
extern struct app_template app_kernmsg_template;
struct {
const char *name;
@ -509,6 +533,10 @@ struct {
{
"squares",
&app_squares_template,
},
{
"kernmsg",
&app_kernmsg_template,
}
};
#define NUM_KNOWN_APPS (sizeof(known_apps)/sizeof(known_apps[0]))

View file

@ -1,10 +1,7 @@
#include <stddef.h>
#include <stdint.h>
#include "app.h"
#include "font.h"
#include "keyboard.h"
#include "ram.h"
#include "unicode.h"
#include "std.h"
#define FONT_TEX_NUM_PIXELS 10*20
@ -13,49 +10,29 @@ struct app_kernmsg {
size_t width;
size_t height;
struct kernmsg_iter msg_view;
struct Component *up;
struct Component *down;
struct Component *canvas;
};
void *app_kernmsg_create(size_t width, size_t height, void *arg) {
(void)arg;
struct ppn ppn;
if (!ram_alloc_frame(&ppn, RAM_PAGE_NORMAL)) {
return NULL;
}
struct app_kernmsg *app = ppn_to_pointer(ppn);
app->width = width;
app->height = height;
kernmsg_iter_init(&app->msg_view);
return app;
}
void app_kernmsg_destroy(void *self) {
struct app_kernmsg *app = self;
ram_free(ppn_from_aligned_pa(pa_from_pointer(app)));
}
static void app_kernmsg_redraw(struct app_kernmsg *app) {
app_draw_rect(app, COLOR_LUMA(0), NULL);
app_canvas_draw_rect(app, app->canvas, COLOR_LUMA(0), NULL);
const uint8_t *msg;
struct kernmsg_iter it = app->msg_view;
size_t y = 0;
while (kernmsg_iter_next(&it, &msg)) {
app_draw_text(app, msg, 0, y, COLOR_LUMA(255), COLOR_LUMA(0));
app_canvas_draw_text(app, app->canvas, (const char*)msg, 0, y, COLOR_LUMA(255), COLOR_LUMA(0));
y += app_text_height();
if (y >= app->height) {
break;
}
}
app_component_redraw(app, app->canvas);
}
void app_kernmsg_init(void *self) {
void app_kernmsg_on_click(void *self, struct Component *btn) {
struct app_kernmsg *app = self;
app_kernmsg_redraw(app);
}
void app_kernmsg_event_keyboard(void *self, struct key_event ev) {
struct app_kernmsg *app = self;
if (ev.code == KEY_ARROW_UP && ev.pressed && app->msg_view.coff > 0) {
if (btn == app->up && app->msg_view.coff > 0) {
struct kernmsg_iter it;
kernmsg_iter_init(&it);
while (1) {
@ -67,8 +44,48 @@ void app_kernmsg_event_keyboard(void *self, struct key_event ev) {
}
}
app_kernmsg_redraw(app);
} else if (ev.code == KEY_ARROW_DOWN && ev.pressed) {
} else if (btn == app->down) {
kernmsg_iter_next(&app->msg_view, NULL);
app_kernmsg_redraw(app);
}
}
struct AppCreation app_kernmsg_create(size_t width, size_t height, void *arg) {
(void)arg;
struct ppn ppn;
if (!ram_alloc_frame(&ppn, RAM_PAGE_NORMAL)) {
return (struct AppCreation){ 0 };
}
struct app_kernmsg *app = ppn_to_pointer(ppn);
struct Component *up = app_component_new_button("up", app_kernmsg_on_click);
struct Component *down = app_component_new_button("down", app_kernmsg_on_click);
struct Component *canvas = app_component_new_canvas(300, 300);
app->width = 300;
app->height = 300;
up->next = down;
down->next = canvas;
canvas->next = NULL;
app->up = up;
app->down = down;
app->canvas = canvas;
kernmsg_iter_init(&app->msg_view);
return (struct AppCreation) { .ptr = app, .root = up };
}
void app_kernmsg_destroy(void *self) {
struct app_kernmsg *app = self;
ram_free(ppn_from_aligned_pa(pa_from_pointer(app)));
}
void app_kernmsg_init(void *self) {
struct app_kernmsg *app = self;
app_kernmsg_redraw(app);
}
struct app_template app_kernmsg_template = {
.create = app_kernmsg_create,
.destroy = app_kernmsg_destroy,
.init = app_kernmsg_init
};