home | blog | art | now | git gpg | email | rss

splashdown

Minimal bootsplash program
git clone https://pollux.codes/git/splashdown.git
Log | Files | Refs | README | LICENSE
commit dee31183e886558f7bfcec05ddfd70ee49096940
parent 03ab864bf4cf2b837d8261780251594e506fb354
Author: Pollux <pollux@pollux.codes>
Date:   Sat,  7 Mar 2026 15:12:39 +0000

style: Format code

Signed-off-by: Pollux <pollux@pollux.codes>

Diffstat:
Msplashdown-openrc-plugin.c | 53++++++++++++++++++++++++++++++-----------------------
Msplashdown.c | 191+++++++++++++++++++++++++++++++++++++++++++++++++------------------------------
2 files changed, 149 insertions(+), 95 deletions(-)

diff --git a/splashdown-openrc-plugin.c b/splashdown-openrc-plugin.c @@ -1,3 +1,4 @@ + /* * splashdown - minimal bootsplash program * Copyright (C) 2026 Pollux <pollux@pollux.codes> @@ -27,12 +28,15 @@ #define LENGTH(X) (sizeof (X) / sizeof (X)[0]) +void die(const char *fmt, ...); +int run_splashdown(char *message, char *service); + #include "config.h" void die(const char *fmt, ...) { - va_list ap; - int saved_errno; + va_list ap; + int saved_errno; saved_errno = errno; @@ -46,9 +50,11 @@ die(const char *fmt, ...) { exit(1); } -int run_splashdown(char* message, char* service) { +int +run_splashdown(char *message, char *service) { + + char cmd[128]; - char cmd[128]; cmd[0] = '\0'; strcpy(cmd, "splashdown '"); @@ -56,20 +62,21 @@ int run_splashdown(char* message, char* service) { strcat(cmd, service); strcat(cmd, "...'"); - int rv = system(cmd); + int rv = system(cmd); return rv; } int rc_plugin_hook(RC_HOOK hook, const char *name) { - - int rv = 0; - char name_cpy[256]; + int rv = 0; + + char name_cpy[256]; + strcpy(name_cpy, name); - char* runlevel = rc_runlevel_get(); + char *runlevel = rc_runlevel_get(); for(uint32_t i = 0; i < LENGTH(openrc_exclude); i++) { if(!strcmp(name_cpy, openrc_exclude[i])) { @@ -77,22 +84,22 @@ rc_plugin_hook(RC_HOOK hook, const char *name) { } } - switch(hook) { - case RC_HOOK_SERVICE_START_NOW: - if(run_splashdown("Starting ", name_cpy)){ - rv=1; - } - break; - case RC_HOOK_SERVICE_STOP_NOW: - if(run_splashdown("Stopping ", name_cpy)){ - rv=1; - } - break; - default: - break; + switch (hook) { + case RC_HOOK_SERVICE_START_NOW: + if(run_splashdown("Starting ", name_cpy)) { + rv = 1; + } + break; + case RC_HOOK_SERVICE_STOP_NOW: + if(run_splashdown("Stopping ", name_cpy)) { + rv = 1; + } + break; + default: + break; } -end: + end: free(runlevel); return rv; diff --git a/splashdown.c b/splashdown.c @@ -1,3 +1,4 @@ + /* * splashdown - minimal bootsplash program * Copyright (C) 2026 Pollux <pollux@pollux.codes> @@ -39,24 +40,30 @@ #define MIN(A, B) ((A) < (B) ? (A) : (B)) struct image_buffer { - uint32_t width; - uint32_t height; - uint32_t *data; + uint32_t width; + uint32_t height; + uint32_t *data; }; -void die(const char *fmt, ...); -int mmap_fb(struct image_buffer *fb); -void draw_banner(struct image_buffer src, int srcx, int srcy, int srcw, int srch, struct image_buffer dest, int destx, int desty); -void draw_glyph(struct image_buffer buffer, FT_Bitmap bitmap, int x, int y, uint32_t color); -void draw_text(struct image_buffer buffer, int x, int y, FT_Face face, uint32_t color, const char* text, size_t len); -int read_jpeg(const char* path, struct image_buffer *buffer); +void die(const char *fmt, ...); +void draw_buffer(struct image_buffer src, uint32_t srcx, + uint32_t srcy, uint32_t srcw, uint32_t srch, + struct image_buffer dest, uint32_t destx, + uint32_t desty); +void draw_glyph(struct image_buffer buffer, FT_Bitmap bitmap, int x, + int y, uint32_t color); +void draw_text(struct image_buffer buffer, int x, int y, + FT_Face face, uint32_t color, const char *text, + size_t len); +int mmap_fb(struct image_buffer *fb); +int read_jpeg(const char *path, struct image_buffer *buffer); #include "config.h" void die(const char *fmt, ...) { - va_list ap; - int saved_errno; + va_list ap; + int saved_errno; saved_errno = errno; @@ -71,7 +78,9 @@ die(const char *fmt, ...) { } void -draw_buffer(struct image_buffer src, uint32_t srcx, uint32_t srcy, uint32_t srcw, uint32_t srch, struct image_buffer dest, uint32_t destx, uint32_t desty) { +draw_buffer(struct image_buffer src, uint32_t srcx, uint32_t srcy, + uint32_t srcw, uint32_t srch, struct image_buffer dest, + uint32_t destx, uint32_t desty) { srcw = MIN(srcw, src.width); srch = MIN(srch, src.height); @@ -79,46 +88,56 @@ draw_buffer(struct image_buffer src, uint32_t srcx, uint32_t srcy, uint32_t srcw srcw = MIN(srcw, dest.width - destx); srch = MIN(srch, dest.height - desty); - int row_bytes = srcw * sizeof(uint32_t); + int row_bytes = srcw * sizeof(uint32_t); + for(uint32_t y = 0; y < srch; y++) { - memcpy(dest.data + dest.width*(desty+y) + destx, src.data + src.width*(y + srcy) + srcx, row_bytes); + memcpy(dest.data + dest.width * (desty + y) + destx, + src.data + src.width * (y + srcy) + srcx, row_bytes); } } void -draw_glyph(struct image_buffer buffer, FT_Bitmap bitmap, int x, int y, uint32_t color) { +draw_glyph(struct image_buffer buffer, FT_Bitmap bitmap, int x, int y, + uint32_t color) { for(uint32_t py = 0; py < bitmap.rows; py++) { for(uint32_t px = 0; px < bitmap.width; px++) { - uint8_t a = bitmap.buffer[bitmap.pitch * py + px]; - uint32_t bg = buffer.data[(y+py)*buffer.width + x + px]; + uint8_t a = + bitmap.buffer[bitmap.pitch * py + px]; + uint32_t bg = + buffer.data[(y + py) * buffer.width + x + px]; - uint16_t r = bg >> 16 & 0xff; - uint16_t g = bg >> 8 & 0xff; - uint16_t b = bg >> 0 & 0xff; + uint16_t r = bg >> 16 & 0xff; + uint16_t g = bg >> 8 & 0xff; + uint16_t b = bg >> 0 & 0xff; - uint16_t r_t = color >> 16 & 0xff; - uint16_t g_t = color >> 8 & 0xff; - uint16_t b_t = color >> 0 & 0xff; + uint16_t r_t = color >> 16 & 0xff; + uint16_t g_t = color >> 8 & 0xff; + uint16_t b_t = color >> 0 & 0xff; - r = (r * (255-a) + r_t * a) / 255; - g = (g * (255-a) + g_t * a) / 255; - b = (b * (255-a) + b_t * a) / 255; + r = (r * (255 - a) + r_t * a) / 255; + g = (g * (255 - a) + g_t * a) / 255; + b = (b * (255 - a) + b_t * a) / 255; - buffer.data[(y+py)*buffer.width + x + px] = b | g << 8 | r << 16; + buffer.data[(y + py) * buffer.width + x + px] = + b | g << 8 | r << 16; } } } void -draw_text(struct image_buffer buffer, int x, int y, FT_Face face, uint32_t color, const char* text, size_t len) { +draw_text(struct image_buffer buffer, int x, int y, FT_Face face, + uint32_t color, const char *text, size_t len) { + + int e, pen_x = x; - int e, pen_x = x; - for(uint32_t n = 0; n < len; n++) { e = FT_Load_Char(face, text[n], FT_LOAD_RENDER); - if (e) continue; + if(e) + continue; - draw_glyph(buffer, face->glyph->bitmap, pen_x + face->glyph->bitmap_left, y - face->glyph->bitmap_top, color); + draw_glyph(buffer, face->glyph->bitmap, + pen_x + face->glyph->bitmap_left, + y - face->glyph->bitmap_top, color); pen_x += face->glyph->advance.x >> 6; } @@ -126,24 +145,29 @@ draw_text(struct image_buffer buffer, int x, int y, FT_Face face, uint32_t color int mmap_fb(struct image_buffer *fb) { - int fd = open(FB_DEV, O_RDWR); + int fd = open(FB_DEV, O_RDWR); struct fb_var_screeninfo fb_info; - int e = ioctl(fd, FBIOGET_VSCREENINFO, &fb_info); - if(e) return -1; + int e = ioctl(fd, FBIOGET_VSCREENINFO, &fb_info); + + if(e) + return -1; fb->width = fb_info.xres; fb->height = fb_info.yres; - uint32_t fb_size = fb->width * fb->height * 4; - fb->data = mmap(NULL, fb_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); + uint32_t fb_size = fb->width * fb->height * 4; + + fb->data = + mmap(NULL, fb_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); close(fd); return 0; } int -read_jpeg(const char* path, struct image_buffer *buffer) { - FILE *fd; +read_jpeg(const char *path, struct image_buffer *buffer) { + FILE *fd; fd = fopen(path, "rb"); - if(fd == NULL) return -1; + if(fd == NULL) + return -1; struct jpeg_error_mgr jerr; struct jpeg_decompress_struct cinfo; @@ -152,36 +176,44 @@ read_jpeg(const char* path, struct image_buffer *buffer) { jpeg_create_decompress(&cinfo); jpeg_stdio_src(&cinfo, fd); - if(jpeg_read_header(&cinfo, TRUE) != JPEG_HEADER_OK) goto bail; - if(!jpeg_start_decompress(&cinfo)) goto bail; + if(jpeg_read_header(&cinfo, TRUE) != JPEG_HEADER_OK) + goto bail; + if(!jpeg_start_decompress(&cinfo)) + goto bail; buffer->width = cinfo.output_width; buffer->height = cinfo.output_height; - int pixels = buffer->width * buffer->height; + int pixels = buffer->width * buffer->height; + buffer->data = malloc(pixels * sizeof(uint32_t)); - int row_stride = cinfo.output_width * cinfo.output_components; + int row_stride = + cinfo.output_width * cinfo.output_components; - JSAMPARRAY working_buffer = (cinfo.mem->alloc_sarray)((j_common_ptr)&cinfo, JPOOL_IMAGE, row_stride, 1); + JSAMPARRAY working_buffer = + (cinfo.mem->alloc_sarray) ((j_common_ptr) & cinfo, JPOOL_IMAGE, + row_stride, 1); while(cinfo.output_scanline < cinfo.output_height) { if(jpeg_read_scanlines(&cinfo, working_buffer, 1) != 1) goto bail; for(uint32_t x = 0; x < cinfo.output_width; x++) - buffer->data[buffer->width*(cinfo.output_scanline-1) + x] = - (working_buffer[0][x*3+2] & 0xff) | - ((working_buffer[0][x*3+1] & 0xff) << 8) | - ((working_buffer[0][x*3] & 0xff) << 16); + buffer->data[buffer->width * + (cinfo.output_scanline - 1) + x] = + (working_buffer[0][x * 3 + 2] & 0xff) | + ((working_buffer[0][x * 3 + 1] & 0xff) << 8) | + ((working_buffer[0][x * 3] & 0xff) << 16); } jpeg_finish_decompress(&cinfo); jpeg_destroy_decompress(&cinfo); return 0; -bail: + bail: jpeg_destroy_decompress(&cinfo); - if(buffer->data) free(buffer->data); + if(buffer->data) + free(buffer->data); buffer->data = NULL; return -1; } @@ -189,52 +221,67 @@ bail: int main(const int argc, const char **argv) { - struct image_buffer splash_image = { .data=NULL }; - struct image_buffer framebuffer = { .data=NULL }; + struct image_buffer splash_image = {.data = NULL }; + struct image_buffer framebuffer = {.data = NULL }; + + const char *err = NULL; + + const char *text = NULL; - const char *err = NULL; + if(argc > 1) + text = argv[1]; - const char *text = NULL; - if(argc > 1) text = argv[1]; + FT_Library lib = NULL; + FT_Face face = NULL; - FT_Library lib = NULL; - FT_Face face = NULL; - if(FT_Init_FreeType(&lib)) die("Could not load freetype2."); + if(FT_Init_FreeType(&lib)) + die("Could not load freetype2."); for(uint32_t i = 0; i < LENGTH(fonts); i++) - if(!FT_New_Face(lib, fonts[i], 0, &face)) break; + if(!FT_New_Face(lib, fonts[i], 0, &face)) + break; if(!face) { err = "Could not locate font."; goto cleanup; } - if(FT_Set_Pixel_Sizes(face, 0, font_size)){ + if(FT_Set_Pixel_Sizes(face, 0, font_size)) { err = "Could not set font properties."; goto cleanup; } for(uint32_t i = 0; i < LENGTH(image_paths); i++) - if(read_jpeg(image_paths[i], &splash_image)) break; + if(read_jpeg(image_paths[i], &splash_image)) + break; if(!splash_image.data) { err = "Could not open image."; goto cleanup; } - if(mmap_fb(&framebuffer)){ + if(mmap_fb(&framebuffer)) { err = "Could not open framebuffer."; goto cleanup; } if(text) - draw_text(splash_image, margin_x, margin_y, face, font_color, text, strlen(text)); - draw_buffer(splash_image, 0, 0, splash_image.width, splash_image.height, framebuffer, 0, 0); - -cleanup: - if(framebuffer.data) munmap(framebuffer.data, framebuffer.width*framebuffer.height*sizeof(uint32_t)); - if(splash_image.data) free(splash_image.data); - if(face) FT_Done_Face(face); - if(lib) FT_Done_FreeType(lib); - if(err) die(err); + draw_text(splash_image, margin_x, margin_y, face, font_color, + text, strlen(text)); + draw_buffer(splash_image, 0, 0, splash_image.width, splash_image.height, + framebuffer, 0, 0); + + cleanup: + if(framebuffer.data) + munmap(framebuffer.data, + framebuffer.width * framebuffer.height * + sizeof(uint32_t)); + if(splash_image.data) + free(splash_image.data); + if(face) + FT_Done_Face(face); + if(lib) + FT_Done_FreeType(lib); + if(err) + die(err); return 0; }