diff --git a/examples/meson.build b/examples/meson.build index 292ab053..a29a3310 100644 --- a/examples/meson.build +++ b/examples/meson.build @@ -26,5 +26,5 @@ executable( executable( 'screenshot', 'screenshot.c', - dependencies: [wayland_client, wlr_protos, dependency('cairo')], + dependencies: [wayland_client, wlr_protos], ) diff --git a/examples/screenshot.c b/examples/screenshot.c index f70b9b56..253638c9 100644 --- a/examples/screenshot.c +++ b/examples/screenshot.c @@ -33,7 +33,6 @@ #include #include #include -#include #include #include "../backend/wayland/os-compatibility.c" @@ -174,11 +173,20 @@ create_shm_buffer(int width, int height, void **data_out) return buffer; } +static void argb_to_rgba(uint32_t *data, size_t height, size_t stride) { + size_t n = height*stride/4; + for (size_t i = 0; i < n; ++i) { + uint32_t v = data[i]; + uint32_t rgb = v & 0x00ffffff; + uint32_t a = (v & 0xff000000) >> 24; + data[i] = (rgb << 8) | a; + } +} + static void write_png(int width, int height) { int output_stride, buffer_stride, i; - cairo_surface_t *surface; void *data, *d, *s; struct screenshooter_output *output, *next; @@ -203,11 +211,13 @@ write_png(int width, int height) free(output); } - surface = cairo_image_surface_create_for_data(data, - CAIRO_FORMAT_RGB24, - width, height, buffer_stride); - cairo_surface_write_to_png(surface, "wayland-screenshot.png"); - cairo_surface_destroy(surface); + argb_to_rgba(data, height, buffer_stride); + + // TODO: call convert + FILE *f = fopen("wayland-screenshot", "w"); + fwrite(data, buffer_stride * height, 1, f); + fclose(f); + free(data); } diff --git a/include/wlr/types/wlr_output.h b/include/wlr/types/wlr_output.h index 7fab1cf6..ab3be5c7 100644 --- a/include/wlr/types/wlr_output.h +++ b/include/wlr/types/wlr_output.h @@ -71,6 +71,10 @@ void wlr_output_swap_buffers(struct wlr_output *output); void wlr_output_set_gamma(struct wlr_output *output, uint16_t size, uint16_t *r, uint16_t *g, uint16_t *b); uint16_t wlr_output_get_gamma_size(struct wlr_output *output); + +/** + * Reads all pixels from the output and stores them as ARGB. + */ void wlr_output_read_pixels(struct wlr_output *output, void *out_data); #endif diff --git a/types/wlr_output.c b/types/wlr_output.c index 85357d2a..1db63151 100644 --- a/types/wlr_output.c +++ b/types/wlr_output.c @@ -8,7 +8,6 @@ #include #include #include -#include #include #include #include @@ -252,9 +251,19 @@ uint16_t wlr_output_get_gamma_size(struct wlr_output *output) { return output->impl->get_gamma_size(output); } -void wlr_output_read_pixels(struct wlr_output *output, void *out_data) { - // TODO: is wlr_output_make_current required? - wlr_output_make_current(output); - glReadPixels(0, 0, output->width, output->height, GL_BGRA_EXT, - GL_UNSIGNED_BYTE, out_data); +static void rgba_to_argb(uint32_t *data, size_t height, size_t stride) { + size_t n = height*stride/4; + for (size_t i = 0; i < n; ++i) { + uint32_t v = data[i]; + uint32_t rgb = (v & 0xffffff00) >> 8; + uint32_t a = v & 0x000000ff; + data[i] = rgb | (a << 24); + } +} + +void wlr_output_read_pixels(struct wlr_output *output, void *out_data) { + wlr_output_make_current(output); + glReadPixels(0, 0, output->width, output->height, GL_RGBA, GL_UNSIGNED_BYTE, + out_data); + rgba_to_argb(out_data, output->height, output->width*4); }