diff --git a/userspace/compositor.c b/userspace/compositor.c index bcb8dc29..c526c72e 100644 --- a/userspace/compositor.c +++ b/userspace/compositor.c @@ -40,6 +40,7 @@ void spin_unlock(int volatile * lock) { window_t * windows[0x10000]; +volatile uint8_t screenshot_next_frame = 0; sprite_t * sprites[128]; @@ -1131,6 +1132,9 @@ void * process_requests(void * garbage) { #if 1 if (packet->buttons & MOUSE_BUTTON_MIDDLE) { printf("middle click @%dx%d!\n", mouse_x / MOUSE_SCALE, mouse_y / MOUSE_SCALE); + screenshot_next_frame = 1; + printf("Screenshot, plz?\n"); +#if 0 window_t * focused = focused_window(); if (focused) { if (focused->z != 0 && focused->z != 0xFFFF) { @@ -1138,6 +1142,7 @@ void * process_requests(void * garbage) { } redraw_region_slow(0,0,ctx->width,ctx->height); } +#endif } #endif #endif @@ -1169,6 +1174,15 @@ void * redraw_thread(void * derp) { redraw_cursor(); spin_unlock(&am_drawing); flip(ctx); + if (screenshot_next_frame) { + screenshot_next_frame = 0; + + printf("Going for screenshot...\n"); + + FILE * screenshot = fopen("/usr/share/screenshot.png", "w"); + context_to_png(screenshot, ctx); + fclose(screenshot); + } syscall_yield(); } } diff --git a/userspace/lib/graphics.c b/userspace/lib/graphics.c index a4736026..593877fd 100644 --- a/userspace/lib/graphics.c +++ b/userspace/lib/graphics.c @@ -215,6 +215,59 @@ int load_sprite_png(sprite_t * sprite, char * file) { } +void context_to_png(FILE * file, gfx_context_t * ctx) { + png_structp png_ptr = NULL; + png_infop info_ptr = NULL; + int32_t x, y; + + png_byte ** row_pointers = NULL; + + int status = -1; + int depth = 8; + + png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); + info_ptr = png_create_info_struct(png_ptr); + + if (setjmp(png_jmpbuf(png_ptr))) { + goto png_write_failure; + } + + png_set_IHDR(png_ptr, info_ptr, + ctx->width, ctx->height, depth, + PNG_COLOR_TYPE_RGB_ALPHA, PNG_INTERLACE_NONE, + PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); + + row_pointers = png_malloc(png_ptr, ctx->height * sizeof(png_byte *)); + for (y = 0; y < ctx->height; ++y) { + png_byte * row = png_malloc(png_ptr, sizeof(uint8_t) * ctx->width * sizeof(uint32_t)); + row_pointers[y] = row; + for (x = 0; x < ctx->width; ++x) { + uint32_t pixel = GFX(ctx, x, y); + *row++ = _RED(pixel); + *row++ = _GRE(pixel); + *row++ = _BLU(pixel); + *row++ = _ALP(pixel); + } + } + + png_init_io(png_ptr, file); + png_set_rows(png_ptr, info_ptr, row_pointers); + png_write_png(png_ptr, info_ptr, PNG_TRANSFORM_IDENTITY, NULL); + + for (y = 0; y < ctx->height; y++) { + png_free(png_ptr, row_pointers[y]); + } + png_free(png_ptr, row_pointers); + + fprintf(stderr, "Done writing PNG.\n"); + return; + + png_write_failure: + fprintf(stderr, "There was an exception while trying to write out a PNG file :(\n"); + return; +} + + static inline int32_t min(int32_t a, int32_t b) { return (a < b) ? a : b; }