aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoremersion <contact@emersion.fr>2018-02-01 21:41:15 +0100
committerGitHub <noreply@github.com>2018-02-01 21:41:15 +0100
commita43555d7f57845e5a3da519cb3dddc55c9e79c1f (patch)
treea4576d0175ea6b36ed713c92bf3b307fa7986ee2
parent42ec696b82bfd7ab5f6d0804b4c5f7a681543c50 (diff)
parentcd925f496c2e1f644de0ff7f79f7dce49759e769 (diff)
Merge pull request #598 from Ongy/screenshot_transform
Screenshot transform
-rw-r--r--examples/screenshot.c91
1 files changed, 81 insertions, 10 deletions
diff --git a/examples/screenshot.c b/examples/screenshot.c
index ba225023..7de2ab8e 100644
--- a/examples/screenshot.c
+++ b/examples/screenshot.c
@@ -48,6 +48,7 @@ struct screenshooter_output {
struct wl_output *output;
struct wl_buffer *buffer;
int width, height, offset_x, offset_y;
+ enum wl_output_transform transform;
void *data;
struct wl_list link;
};
@@ -60,6 +61,7 @@ static void output_handle_geometry(void *data, struct wl_output *wl_output,
if (wl_output == output->output) {
output->offset_x = x;
output->offset_y = y;
+ output->transform = transform;
}
}
@@ -159,14 +161,75 @@ static void write_image(const char *filename, int width, int height) {
struct screenshooter_output *output, *next;
wl_list_for_each_safe(output, next, &output_list, link) {
int output_stride = output->width * 4;
- void *s = output->data;
- void *d = data + (output->offset_y - min_y) * buffer_stride +
- (output->offset_x - min_x) * 4;
-
- for (int i = 0; i < output->height; i++) {
- memcpy(d, s, output_stride);
- d += buffer_stride;
- s += output_stride;
+ uint32_t *src = (uint32_t *)output->data;
+ uint32_t *dst = (uint32_t *)(data +
+ (output->offset_y - min_y) * buffer_stride +
+ (output->offset_x - min_x) * 4);
+
+ switch (output->transform) {
+ case WL_OUTPUT_TRANSFORM_NORMAL:
+ for (int i = 0; i < output->height; i++) {
+ memcpy(dst, src, output_stride);
+ dst += width;
+ src += output->width;
+ }
+ break;
+ case WL_OUTPUT_TRANSFORM_FLIPPED:
+ for (int i = 0; i < output->height; ++i) {
+ for (int j = 0; j < output->width; ++j) {
+ dst[i * width + j] =
+ src[i * output->width + output->width - 1 - j];
+ }
+ }
+ break;
+ case WL_OUTPUT_TRANSFORM_90:
+ for (int i = 0; i < output->width; ++i) {
+ for (int j = 0; j < output->height; ++j) {
+ dst[i * width + j] =
+ src[j * output->width + output->width - 1 - i];
+ }
+ }
+ break;
+ case WL_OUTPUT_TRANSFORM_FLIPPED_90:
+ for (int i = 0; i < output->width; ++i) {
+ for (int j = 0; j < output->height; ++j) {
+ dst[i * width + j] =
+ src[(output->height - 1 - j) * output->width + output->width - 1 - i];
+ }
+ }
+ break;
+ case WL_OUTPUT_TRANSFORM_180:
+ for (int i = 0; i < output->height; ++i) {
+ for (int j = 0; j < output->width; ++j) {
+ dst[i * width + j] =
+ src[(output->height - 1 - i) * output->width + output->width - 1 - j];
+ }
+ }
+ break;
+ case WL_OUTPUT_TRANSFORM_FLIPPED_180:
+ for (int i = 0; i < output->height; ++i) {
+ for (int j = 0; j < output->width; ++j) {
+ dst[i * width + j] =
+ src[(output->height - 1 - i) * output->width + j];
+ }
+ }
+ break;
+ case WL_OUTPUT_TRANSFORM_270:
+ for (int i = 0; i < output->width; ++i) {
+ for (int j = 0; j < output->height; ++j) {
+ dst[i * width + j] =
+ src[(output->height - 1 - j) * output->width + i];
+ }
+ }
+ break;
+ case WL_OUTPUT_TRANSFORM_FLIPPED_270:
+ for (int i = 0; i < output->width; ++i) {
+ for (int j = 0; j < output->height; ++j) {
+ dst[i * width + j] =
+ src[j * output->width + i];
+ }
+ }
+ break;
}
free(output);
@@ -211,15 +274,23 @@ static void write_image(const char *filename, int width, int height) {
}
static int set_buffer_size(int *width, int *height) {
+ int owidth, oheight;
min_x = min_y = INT_MAX;
max_x = max_y = INT_MIN;
struct screenshooter_output *output;
wl_list_for_each(output, &output_list, link) {
+ if (output->transform & 0x1) {
+ owidth = output->height;
+ oheight = output->width;
+ } else {
+ owidth = output->width;
+ oheight = output->height;
+ }
min_x = MIN(min_x, output->offset_x);
min_y = MIN(min_y, output->offset_y);
- max_x = MAX(max_x, output->offset_x + output->width);
- max_y = MAX(max_y, output->offset_y + output->height);
+ max_x = MAX(max_x, output->offset_x + owidth);
+ max_y = MAX(max_y, output->offset_y + oheight);
}
if (max_x <= min_x || max_y <= min_y) {