[PATCH 3/3 v1] screenshooter: Don't assume output offsets start at zero

Scott Moreau oreaus at gmail.com
Fri Apr 20 12:37:35 PDT 2012


---
 clients/screenshot.c |   38 ++++++++++++++++++++++++++++++++------
 1 files changed, 32 insertions(+), 6 deletions(-)

diff --git a/clients/screenshot.c b/clients/screenshot.c
index a23ef13..e023199 100644
--- a/clients/screenshot.c
+++ b/clients/screenshot.c
@@ -26,14 +26,14 @@
 #include <string.h>
 #include <fcntl.h>
 #include <unistd.h>
+#include <limits.h>
+#include <sys/param.h>
 #include <sys/mman.h>
 #include <cairo.h>
 
 #include <wayland-client.h>
 #include "screenshooter-client-protocol.h"
 
-#define MAX(X,Y) ((X) > (Y) ? (X) : (Y))
-
 /* The screenshooter is a good example of a custom object exposed by
  * the compositor and serves as a test bed for implementing client
  * side marshalling outside libwayland.so */
@@ -41,6 +41,7 @@
 static struct wl_shm *shm;
 static struct screenshooter *screenshooter;
 static struct wl_list output_list;
+int min_x, min_y, max_x, max_y;
 int buffer_copy_done;
 
 struct screenshooter_output {
@@ -182,7 +183,8 @@ write_png(int width, int height)
 	wl_list_for_each_safe(output, next, &output_list, link) {
 		output_stride = output->width * 4;
 		s = output->data;
-		d = data + output->offset_y * buffer_stride + output->offset_x * 4;
+		d = data + (output->offset_y - min_y) * buffer_stride +
+			   (output->offset_x - min_x) * 4;
 
 		for (i = 0; i < output->height; i++) {
 			memcpy(d, s, output_stride);
@@ -201,11 +203,34 @@ write_png(int width, int height)
 	free(data);
 }
 
+static int
+set_buffer_size(int *width, int *height)
+{
+	struct screenshooter_output *output;
+	min_x = min_y = INT_MAX;
+	max_x = max_y = INT_MIN;
+
+	wl_list_for_each(output, &output_list, link) {
+		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);
+	}
+
+	if (max_x <= min_x || max_y <= min_y)
+		return -1;
+
+	*width = max_x - min_x;
+	*height = max_y - min_y;
+
+	return 0;
+}
+
 int main(int argc, char *argv[])
 {
 	struct wl_display *display;
 	struct screenshooter_output *output;
-	int width = 0, height = 0;
+	int width, height;
 
 	display = wl_display_connect(NULL);
 	if (display == NULL) {
@@ -224,12 +249,13 @@ int main(int argc, char *argv[])
 
 	screenshooter_add_listener(screenshooter, &screenshooter_listener, screenshooter);
 
+	if (set_buffer_size(&width, &height))
+		return -1;
+
 
 	wl_list_for_each(output, &output_list, link) {
 		output->buffer = create_shm_buffer(output->width, output->height, &output->data);
 		screenshooter_shoot(screenshooter, output->output, output->buffer);
-		width = MAX(width, output->offset_x + output->width);
-		height = MAX(height, output->offset_y + output->height);
 		buffer_copy_done = 0;
 		while (!buffer_copy_done)
 			wl_display_roundtrip(display);
-- 
1.7.4.1



More information about the wayland-devel mailing list