desktop-shell: new wallpaper mode scale-crop

Scale-crop mode scales the wallpaper to tightly fill the whole output,
but preserving wallpaper aspect ratio. If aspect ratio differs from the
output's, the wallpaper is centered cutting it from top/bottom or
left/right.

Add this to the weston.ini man page, and explain all three modes.

Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk>
diff --git a/clients/desktop-shell.c b/clients/desktop-shell.c
index 3b71403..40dd1dd 100644
--- a/clients/desktop-shell.c
+++ b/clients/desktop-shell.c
@@ -660,6 +660,7 @@
 
 enum {
 	BACKGROUND_SCALE,
+	BACKGROUND_SCALE_CROP,
 	BACKGROUND_TILE
 };
 
@@ -671,7 +672,9 @@
 	cairo_pattern_t *pattern;
 	cairo_matrix_t matrix;
 	cairo_t *cr;
-	double sx, sy;
+	double im_w, im_h;
+	double sx, sy, s;
+	double tx, ty;
 	struct rectangle allocation;
 	int type = -1;
 	struct display *display;
@@ -691,6 +694,8 @@
 
 	if (strcmp(key_background_type, "scale") == 0)
 		type = BACKGROUND_SCALE;
+	else if (strcmp(key_background_type, "scale-crop") == 0)
+		type = BACKGROUND_SCALE_CROP;
 	else if (strcmp(key_background_type, "tile") == 0)
 		type = BACKGROUND_TILE;
 	else
@@ -698,20 +703,32 @@
 			key_background_type);
 
 	if (image && type != -1) {
+		im_w = cairo_image_surface_get_width(image);
+		im_h = cairo_image_surface_get_height(image);
+		sx = im_w / allocation.width;
+		sy = im_h / allocation.height;
+
 		pattern = cairo_pattern_create_for_surface(image);
+
 		switch (type) {
 		case BACKGROUND_SCALE:
-			sx = (double) cairo_image_surface_get_width(image) /
-				allocation.width;
-			sy = (double) cairo_image_surface_get_height(image) /
-				allocation.height;
 			cairo_matrix_init_scale(&matrix, sx, sy);
 			cairo_pattern_set_matrix(pattern, &matrix);
 			break;
+		case BACKGROUND_SCALE_CROP:
+			s = (sx < sy) ? sx : sy;
+			/* align center */
+			tx = (im_w - s * allocation.width) * 0.5;
+			ty = (im_h - s * allocation.height) * 0.5;
+			cairo_matrix_init_translate(&matrix, tx, ty);
+			cairo_matrix_scale(&matrix, s, s);
+			cairo_pattern_set_matrix(pattern, &matrix);
+			break;
 		case BACKGROUND_TILE:
 			cairo_pattern_set_extend(pattern, CAIRO_EXTEND_REPEAT);
 			break;
 		}
+
 		cairo_set_source(cr, pattern);
 		cairo_pattern_destroy (pattern);
 		cairo_surface_destroy(image);