#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; }