|  |  |  | @ -1,29 +1,12 @@ | 
			
		
	
		
			
				
					|  |  |  |  | #include <assert.h> | 
			
		
	
		
			
				
					|  |  |  |  | #include "background-image.h" | 
			
		
	
		
			
				
					|  |  |  |  | #include "cairo_util.h" | 
			
		
	
		
			
				
					|  |  |  |  | #include "config.h" | 
			
		
	
		
			
				
					|  |  |  |  | #include "log.h" | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | #if HAVE_GDK_PIXBUF | 
			
		
	
		
			
				
					|  |  |  |  | #include <gdk-pixbuf/gdk-pixbuf.h> | 
			
		
	
		
			
				
					|  |  |  |  | #endif | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | enum background_mode parse_background_mode(const char *mode) { | 
			
		
	
		
			
				
					|  |  |  |  | 	if (strcmp(mode, "stretch") == 0) { | 
			
		
	
		
			
				
					|  |  |  |  | 		return BACKGROUND_MODE_STRETCH; | 
			
		
	
		
			
				
					|  |  |  |  | 	} else if (strcmp(mode, "fill") == 0) { | 
			
		
	
		
			
				
					|  |  |  |  | 		return BACKGROUND_MODE_FILL; | 
			
		
	
		
			
				
					|  |  |  |  | 	} else if (strcmp(mode, "fit") == 0) { | 
			
		
	
		
			
				
					|  |  |  |  | 		return BACKGROUND_MODE_FIT; | 
			
		
	
		
			
				
					|  |  |  |  | 	} else if (strcmp(mode, "center") == 0) { | 
			
		
	
		
			
				
					|  |  |  |  | 		return BACKGROUND_MODE_CENTER; | 
			
		
	
		
			
				
					|  |  |  |  | 	} else if (strcmp(mode, "tile") == 0) { | 
			
		
	
		
			
				
					|  |  |  |  | 		return BACKGROUND_MODE_TILE; | 
			
		
	
		
			
				
					|  |  |  |  | 	} else if (strcmp(mode, "solid_color") == 0) { | 
			
		
	
		
			
				
					|  |  |  |  | 		return BACKGROUND_MODE_SOLID_COLOR; | 
			
		
	
		
			
				
					|  |  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  |  | 	sway_log(SWAY_ERROR, "Unsupported background mode: %s", mode); | 
			
		
	
		
			
				
					|  |  |  |  | 	return BACKGROUND_MODE_INVALID; | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | #if HAVE_GDK_PIXBUF | 
			
		
	
		
			
				
					|  |  |  |  | static cairo_surface_t* gdk_cairo_image_surface_create_from_pixbuf( | 
			
		
	
		
			
				
					|  |  |  |  | 		const GdkPixbuf *gdkbuf) { | 
			
		
	
	
		
			
				
					|  |  |  | @ -151,70 +134,3 @@ cairo_surface_t *load_background_image(const char *path) { | 
			
		
	
		
			
				
					|  |  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  |  | 	return image; | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | void render_background_image(cairo_t *cairo, cairo_surface_t *image, | 
			
		
	
		
			
				
					|  |  |  |  | 		enum background_mode mode, int buffer_width, int buffer_height) { | 
			
		
	
		
			
				
					|  |  |  |  | 	double width = cairo_image_surface_get_width(image); | 
			
		
	
		
			
				
					|  |  |  |  | 	double height = cairo_image_surface_get_height(image); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	cairo_save(cairo); | 
			
		
	
		
			
				
					|  |  |  |  | 	switch (mode) { | 
			
		
	
		
			
				
					|  |  |  |  | 	case BACKGROUND_MODE_STRETCH: | 
			
		
	
		
			
				
					|  |  |  |  | 		cairo_scale(cairo, | 
			
		
	
		
			
				
					|  |  |  |  | 				(double)buffer_width / width, | 
			
		
	
		
			
				
					|  |  |  |  | 				(double)buffer_height / height); | 
			
		
	
		
			
				
					|  |  |  |  | 		cairo_set_source_surface(cairo, image, 0, 0); | 
			
		
	
		
			
				
					|  |  |  |  | 		break; | 
			
		
	
		
			
				
					|  |  |  |  | 	case BACKGROUND_MODE_FILL: { | 
			
		
	
		
			
				
					|  |  |  |  | 		double window_ratio = (double)buffer_width / buffer_height; | 
			
		
	
		
			
				
					|  |  |  |  | 		double bg_ratio = width / height; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 		if (window_ratio > bg_ratio) { | 
			
		
	
		
			
				
					|  |  |  |  | 			double scale = (double)buffer_width / width; | 
			
		
	
		
			
				
					|  |  |  |  | 			cairo_scale(cairo, scale, scale); | 
			
		
	
		
			
				
					|  |  |  |  | 			cairo_set_source_surface(cairo, image, | 
			
		
	
		
			
				
					|  |  |  |  | 					0, (double)buffer_height / 2 / scale - height / 2); | 
			
		
	
		
			
				
					|  |  |  |  | 		} else { | 
			
		
	
		
			
				
					|  |  |  |  | 			double scale = (double)buffer_height / height; | 
			
		
	
		
			
				
					|  |  |  |  | 			cairo_scale(cairo, scale, scale); | 
			
		
	
		
			
				
					|  |  |  |  | 			cairo_set_source_surface(cairo, image, | 
			
		
	
		
			
				
					|  |  |  |  | 					(double)buffer_width / 2 / scale - width / 2, 0); | 
			
		
	
		
			
				
					|  |  |  |  | 		} | 
			
		
	
		
			
				
					|  |  |  |  | 		break; | 
			
		
	
		
			
				
					|  |  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  |  | 	case BACKGROUND_MODE_FIT: { | 
			
		
	
		
			
				
					|  |  |  |  | 		double window_ratio = (double)buffer_width / buffer_height; | 
			
		
	
		
			
				
					|  |  |  |  | 		double bg_ratio = width / height; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 		if (window_ratio > bg_ratio) { | 
			
		
	
		
			
				
					|  |  |  |  | 			double scale = (double)buffer_height / height; | 
			
		
	
		
			
				
					|  |  |  |  | 			cairo_scale(cairo, scale, scale); | 
			
		
	
		
			
				
					|  |  |  |  | 			cairo_set_source_surface(cairo, image, | 
			
		
	
		
			
				
					|  |  |  |  | 					(double)buffer_width / 2 / scale - width / 2, 0); | 
			
		
	
		
			
				
					|  |  |  |  | 		} else { | 
			
		
	
		
			
				
					|  |  |  |  | 			double scale = (double)buffer_width / width; | 
			
		
	
		
			
				
					|  |  |  |  | 			cairo_scale(cairo, scale, scale); | 
			
		
	
		
			
				
					|  |  |  |  | 			cairo_set_source_surface(cairo, image, | 
			
		
	
		
			
				
					|  |  |  |  | 					0, (double)buffer_height / 2 / scale - height / 2); | 
			
		
	
		
			
				
					|  |  |  |  | 		} | 
			
		
	
		
			
				
					|  |  |  |  | 		break; | 
			
		
	
		
			
				
					|  |  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  |  | 	case BACKGROUND_MODE_CENTER: | 
			
		
	
		
			
				
					|  |  |  |  | 		cairo_set_source_surface(cairo, image, | 
			
		
	
		
			
				
					|  |  |  |  | 				(double)buffer_width / 2 - width / 2, | 
			
		
	
		
			
				
					|  |  |  |  | 				(double)buffer_height / 2 - height / 2); | 
			
		
	
		
			
				
					|  |  |  |  | 		break; | 
			
		
	
		
			
				
					|  |  |  |  | 	case BACKGROUND_MODE_TILE: { | 
			
		
	
		
			
				
					|  |  |  |  | 		cairo_pattern_t *pattern = cairo_pattern_create_for_surface(image); | 
			
		
	
		
			
				
					|  |  |  |  | 		cairo_pattern_set_extend(pattern, CAIRO_EXTEND_REPEAT); | 
			
		
	
		
			
				
					|  |  |  |  | 		cairo_set_source(cairo, pattern); | 
			
		
	
		
			
				
					|  |  |  |  | 		break; | 
			
		
	
		
			
				
					|  |  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  |  | 	case BACKGROUND_MODE_SOLID_COLOR: | 
			
		
	
		
			
				
					|  |  |  |  | 	case BACKGROUND_MODE_INVALID: | 
			
		
	
		
			
				
					|  |  |  |  | 		assert(0); | 
			
		
	
		
			
				
					|  |  |  |  | 		break; | 
			
		
	
		
			
				
					|  |  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  |  | 	cairo_paint(cairo); | 
			
		
	
		
			
				
					|  |  |  |  | 	cairo_restore(cairo); | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
	
		
			
				
					|  |  |  | 
 |