mirror of
				https://gitlab.freedesktop.org/wlroots/wlroots.git
				synced 2025-11-03 09:01:40 -05:00 
			
		
		
		
	Merge pull request #598 from Ongy/screenshot_transform
Screenshot transform
This commit is contained in:
		
						commit
						a43555d7f5
					
				
					 1 changed files with 80 additions and 9 deletions
				
			
		| 
						 | 
					@ -48,6 +48,7 @@ struct screenshooter_output {
 | 
				
			||||||
	struct wl_output *output;
 | 
						struct wl_output *output;
 | 
				
			||||||
	struct wl_buffer *buffer;
 | 
						struct wl_buffer *buffer;
 | 
				
			||||||
	int width, height, offset_x, offset_y;
 | 
						int width, height, offset_x, offset_y;
 | 
				
			||||||
 | 
						enum wl_output_transform transform;
 | 
				
			||||||
	void *data;
 | 
						void *data;
 | 
				
			||||||
	struct wl_list link;
 | 
						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) {
 | 
						if (wl_output == output->output) {
 | 
				
			||||||
		output->offset_x = x;
 | 
							output->offset_x = x;
 | 
				
			||||||
		output->offset_y = y;
 | 
							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;
 | 
						struct screenshooter_output *output, *next;
 | 
				
			||||||
	wl_list_for_each_safe(output, next, &output_list, link) {
 | 
						wl_list_for_each_safe(output, next, &output_list, link) {
 | 
				
			||||||
		int output_stride = output->width * 4;
 | 
							int output_stride = output->width * 4;
 | 
				
			||||||
		void *s = output->data;
 | 
							uint32_t *src = (uint32_t *)output->data;
 | 
				
			||||||
		void *d = data + (output->offset_y - min_y) * buffer_stride +
 | 
							uint32_t *dst = (uint32_t *)(data +
 | 
				
			||||||
			(output->offset_x - min_x) * 4;
 | 
								(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++) {
 | 
								for (int i = 0; i < output->height; i++) {
 | 
				
			||||||
			memcpy(d, s, output_stride);
 | 
									memcpy(dst, src, output_stride);
 | 
				
			||||||
			d += buffer_stride;
 | 
									dst += width;
 | 
				
			||||||
			s += output_stride;
 | 
									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);
 | 
							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) {
 | 
					static int set_buffer_size(int *width, int *height) {
 | 
				
			||||||
 | 
						int owidth, oheight;
 | 
				
			||||||
	min_x = min_y = INT_MAX;
 | 
						min_x = min_y = INT_MAX;
 | 
				
			||||||
	max_x = max_y = INT_MIN;
 | 
						max_x = max_y = INT_MIN;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct screenshooter_output *output;
 | 
						struct screenshooter_output *output;
 | 
				
			||||||
	wl_list_for_each(output, &output_list, link) {
 | 
						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_x = MIN(min_x, output->offset_x);
 | 
				
			||||||
		min_y = MIN(min_y, output->offset_y);
 | 
							min_y = MIN(min_y, output->offset_y);
 | 
				
			||||||
		max_x = MAX(max_x, output->offset_x + output->width);
 | 
							max_x = MAX(max_x, output->offset_x + owidth);
 | 
				
			||||||
		max_y = MAX(max_y, output->offset_y + output->height);
 | 
							max_y = MAX(max_y, output->offset_y + oheight);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (max_x <= min_x || max_y <= min_y) {
 | 
						if (max_x <= min_x || max_y <= min_y) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue