| 
						
						
							
								
							
						
						
					 | 
					 | 
					@ -36,6 +36,12 @@ struct screenshooter { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						struct wl_listener destroy_listener; | 
					 | 
					 | 
					 | 
						struct wl_listener destroy_listener; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					}; | 
					 | 
					 | 
					 | 
					}; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					struct screenshooter_read_pixels { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						struct weston_read_pixels base; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						struct wl_buffer *buffer; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						struct wl_resource *resource; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					}; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					static void | 
					 | 
					 | 
					 | 
					static void | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					copy_bgra_yflip(uint8_t *dst, uint8_t *src, int height, | 
					 | 
					 | 
					 | 
					copy_bgra_yflip(uint8_t *dst, uint8_t *src, int height, | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							int dst_stride, int src_stride) | 
					 | 
					 | 
					 | 
							int dst_stride, int src_stride) | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
					 | 
					@ -81,6 +87,43 @@ copy_rgba_yflip(uint8_t *dst, uint8_t *src, int height, | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						} | 
					 | 
					 | 
					 | 
						} | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					} | 
					 | 
					 | 
					 | 
					} | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					static void | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					screenshooter_read_pixels_done(struct weston_read_pixels *base, | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
								       struct weston_output *output) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					{ | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						struct screenshooter_read_pixels *r = | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
							(struct screenshooter_read_pixels *) base; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						int32_t buffer_stride, output_stride; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						uint8_t *d, *s; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						buffer_stride = wl_shm_buffer_get_stride(r->buffer); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						output_stride = output->current->width * 4; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						d = wl_shm_buffer_get_data(r->buffer) + | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
							output->y * buffer_stride + output->x * 4; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						s = r->base.data + output_stride * (output->current->height - 1); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						switch (output->compositor->read_format) { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						case GL_BGRA_EXT: | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
							copy_bgra_yflip(d, s, output->current->height, | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
									buffer_stride, output_stride); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
							break; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						case GL_RGBA: | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
							copy_rgba_yflip(d, s, output->current->height, | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
									buffer_stride, output_stride); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
							break; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						default: | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
							break; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						} | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						wl_list_remove(&r->base.link); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						screenshooter_send_done(r->resource); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						free(r->base.data); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						free(r); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					} | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					static void | 
					 | 
					 | 
					 | 
					static void | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					screenshooter_shoot(struct wl_client *client, | 
					 | 
					 | 
					 | 
					screenshooter_shoot(struct wl_client *client, | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							    struct wl_resource *resource, | 
					 | 
					 | 
					 | 
							    struct wl_resource *resource, | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					 | 
					@ -88,9 +131,9 @@ screenshooter_shoot(struct wl_client *client, | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							    struct wl_resource *buffer_resource) | 
					 | 
					 | 
					 | 
							    struct wl_resource *buffer_resource) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					{ | 
					 | 
					 | 
					 | 
					{ | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						struct weston_output *output = output_resource->data; | 
					 | 
					 | 
					 | 
						struct weston_output *output = output_resource->data; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						struct screenshooter_read_pixels *r; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						struct wl_buffer *buffer = buffer_resource->data; | 
					 | 
					 | 
					 | 
						struct wl_buffer *buffer = buffer_resource->data; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						uint8_t *tmp, *d, *s; | 
					 | 
					 | 
					 | 
						int32_t stride; | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						int32_t buffer_stride, output_stride; | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						if (!wl_buffer_is_shm(buffer)) | 
					 | 
					 | 
					 | 
						if (!wl_buffer_is_shm(buffer)) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							return; | 
					 | 
					 | 
					 | 
							return; | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					 | 
					@ -99,35 +142,30 @@ screenshooter_shoot(struct wl_client *client, | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						    buffer->height < output->current->height) | 
					 | 
					 | 
					 | 
						    buffer->height < output->current->height) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							return; | 
					 | 
					 | 
					 | 
							return; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						buffer_stride = wl_shm_buffer_get_stride(buffer); | 
					 | 
					 | 
					 | 
						r = malloc(sizeof *r); | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						output_stride = output->current->width * 4; | 
					 | 
					 | 
					 | 
						if (r == NULL) { | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						tmp = malloc(output_stride * output->current->height); | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						if (tmp == NULL) { | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							wl_resource_post_no_memory(resource); | 
					 | 
					 | 
					 | 
							wl_resource_post_no_memory(resource); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							return; | 
					 | 
					 | 
					 | 
							return; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						} | 
					 | 
					 | 
					 | 
						} | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						glPixelStorei(GL_PACK_ALIGNMENT, 1); | 
					 | 
					 | 
					 | 
						r->base.x = 0; | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						output->read_pixels(output, tmp); | 
					 | 
					 | 
					 | 
						r->base.y = 0; | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
						r->base.width = output->current->width; | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						d = wl_shm_buffer_get_data(buffer) + output->y * buffer_stride + | 
					 | 
					 | 
					 | 
						r->base.height = output->current->height; | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
												output->x * 4; | 
					 | 
					 | 
					 | 
						r->base.done = screenshooter_read_pixels_done; | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						s = tmp + output_stride * (output->current->height - 1); | 
					 | 
					 | 
					 | 
						r->buffer = buffer; | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
						r->resource = resource; | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						switch (output->compositor->read_format) { | 
					 | 
					 | 
					 | 
						stride = buffer->width * 4; | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						case GL_BGRA_EXT: | 
					 | 
					 | 
					 | 
						r->base.data = malloc(stride * buffer->height); | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							copy_bgra_yflip(d, s, output->current->height, | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
									buffer_stride, output_stride); | 
					 | 
					 | 
					 | 
						if (r->base.data == NULL) { | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							break; | 
					 | 
					 | 
					 | 
							free(r); | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						case GL_RGBA: | 
					 | 
					 | 
					 | 
							wl_resource_post_no_memory(resource); | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							copy_rgba_yflip(d, s, output->current->height, | 
					 | 
					 | 
					 | 
							return; | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
									buffer_stride, output_stride); | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							break; | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						default: | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							break; | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						} | 
					 | 
					 | 
					 | 
						} | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						free(tmp); | 
					 | 
					 | 
					 | 
						wl_list_insert(output->read_pixels_list.prev, &r->base.link); | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						weston_compositor_schedule_repaint(output->compositor); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					} | 
					 | 
					 | 
					 | 
					} | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					struct screenshooter_interface screenshooter_implementation = { | 
					 | 
					 | 
					 | 
					struct screenshooter_interface screenshooter_implementation = { | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
						
					 | 
					 | 
					
  |