From 072ebb56323baf441e8178615c4b883033c54d50 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juhani=20Krekel=C3=A4?= Date: Tue, 16 Nov 2021 06:29:24 +0200 Subject: [PATCH] Further bringup and drawing routines --- sortix.c | 214 +++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 208 insertions(+), 6 deletions(-) diff --git a/sortix.c b/sortix.c index dc9712a..4c526e6 100644 --- a/sortix.c +++ b/sortix.c @@ -8,35 +8,237 @@ #ifdef GRDRV_SORTIX -#include #include //debg #include +#include + +#include +#include #include "links.h" -struct display_connection* sortix_display; +static int default_window_width = 600; +static int default_window_height = 500; -unsigned char *sortix_init_driver(unsigned char *param, unsigned char *display) +static struct display_connection* connection; +static struct display_event_handlers event_handlers; + +struct graphics_driver sortix_driver; + +static void sortix_process_events(void *data) +{ + (void) data; + warnx("sortix_process_events");//debg + while (display_poll_event(connection, &event_handlers) == 0); +} + +static unsigned char *sortix_init_driver(unsigned char *param, unsigned char *display) { if (param && *param) errx(1, "param %s", param); if (display && *display) errx(1, "display %s", display); - sortix_display = display_connect_default(); - if (!sortix_display && errno == ECONNREFUSED) + connection = display_connect_default(); + if (!connection && errno == ECONNREFUSED) return "TODO: display_spawn"; - if ( !sortix_display ) + if (!connection) return "TODO: Proper error reporting"; + sortix_driver.get_color = get_color_fn(sortix_driver.depth); + + set_handlers(display_connection_fd(connection), sortix_process_events, NULL, NULL); + return NULL; } +struct window_data +{ + uint32_t window_id; + struct framebuffer fb; +}; + +static struct graphics_device *sortix_init_device(void) +{ + struct graphics_device *dev = mem_calloc(sizeof(struct graphics_device)); + + dev->size.x1 = 0; + dev->size.y1 = 0; + dev->size.x2 = default_window_width; + dev->size.y2 = default_window_height; + + dev->clip = dev->size; + + struct window_data *window_data = mem_calloc(sizeof(struct window_data)); + dev->driver_data = window_data; + window_data->window_id = 0; + + // TODO: Overflow when multiplying + window_data->fb.buffer = mem_calloc(dev->size.x2 * dev->size.y2 * sizeof(uint32_t)); + window_data->fb.xres = dev->size.x2; + window_data->fb.yres = dev->size.y2; + window_data->fb.pitch = dev->size.x2; + + display_create_window(connection, window_data->window_id); + display_resize_window(connection, window_data->window_id, dev->size.x2, dev->size.y2); + display_show_window(connection, window_data->window_id); + + return dev; +} + +static void sortix_shutdown_device(struct graphics_device *dev) +{ + struct window_data *window_data = dev->driver_data; + display_destroy_window(connection, window_data->window_id); + free(window_data); +} + +static void sortix_shutdown_driver(void) +{ + display_disconnect(connection); +} + +static void sortix_after_fork(void) +{ + if (connection) + display_disconnect(connection); +} + +static unsigned char *sortix_get_driver_param(void) +{ + return NULL; //TODO: driver parameters? +} + +static int sortix_get_empty_bitmap(struct bitmap *dest) +{ + // TODO: Overflow when multiplying + dest->data = mem_alloc_mayfail((size_t)dest->x * (size_t)dest->y * sizeof(uint32_t)); + if (!dest->data) + return -1; + // TODO: Overflow when multiplying + dest->skip = (ssize_t)dest->x * sizeof(uint32_t); + dest->flags = 0; + return 0; +} + +static void sortix_register_bitmap(struct bitmap *bmp) +{ +} + +static void *sortix_prepare_strip(struct bitmap *bmp, int top, int lines) +{ + if (!bmp->data) + return NULL; + // TODO: Overflow when multiplying + return ((unsigned char *)bmp->data) + bmp->skip * top; +} + +static void sortix_commit_strip(struct bitmap *bmp, int top, int lines) +{ +} + +static void sortix_unregister_bitmap(struct bitmap *bmp) +{ + if (bmp->data) + mem_free(bmp->data); +} + +static void sortix_draw_bitmap(struct graphics_device *dev, struct bitmap *bmp, int x1, int y1) +{ + struct window_data *window_data = dev->driver_data; + + warnx("sortix_draw_bitmap(%p, %p, %i, %i)", dev, bmp, x1, y1); //debg + size_t width = bmp->x; + size_t height = bmp->y; + + for (size_t y = 0; y < height; y++) { + if (window_data->fb.yres <= y1 + y) continue; + for (size_t x = 0; x < width; x++) { + if (window_data->fb.xres <= x1 + x) continue; + void *pixel_data = ((unsigned char*)bmp->data) + y * bmp->skip + x * sizeof(uint32_t); + uint32_t pixel; + memcpy(&pixel, pixel_data, sizeof(uint32_t)); + // Set the alpha channel (see sortix_fill_area() for further details) + pixel |= 0xff000000; + window_data->fb.buffer[(y1 + y) * window_data->fb.pitch + x + x1] = pixel; + } + } + display_render_window(connection, window_data->window_id, 0, 0, window_data->fb.xres, window_data->fb.yres, window_data->fb.buffer); +} + +static void sortix_fill_area(struct graphics_device *dev, int x1, int y1, int x2, int y2, long color) +{ + struct window_data *window_data = dev->driver_data; + + size_t width = x2 - x1; + size_t height = y2 - y1; + + // Links uses a pixel format where the top byte is clear + // Sortix stores alpha there, so set it to 255 + uint32_t pixel = color | 0xff000000; + + for (size_t y = 0; y < height; y++) { + for (size_t x = 0; x < width; x++) + window_data->fb.buffer[(y1 + y) * window_data->fb.pitch + x + x1] = pixel; + } + display_render_window(connection, window_data->window_id, 0, 0, window_data->fb.xres, window_data->fb.yres, window_data->fb.buffer); +} + +static void sortix_draw_hline(struct graphics_device *dev, int x1, int y, int x2, long color) +{ + sortix_fill_area(dev, x1, y, x2, y, color); +} + +static void sortix_draw_vline(struct graphics_device *dev, int x, int y1, int y2, long color) +{ + sortix_fill_area(dev, x, y1, x, y2, color); +} + +static void sortix_set_title(struct graphics_device *dev, unsigned char *title) +{ + struct window_data *window_data = dev->driver_data; + display_title_window(connection, window_data->window_id, title); +} + struct graphics_driver sortix_driver = { (unsigned char *)"sortix", sortix_init_driver, + sortix_init_device, + sortix_shutdown_device, + sortix_shutdown_driver, + NULL, // emergency_shutdown + sortix_after_fork, + sortix_get_driver_param, + NULL, // get_af_unix_name + NULL, // get_margin + NULL, // set_margin + sortix_get_empty_bitmap, + sortix_register_bitmap, + sortix_prepare_strip, + sortix_commit_strip, + sortix_unregister_bitmap, + sortix_draw_bitmap, + NULL, // get_color, set in sortix_init_driver() + sortix_fill_area, + sortix_draw_hline, + sortix_draw_vline, + NULL, // scroll + NULL, // set_clip_area + NULL, // flush + NULL, // block + NULL, // unblock + NULL, // set_palette + NULL, // get_real_colors + sortix_set_title, + NULL, // exec + NULL, // set_clipboard_text + NULL, // get_clipboard_text + (24 << 3) | 4, // depth: 24bpp, 4 bytes per pixel + 0, 0, // size (x, y), unused + GD_DONT_USE_SCROLL, //flags + NULL, // param }; #endif /* GRDRV_SORTIX */