2021-08-28 18:00:36 +00:00
|
|
|
/* sortix.c
|
|
|
|
* Sortix display(1) support
|
|
|
|
* (c) 2021 Juhani 'nortti' Krekelä
|
|
|
|
* This file is a part of the Links program, released under GPL.
|
|
|
|
*/
|
|
|
|
|
2021-11-27 22:24:36 +00:00
|
|
|
#include "cfg.h"
|
|
|
|
|
|
|
|
#ifdef GRDRV_SORTIX
|
|
|
|
|
2021-08-28 18:00:36 +00:00
|
|
|
#include <err.h> //debg
|
|
|
|
#include <errno.h>
|
2021-11-16 04:29:24 +00:00
|
|
|
#include <stdint.h>
|
|
|
|
|
|
|
|
#include <display.h>
|
|
|
|
#include <framebuffer.h>
|
2021-08-28 18:00:36 +00:00
|
|
|
|
2021-11-27 22:24:36 +00:00
|
|
|
#include "links.h"
|
|
|
|
|
2021-11-16 04:29:24 +00:00
|
|
|
static int default_window_width = 600;
|
|
|
|
static int default_window_height = 500;
|
|
|
|
|
|
|
|
static struct display_connection* connection;
|
|
|
|
static struct display_event_handlers event_handlers;
|
|
|
|
|
|
|
|
struct graphics_driver sortix_driver;
|
2021-08-28 18:00:36 +00:00
|
|
|
|
2021-11-16 04:29:24 +00:00
|
|
|
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)
|
2021-08-28 18:00:36 +00:00
|
|
|
{
|
|
|
|
if (param && *param)
|
|
|
|
errx(1, "param %s", param);
|
|
|
|
if (display && *display)
|
|
|
|
errx(1, "display %s", display);
|
|
|
|
|
2021-11-16 04:29:24 +00:00
|
|
|
connection = display_connect_default();
|
|
|
|
if (!connection && errno == ECONNREFUSED)
|
2021-08-28 18:00:36 +00:00
|
|
|
return "TODO: display_spawn";
|
|
|
|
|
2021-11-16 04:29:24 +00:00
|
|
|
if (!connection)
|
2021-08-28 18:00:36 +00:00
|
|
|
return "TODO: Proper error reporting";
|
|
|
|
|
2021-11-16 04:29:24 +00:00
|
|
|
sortix_driver.get_color = get_color_fn(sortix_driver.depth);
|
|
|
|
|
|
|
|
set_handlers(display_connection_fd(connection), sortix_process_events, NULL, NULL);
|
|
|
|
|
2021-08-28 18:00:36 +00:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2021-11-16 04:29:24 +00:00
|
|
|
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;
|
|
|
|
|
|
|
|
size_t width = bmp->x;
|
|
|
|
size_t height = bmp->y;
|
2021-11-16 06:08:47 +00:00
|
|
|
if (!width || !height)
|
|
|
|
return;
|
|
|
|
// TODO: Overflow when multiplying
|
|
|
|
uint32_t *buffer = mem_alloc(width * height * sizeof(uint32_t));
|
2021-11-16 04:29:24 +00:00
|
|
|
|
|
|
|
for (size_t y = 0; y < height; y++) {
|
|
|
|
for (size_t x = 0; x < width; x++) {
|
|
|
|
void *pixel_data = ((unsigned char*)bmp->data) + y * bmp->skip + x * sizeof(uint32_t);
|
|
|
|
uint32_t pixel;
|
|
|
|
memcpy(&pixel, pixel_data, sizeof(uint32_t));
|
2021-11-16 06:08:47 +00:00
|
|
|
// Set alpha (see sortix_fill_area() for more details)
|
2021-11-16 04:29:24 +00:00
|
|
|
pixel |= 0xff000000;
|
2021-11-16 06:08:47 +00:00
|
|
|
buffer[y * width + x] = pixel;
|
2021-11-16 04:29:24 +00:00
|
|
|
}
|
|
|
|
}
|
2021-11-16 06:08:47 +00:00
|
|
|
display_render_window(connection, window_data->window_id, x1, y1, width, height, buffer);
|
|
|
|
free(buffer);
|
2021-11-16 04:29:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
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;
|
2021-11-16 06:08:47 +00:00
|
|
|
if (!width || !height)
|
|
|
|
return;
|
|
|
|
// TODO: Overflow when multiplying
|
|
|
|
uint32_t *buffer = mem_alloc(width * height * sizeof(uint32_t));
|
2021-11-16 04:29:24 +00:00
|
|
|
|
|
|
|
// 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++)
|
2021-11-16 06:08:47 +00:00
|
|
|
buffer[y * width + x] = pixel;
|
2021-11-16 04:29:24 +00:00
|
|
|
}
|
2021-11-16 06:08:47 +00:00
|
|
|
display_render_window(connection, window_data->window_id, x1, y1, width, height, buffer);
|
|
|
|
free(buffer);
|
2021-11-16 04:29:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void sortix_draw_hline(struct graphics_device *dev, int x1, int y, int x2, long color)
|
|
|
|
{
|
2021-11-16 06:08:47 +00:00
|
|
|
sortix_fill_area(dev, x1, y, x2, y + 1, color);
|
2021-11-16 04:29:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void sortix_draw_vline(struct graphics_device *dev, int x, int y1, int y2, long color)
|
|
|
|
{
|
2021-11-16 06:08:47 +00:00
|
|
|
sortix_fill_area(dev, x, y1, x + 1, y2, color);
|
2021-11-16 04:29:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
2021-08-28 17:36:11 +00:00
|
|
|
struct graphics_driver sortix_driver =
|
|
|
|
{
|
2021-08-28 18:00:36 +00:00
|
|
|
(unsigned char *)"sortix",
|
|
|
|
sortix_init_driver,
|
2021-11-16 04:29:24 +00:00
|
|
|
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
|
2021-08-28 17:36:11 +00:00
|
|
|
};
|
2021-11-27 22:24:36 +00:00
|
|
|
|
|
|
|
#endif /* GRDRV_SORTIX */
|