diff options
| -rw-r--r-- | fbdev.c | 130 | 
1 files changed, 130 insertions, 0 deletions
| @@ -34,6 +34,7 @@  #include <linux/fb.h> +#define min(a, b)	((a) < (b) ? (a) : (b))  #define ARRAY_SIZE(a)	(sizeof(a)/sizeof((a)[0]))  struct device { @@ -52,6 +53,7 @@ enum fb_fill_mode {  enum fb_fill_pattern {  	FB_PATTERN_SMPTE = 0, +	FB_PATTERN_LINES = 1,  };  /* ----------------------------------------------------------------------------- @@ -815,6 +817,127 @@ fb_fill_smpte(struct device *dev, unsigned int xoffset, unsigned int yoffset,  	}  } +static void +fb_fill_lines_rgb16(struct device *dev, unsigned int xoffset, +		    unsigned int yoffset, unsigned int xres, unsigned int yres) +{ +	const uint16_t colors[] = { +		FB_MAKE_COLOR(&dev->var_info, 192, 192, 0),	/* yellow */ +		FB_MAKE_COLOR(&dev->var_info, 19, 19, 19),	/* black */ +		FB_MAKE_COLOR(&dev->var_info, 0, 192, 0),	/* green */ +		FB_MAKE_COLOR(&dev->var_info, 19, 19, 19),	/* black */ +		FB_MAKE_COLOR(&dev->var_info, 192, 0, 0),	/* red */ +		FB_MAKE_COLOR(&dev->var_info, 19, 19, 19),	/* black */ +		FB_MAKE_COLOR(&dev->var_info, 0, 0, 192),	/* blue */ +		FB_MAKE_COLOR(&dev->var_info, 19, 19, 19),	/* black */ +	}; +	void *mem = dev->mem + dev->fix_info.line_length * yoffset +		  + xoffset * dev->var_info.bits_per_pixel / 8; +	unsigned int x_min; +	unsigned int y_min; +	unsigned int x; +	unsigned int y; + +	for (y = 0; y < yres; ++y) { +		y_min = min(y, yres - y - 1); +		for (x = 0; x < xres; ++x) { +			x_min = min(x, xres - x - 1); +			((uint16_t *)mem)[x] = +				colors[min(x_min, y_min) % ARRAY_SIZE(colors)]; +		} +		mem += dev->fix_info.line_length; +	} +} + +static void +fb_fill_lines_rgb24(struct device *dev, unsigned int xoffset, +		    unsigned int yoffset, unsigned int xres, unsigned int yres) +{ +	const struct fb_color24 colors[] = { +		FB_MAKE_COLOR24(&dev->var_info, 192, 192, 0),	/* yellow */ +		FB_MAKE_COLOR24(&dev->var_info, 19, 19, 19),	/* black */ +		FB_MAKE_COLOR24(&dev->var_info, 0, 192, 0),	/* green */ +		FB_MAKE_COLOR24(&dev->var_info, 19, 19, 19),	/* black */ +		FB_MAKE_COLOR24(&dev->var_info, 192, 0, 0),	/* red */ +		FB_MAKE_COLOR24(&dev->var_info, 19, 19, 19),	/* black */ +		FB_MAKE_COLOR24(&dev->var_info, 0, 0, 192),	/* blue */ +		FB_MAKE_COLOR24(&dev->var_info, 19, 19, 19),	/* black */ +	}; +	void *mem = dev->mem + dev->fix_info.line_length * yoffset +		  + xoffset * dev->var_info.bits_per_pixel / 8; +	unsigned int x_min; +	unsigned int y_min; +	unsigned int x; +	unsigned int y; + +	for (y = 0; y < yres; ++y) { +		y_min = min(y, yres - y - 1); +		for (x = 0; x < xres; ++x) { +			x_min = min(x, xres - x - 1); +			((struct fb_color24 *)mem)[x] = +				colors[min(x_min, y_min) % ARRAY_SIZE(colors)]; +		} +		mem += dev->fix_info.line_length; +	} +} + +static void +fb_fill_lines_rgb32(struct device *dev, unsigned int xoffset, +		    unsigned int yoffset, unsigned int xres, unsigned int yres) +{ +	const uint32_t colors[] = { +		FB_MAKE_COLOR(&dev->var_info, 192, 192, 0),	/* yellow */ +		FB_MAKE_COLOR(&dev->var_info, 19, 19, 19),	/* black */ +		FB_MAKE_COLOR(&dev->var_info, 0, 192, 0),	/* green */ +		FB_MAKE_COLOR(&dev->var_info, 19, 19, 19),	/* black */ +		FB_MAKE_COLOR(&dev->var_info, 192, 0, 0),	/* red */ +		FB_MAKE_COLOR(&dev->var_info, 19, 19, 19),	/* black */ +		FB_MAKE_COLOR(&dev->var_info, 0, 0, 192),	/* blue */ +		FB_MAKE_COLOR(&dev->var_info, 19, 19, 19),	/* black */ +	}; +	void *mem = dev->mem + dev->fix_info.line_length * yoffset +		  + xoffset * dev->var_info.bits_per_pixel / 8; +	unsigned int x_min; +	unsigned int y_min; +	unsigned int x; +	unsigned int y; + +	for (y = 0; y < yres; ++y) { +		y_min = min(y, yres - y - 1); +		for (x = 0; x < xres; ++x) { +			x_min = min(x, xres - x - 1); +			((uint32_t *)mem)[x] = +				colors[min(x_min, y_min) % ARRAY_SIZE(colors)]; +		} +		mem += dev->fix_info.line_length; +	} +} + +/* + * fb_fill_lines - Fill the frame buffer with a lines test pattern + * @dev: FB device + * @xoffset: Horizontal offset, in pixels + * @yoffset: Vertical offset, in pixels + * @xres: Horizontal size, in pixels + * @yres: Vertical size, in pixels + * + * Fill the display (when mode is FB_FILL_DISPLAY) or virtual frame buffer area + * (when mode is FB_FILL_VIRTUAL) with a lines pattern. + */ +static void +fb_fill_lines(struct device *dev, unsigned int xoffset, unsigned int yoffset, +	      unsigned int xres, unsigned int yres) +{ +	switch (dev->var_info.bits_per_pixel) { +	case 16: +		return fb_fill_lines_rgb16(dev, xoffset, yoffset, xres, yres); +	case 24: +		return fb_fill_lines_rgb24(dev, xoffset, yoffset, xres, yres); +	case 32: +		return fb_fill_lines_rgb32(dev, xoffset, yoffset, xres, yres); +	} +} +  /*   * fb_fill - Fill the frame buffer with a test pattern   * @dev: FB device @@ -862,6 +985,10 @@ fb_fill(struct device *dev, enum fb_fill_mode mode, enum fb_fill_pattern pattern  		printf("Filling frame buffer with SMPTE test pattern\n");  		return fb_fill_smpte(dev, xoffset, yoffset, xres, yres); +	case FB_PATTERN_LINES: +		printf("Filling frame buffer with lines test pattern\n"); +		return fb_fill_lines(dev, xoffset, yoffset, xres, yres); +  	default:  		printf("Error: unsupported test pattern %u.\n", pattern);  		break; @@ -891,6 +1018,7 @@ static void usage(const char *argv0)  	printf(" virtual	Fill the whole virtual frame buffer\n");  	printf("Support test pattern are:\n");  	printf(" smpte		SMPTE color bars\n"); +	printf(" lines		Color lines\n");  	printf("Supported blanking modes are:\n");  	printf(" off		Blanking off, screen active\n");  	printf(" on		Blanked, HSync on,  VSync on\n"); @@ -1044,6 +1172,8 @@ int main(int argc, char *argv[])  		case 'P':  			if (strcmp(optarg, "smpte") == 0)  				fill_pattern = FB_PATTERN_SMPTE; +			else if (strcmp(optarg, "lines") == 0) +				fill_pattern = FB_PATTERN_LINES;  			else {  				printf("Invalid test pattern `%s'\n", optarg);  				printf("Run %s -h for help.\n", argv[0]); | 
