#include <errno.h>
#include <fcntl.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/epoll.h>
#include <sys/mman.h>
#include <sys/socket.h>
#include <sys/uio.h>
#include <shell.h>
#include <unistd.h>
#define array_size(a) (sizeof(a) / sizeof((a)[0]))
_Noreturn static void
die(const char *m)
{
fprintf(stderr, "%s\n", m);
exit(1);
}
static const char *norstrulde[] = {
" ",
" ",
" ## # # # ## ",
" ### ### ### ### ### ### # # # ### ### ",
" # # # # # # # # # # # # # # ",
" # # ### # ## ## # ### ## ### ## ",
" ",
};
#define BYTES_PER_PIXEL 4
static uint32_t
encode_color_xrgb(uint8_t r, uint8_t g, uint8_t b)
{
union {
uint32_t u;
uint8_t bytes[4];
} x = {
.bytes = { b, g, r, 0 },
};
return x.u;
}
static void
draw_background(void *mem, uint32_t width, uint32_t height)
{
uint32_t color = encode_color_xrgb(0xff, 0xff, 0xff);
uint32_t *pixel = mem;
for (uint32_t y = 0; y < height; y++)
for (uint32_t x = 0; x < width; x++)
*pixel++ = color;
}
static void
draw_norstrulde(void *mem, uint32_t width, uint32_t x, uint32_t y)
{
uint32_t *pixels = mem;
uint32_t gray = encode_color_xrgb(0x48, 0x48, 0x48);
uint32_t white = encode_color_xrgb(0xff, 0xff, 0xff);
for (int i = 0; i < array_size(norstrulde); i++)
for (int j = 0; j < strlen(norstrulde[i]); j++)
for (int m = 0; m < 16; m++)
for (int n = 0; n < 16; n++)
pixels[(120 + y + 16 * i + m) * width + (x + 16 * j + n)] =
(norstrulde[i][j] == ' ') ? gray : white;
}
static void
receive_welcome(int fd, struct shell_message_welcome *message)
{
ssize_t r = read(fd, message, sizeof(*message));
if (r != sizeof(*message))
die("Failed to read welcome message.");
if (message->class != SHELL_MESSAGE_WELCOME)
die("Failed to receive welcome.");
}
static void
send_show(int fd)
{
struct shell_message_show message = {
.class = SHELL_MESSAGE_SHOW,
};
ssize_t r = write(fd, &message, sizeof(message));
if (r != sizeof(message))
die("Failed to write show message.");
}
int
main(void)
{
uint32_t width, height;
{
struct shell_message_welcome message;
receive_welcome(3, &message);
width = message.width;
height = message.height;
}
size_t mem_size = 8 * width * height;
void *mem = mmap(NULL, mem_size, PROT_READ|PROT_WRITE, MAP_SHARED, 4, 0);
if (mem == MAP_FAILED)
die("Failed to create draw buffers for child process.");
close(4);
uint32_t x = 160;
uint32_t y = height / 2 - 160;
void *buffer = mem + 4 * width * height;
draw_background(buffer, width, height);
draw_norstrulde(buffer, width, x, y);
send_show(3);
sleep(5);
return 0;
}