diff options
Diffstat (limited to 'tests/modefb')
| -rw-r--r-- | tests/modefb/Makefile | 14 | ||||
| -rw-r--r-- | tests/modefb/demo.c | 230 | ||||
| -rwxr-xr-x | tests/modefb/test | 1 | 
3 files changed, 245 insertions, 0 deletions
| diff --git a/tests/modefb/Makefile b/tests/modefb/Makefile new file mode 100644 index 00000000..467fb11a --- /dev/null +++ b/tests/modefb/Makefile @@ -0,0 +1,14 @@ + +all: app + +#CFLAGS = -g -ansi -pedantic -DPOSIX_C_SOURCE=199309L \ +#        -D_POSIX_SOURCE -D_XOPEN_SOURCE -D_BSD_SOURCE -D_SVID_SOURCE \ + +app: demo.c +	@gcc $(CFLAGS) -o app -Wall -I../../libdrm -I../../shared-core -L../../libdrm/.libs -ldrm demo.c + +clean: +	@rm -f app + +run: app +	sudo ./test diff --git a/tests/modefb/demo.c b/tests/modefb/demo.c new file mode 100644 index 00000000..ead53334 --- /dev/null +++ b/tests/modefb/demo.c @@ -0,0 +1,230 @@ +#include <stdio.h> +#include <unistd.h> +#include <stdlib.h> +#include <errno.h> +#include <fcntl.h> +#include <string.h> +#include "linux/fb.h" +#include <sys/mman.h> +#include "sys/ioctl.h" +#include "xf86drm.h" +#include "xf86drmMode.h" + +void pretty(int fd); +void setMode(struct fb_var_screeninfo *var); +void pan(int fd, struct fb_var_screeninfo *var, int x, int y); +void cursor(int fd, int drmfd); +void prettyColors(int fd); +void prettyCursor(int fd, unsigned int handle, unsigned int color); + +struct fb_var_screeninfo var; +struct fb_fix_screeninfo fix; + +int main(int argc, char **argv) +{ +	char name[100]; +	int i,d; +	int fd; +	int drmfd = drmOpen("i915", NULL); + +	if (drmfd < 0) { +		printf("drmOpenControl failed\n"); +		return 1; +	} + +	/* try four devices */ +	for (d = 0; d < 4; d++) { +		snprintf(name, 100, "/dev/fb%d", d); +		fd = open(name, O_RDWR); + +		if (fd == -1) { +			printf("open %s : %s\n", name, strerror(errno)); +			return 1; +		} + +		memset(&var, 0, sizeof(struct fb_var_screeninfo)); +		memset(&fix, 0, sizeof(struct fb_fix_screeninfo)); + +		if (ioctl(fd, FBIOGET_VSCREENINFO, &var)) +			printf("var  %s\n", strerror(errno)); +		if	(ioctl(fd, FBIOGET_FSCREENINFO, &fix)) +			printf("fix %s\n", strerror(errno)); + +		setMode(&var); + +		if (ioctl(fd, FBIOPUT_VSCREENINFO, &var)) +			printf("var  %s\n", strerror(errno)); + +		for (i = 0; i < 1; i++) { +			prettyColors(fd); +		} +		sleep(1); + +		printf("pan: 0, 0\n"); +		pan(fd, &var, 0, 0); +		sleep(2); +		printf("pan: 100, 0\n"); +		pan(fd, &var, 100, 0); +		sleep(2); +		printf("pan: 0, 100\n"); +		pan(fd, &var, 0, 100); +		sleep(2); +		printf("pan: 100, 100\n"); +		pan(fd, &var, 100, 100); +		sleep(2); +		printf("pan: 0, 0\n"); +		pan(fd, &var, 0, 0); +		sleep(2); + +		printf("cursor (may show up on wrong CRTC - fixme)\n"); +		cursor(fd, drmfd); + +		close(fd); +	} +	return 0; +} + +void pan(int fd, struct fb_var_screeninfo *var, int x, int y) +{ +	var->xoffset = x; +	var->yoffset = y; + +	if (ioctl(fd, FBIOPAN_DISPLAY, var)) +		printf("pan error: %s\n", strerror(errno)); +} + +void draw(unsigned int x, unsigned int y, unsigned int w, unsigned int h, unsigned int v, unsigned int *ptr) +{ +	int i, j; + +	for (i = x; i < x + w; i++) +		for(j = y; j < y + h; j++) +			ptr[(i * var.xres_virtual) + j] = v; +} + +void prettyColors(int fd) +{ +	unsigned int *ptr; +	int i; +	int size = var.xres * var.yres * var.bits_per_pixel; + +	ptr = (unsigned int *)mmap(NULL, size, +				PROT_READ|PROT_WRITE, MAP_SHARED, fd, +				0); +	if (ptr < 0) { +		printf("FAILED MMAP %d\n",errno); +		exit(1); +	} + +	memset(ptr, 0xFF, size); +		 +	for (i = 0; i < 8; i++) +		draw(i * 40, i * 40, 40, 40, 0, ptr); + + +	draw(200, 100, 40, 40, 0xff00ff, ptr); +	draw(100, 200, 40, 40, 0xff00ff, ptr); + +	munmap(ptr, size); +} + +/* + * Cursor support removed from the fb kernel interface + * using drm instead. + */ +void cursor(int fd, int drmfd) +{ +	drmModeResPtr res = drmModeGetResources(drmfd); +	uint32_t crtc = res->crtcs[1]; /* select crtc here */ +	drmBO bo; +	int ret; +	ret = drmBOCreate(drmfd, 64 * 64 * 4, 0, 0, +		DRM_BO_FLAG_READ | +		DRM_BO_FLAG_WRITE | +		DRM_BO_FLAG_MEM_VRAM | +		DRM_BO_FLAG_NO_EVICT, +		DRM_BO_HINT_DONT_FENCE, &bo); + +	if (ret) { +		printf("failed to create buffer: %s\n", strerror(ret)); +		return; +	} + +	prettyCursor(drmfd, bo.handle, 0xFFFF00FF); +	drmModeSetCursor(drmfd, crtc, bo.handle, 64, 64); +	drmModeMoveCursor(drmfd, crtc, 0, 0); +	sleep(1); +	prettyCursor(drmfd, bo.handle, 0xFFFF0000); +	drmModeMoveCursor(drmfd, crtc, 40, 40); +	sleep(1); +	drmModeMoveCursor(drmfd, crtc, 100, 100); +	sleep(1); +	drmModeSetCursor(drmfd, crtc, 0, 0, 0); +	drmBOUnreference(drmfd, &bo); +} + +void prettyCursor(int drmfd, unsigned int handle, unsigned int color) +{ +	drmBO bo; +	unsigned int *ptr; +	int i; + +	drmBOReference(drmfd, handle, &bo); +	drmBOMap(drmfd, &bo, DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE, 0, (void**)&ptr); + +	for (i = 0; i < (64 * 64); i++) +		ptr[i] = color; + +	drmBOUnmap(drmfd, &bo); +	drmBOUnreference(drmfd, &bo); +} + +struct drm_mode +{ +	int clock; +	int hdisplay; +	int hsync_start; +	int hsync_end; +	int htotal; +	int hskew; +	int vdisplay; +	int vsync_start; +	int vsync_end; +	int vtotal; +	int vscan; +	int vrefresh; +	int flags; +}; + +struct drm_mode mode = +{ +	.clock = 25200, +	.hdisplay = 640, +	.hsync_start = 656, +	.hsync_end = 752, +	.htotal = 800, +	.hskew = 0, +	.vdisplay = 480, +	.vsync_start = 490, +	.vsync_end = 492, +	.vtotal = 525, +	.vscan = 0, +	.vrefresh = 60000, /* vertical refresh * 1000 */ +	.flags = 10, +}; + +void setMode(struct fb_var_screeninfo *var) { +	var->activate = FB_ACTIVATE_NOW; +	var->xres = mode.hdisplay; +	var->right_margin = mode.hsync_start - mode.hdisplay; +	var->hsync_len = mode.hsync_end - mode.hsync_start; +	var->left_margin = mode.htotal - mode.hsync_end; +	var->yres = mode.vdisplay; +	var->lower_margin = mode.vsync_start - mode.vdisplay; +	var->vsync_len = mode.vsync_end - mode.vsync_start; +	var->upper_margin = mode.vtotal - mode.vsync_end; +	var->pixclock = 10000000 / mode.htotal * 1000 / mode.vtotal * 100; +	/* avoid overflow */ +	var->pixclock = var->pixclock * 1000 / mode.vrefresh; +	var->bits_per_pixel = 32; +} diff --git a/tests/modefb/test b/tests/modefb/test new file mode 100755 index 00000000..f98e3708 --- /dev/null +++ b/tests/modefb/test @@ -0,0 +1 @@ +LD_PRELOAD=../../libdrm/.libs/libdrm.so ./app | 
