diff options
Diffstat (limited to 'tests')
| -rw-r--r-- | tests/dristat.c | 2 | ||||
| -rw-r--r-- | tests/mode/Makefile | 14 | ||||
| -rw-r--r-- | tests/mode/modetest.c | 380 | ||||
| -rwxr-xr-x | tests/mode/test | 1 | ||||
| -rw-r--r-- | tests/modedemo/Makefile | 14 | ||||
| -rw-r--r-- | tests/modedemo/demo.c | 634 | ||||
| -rwxr-xr-x | tests/modedemo/test | 1 | ||||
| -rw-r--r-- | tests/modefb/Makefile | 14 | ||||
| -rw-r--r-- | tests/modefb/demo.c | 231 | ||||
| -rwxr-xr-x | tests/modefb/test | 1 | ||||
| -rw-r--r-- | tests/modehotplug/Makefile | 14 | ||||
| -rw-r--r-- | tests/modehotplug/demo.c | 157 | ||||
| -rwxr-xr-x | tests/modehotplug/test | 1 | 
13 files changed, 1463 insertions, 1 deletions
| diff --git a/tests/dristat.c b/tests/dristat.c index 89853164..48c3b51b 100644 --- a/tests/dristat.c +++ b/tests/dristat.c @@ -263,7 +263,7 @@ int main(int argc, char **argv)      for (i = 0; i < 16; i++) if (!minor || i == minor) {  	sprintf(buf, DRM_DEV_NAME, DRM_DIR_NAME, i); -	fd = drmOpenMinor(i, 1); +	fd = drmOpenMinor(i, 1, DRM_NODE_RENDER);  	if (fd >= 0) {  	    printf("%s\n", buf);  	    if (mask & DRM_BUSID)   getbusid(fd); diff --git a/tests/mode/Makefile b/tests/mode/Makefile new file mode 100644 index 00000000..7a9c3c24 --- /dev/null +++ b/tests/mode/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: modetest.c +	@gcc $(CFLAGS) -o app -Wall -I../../libdrm -I../../shared-core -L../../libdrm/.libs -ldrm modetest.c + +clean: +	@rm -f app + +run: app +	@sudo ./test diff --git a/tests/mode/modetest.c b/tests/mode/modetest.c new file mode 100644 index 00000000..a50b0cc5 --- /dev/null +++ b/tests/mode/modetest.c @@ -0,0 +1,380 @@ + +#include <assert.h> +#include <stdio.h> +#include <stdlib.h> +#include <stdint.h> +#include <unistd.h> +#include <string.h> + +#include "xf86drm.h" +#include "xf86drmMode.h" + +int dpms_prop_id = 0; +const char* getConnectionText(drmModeConnection conn) +{ +	switch (conn) { +	case DRM_MODE_CONNECTED: +		return "connected"; +	case DRM_MODE_DISCONNECTED: +		return "disconnected"; +	default: +		return "unknown"; +	} + +} + +int printMode(struct drm_mode_modeinfo *mode) +{ +#if 1 +	printf("Mode: %s\n", mode->name); +	printf("\tclock       : %i\n", mode->clock); +	printf("\thdisplay    : %i\n", mode->hdisplay); +	printf("\thsync_start : %i\n", mode->hsync_start); +	printf("\thsync_end   : %i\n", mode->hsync_end); +	printf("\thtotal      : %i\n", mode->htotal); +	printf("\thskew       : %i\n", mode->hskew); +	printf("\tvdisplay    : %i\n", mode->vdisplay); +	printf("\tvsync_start : %i\n", mode->vsync_start); +	printf("\tvsync_end   : %i\n", mode->vsync_end); +	printf("\tvtotal      : %i\n", mode->vtotal); +	printf("\tvscan       : %i\n", mode->vscan); +	printf("\tvrefresh    : %i\n", mode->vrefresh); +	printf("\tflags       : %i\n", mode->flags); +#else +	printf("Mode: \"%s\" %ix%i %.0f\n", mode->name, +		mode->hdisplay, mode->vdisplay, mode->vrefresh / 1000.0); +#endif +	return 0; +} + +int printOutput(int fd, drmModeResPtr res, drmModeOutputPtr output, uint32_t id) +{ +	int i = 0, j; +	struct drm_mode_modeinfo *mode = NULL; +	drmModePropertyPtr props; +	unsigned char *name = NULL; + +	printf("Output: %d-%d\n", output->output_type, output->output_type_id); +	printf("\tid           : %i\n", id); +	printf("\tcrtc id      : %i\n", output->crtc); +	printf("\tconn         : %s\n", getConnectionText(output->connection)); +	printf("\tsize         : %ix%i (mm)\n", output->mmWidth, output->mmHeight); +	printf("\tcount_crtcs  : %i\n", output->count_crtcs); +	printf("\tcrtcs        : %i\n", output->crtcs); +	printf("\tcount_clones : %i\n", output->count_clones); +	printf("\tclones       : %i\n", output->clones); +	printf("\tcount_modes  : %i\n", output->count_modes); +	printf("\tcount_props  : %i\n", output->count_props); + +	for (i = 0; i < output->count_props; i++) { +		props = drmModeGetProperty(fd, output->props[i]); +		name = NULL; +		if (props) { +			printf("Property: %s\n", props->name); +			printf("\tid:        %i\n", props->prop_id); +			printf("\tflags:     %i\n", props->flags); +			printf("\tvalues %d: ", props->count_values); +			for (j = 0; j < props->count_values; j++) +				printf("%lld ", props->values[j]); + +			printf("\n\tenums %d: \n", props->count_enums); +			 +			if (props->flags & DRM_MODE_PROP_BLOB) { +				drmModePropertyBlobPtr blob; + +				blob = drmModeGetPropertyBlob(fd, output->prop_values[i]); +				if (blob) { +					printf("blob is %d length, %08X\n", blob->length, *(uint32_t *)blob->data); +					drmModeFreePropertyBlob(blob); +				} + +			} else { +				if (!strncmp(props->name, "DPMS", 4)) +					dpms_prop_id = props->prop_id; + +				for (j = 0; j < props->count_enums; j++) { +				  printf("\t\t%lld = %s\n", props->enums[j].value, props->enums[j].name); +					if (output->prop_values[i] == props->enums[j].value) +						name = props->enums[j].name; + +				} + +				if (props->count_enums && name) { +					printf("\toutput property name %s %s\n", props->name, name); +				} else { +					printf("\toutput property id %s %lli\n", props->name, output->prop_values[i]); +				} +			} + +			drmModeFreeProperty(props); +		} +	} + +	for (i = 0; i < output->count_modes; i++) { +		mode = &output->modes[i]; +		if (mode) +			printMode(mode); +		else +			printf("\t\tmode: Invalid mode %p\n", &output->modes[i]); +	} + +	return 0; +} + +int printCrtc(int fd, drmModeResPtr res, drmModeCrtcPtr crtc, uint32_t id) +{ +	printf("Crtc\n"); +	printf("\tid           : %i\n", id); +	printf("\tx            : %i\n", crtc->x); +	printf("\ty            : %i\n", crtc->y); +	printf("\twidth        : %i\n", crtc->width); +	printf("\theight       : %i\n", crtc->height); +	printf("\tmode         : %p\n", &crtc->mode); +	printf("\tnum outputs  : %i\n", crtc->count_outputs); +	printf("\toutputs      : %i\n", crtc->outputs); +	printf("\tnum possible : %i\n", crtc->count_possibles); +	printf("\tpossibles    : %i\n", crtc->possibles); + +	return 0; +} + +int printFrameBuffer(int fd, drmModeResPtr res, drmModeFBPtr fb) +{ +	printf("Framebuffer\n"); +	printf("\thandle    : %i\n", fb->handle); +	printf("\twidth     : %i\n", fb->width); +	printf("\theight    : %i\n", fb->height); +	printf("\tpitch     : %i\n", fb->pitch);; +	printf("\tbpp       : %i\n", fb->bpp); +	printf("\tdepth     : %i\n", fb->depth); +	printf("\tbuffer_id : %i\n", fb->buffer_id); + +	return 0; +} + +int printRes(int fd, drmModeResPtr res) +{ +	int i; +	drmModeOutputPtr output; +	drmModeCrtcPtr crtc; +	drmModeFBPtr fb; + +	for (i = 0; i < res->count_outputs; i++) { +		output = drmModeGetOutput(fd, res->outputs[i]); + +		if (!output) +			printf("Could not get output %i\n", i); +		else { +			printOutput(fd, res, output, res->outputs[i]); +			drmModeFreeOutput(output); +		} +	} + +	for (i = 0; i < res->count_crtcs; i++) { +		crtc = drmModeGetCrtc(fd, res->crtcs[i]); + +		if (!crtc) +			printf("Could not get crtc %i\n", i); +		else { +			printCrtc(fd, res, crtc, res->crtcs[i]); +			drmModeFreeCrtc(crtc); +		} +	} + +	for (i = 0; i < res->count_fbs; i++) { +		fb = drmModeGetFB(fd, res->fbs[i]); + +		if (!fb) +			printf("Could not get fb %i\n", res->fbs[i]); +		else { +			printFrameBuffer(fd, res, fb); +			drmModeFreeFB(fb); +		} +	} + +	return 0; +} + +static struct drm_mode_modeinfo mode = { +	.name = "Test 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, +}; + +int testMode(int fd, drmModeResPtr res) +{ +	uint32_t output = res->outputs[0]; +	uint32_t newMode = 0; +	int ret = 0; +	int error = 0; + +	printf("Test: adding mode to output %i\n", output); + +	/* printMode(&mode); */ + +	printf("\tAttaching mode %i to output %i\n", newMode, output); + +	ret = drmModeAttachMode(fd, output, &mode); + +	if (ret) +		goto err_mode; + +	printf("\tDetaching mode %i from output %i\n", newMode, output); +	ret = drmModeDetachMode(fd, output, &mode); + +	if (ret) +		goto err_mode; +	return 0; + +err_mode: + +	printf("\tFailed\n"); + +	if (error) +		printf("\tFailed to delete mode %i\n", newMode); +	return 1; +} + +/* +int testFrameBufferGet(int fd, uint32_t fb) +{ +	drmModeFBPtr frame; + +	printf("Test: get framebuffer %i\n", fb); + +	frame = drmModeGetFB(fd, fb); + +	if (!frame) { +		printf("\tFailed\n"); +	} else { +		printFrameBuffer(fd, frame); +		drmModeFreeFB(frame); +	} + +	return 0; +} +*/ + +int testFrameBufferAdd(int fd, drmModeResPtr res) +{ +	uint32_t fb = 0; +	int ret = 0; +	drmModeFBPtr frame = 0; +	drmBO bo; + +	printf("Test: adding framebuffer\n"); + +	printf("\tCreating BO\n"); + +	/* TODO */ +	ret = drmBOCreate(fd, 800 * 600 * 4, 0, 0, +		DRM_BO_FLAG_READ | +		DRM_BO_FLAG_WRITE | +		DRM_BO_FLAG_MEM_TT | +		DRM_BO_FLAG_MEM_VRAM | +		DRM_BO_FLAG_NO_EVICT, +		DRM_BO_HINT_DONT_FENCE, &bo); + +	printf("\tgot %i\n", ret); +	if (ret) +		goto err; + +	printf("\tAdding FB\n"); +	ret = drmModeAddFB(fd, 800, 600, 32, 8, 0, bo->handle, &fb); +	if (ret) +		goto err_bo; + +	frame = drmModeGetFB(fd, fb); + +	if (!frame) { +		printf("Couldn't retrive created framebuffer\n"); +	} else { +		printFrameBuffer(fd, res, frame); +		drmModeFreeFB(frame); +	} + +	printf("\tRemoveing FB\n"); + +	ret = drmModeRmFB(fd, fb); + +	if (ret) { +		printf("\tFailed this shouldn't happen!\n"); +		goto err_bo; +	} + +	printf("\tRemoveing BO\n"); + +	ret = drmBOUnreference(fb, &bo); + +	return 0; +	 +err_bo: +	drmBOUnreference(fd, &bo); + +err: +	printf("\tFailed\n"); + +	return 1; +} + +int testDPMS(int fd, drmModeResPtr res) +{ +	int output_id; +	int i; + +	for (i = 0; i < res->count_outputs; i++) { +		output_id = res->outputs[i]; +		/* turn output off */ +		drmModeOutputSetProperty(fd, output_id, dpms_prop_id, 3); +		sleep(2); +		drmModeOutputSetProperty(fd, output_id, dpms_prop_id, 0); +	} +	return 1; + +} + +int main(int argc, char **argv) +{ +	int fd; +	drmModeResPtr res; + +	printf("Starting test\n"); + +	fd = drmOpenControl(0); + +	if (fd < 0) { +		printf("Failed to open the card fb (%d)\n",fd); +		return 1; +	} + +	res = drmModeGetResources(fd); +	if (res == 0) { +		printf("Failed to get resources from card\n"); +		drmClose(fd); +		return 1; +	} + +	printRes(fd, res); + +	testMode(fd, res); + +	testFrameBufferAdd(fd, res); + +	/* try dpms test */ +	testDPMS(fd, res); +	drmModeFreeResources(res); +	printf("Ok\n"); + +	return 0; +} diff --git a/tests/mode/test b/tests/mode/test new file mode 100755 index 00000000..f98e3708 --- /dev/null +++ b/tests/mode/test @@ -0,0 +1 @@ +LD_PRELOAD=../../libdrm/.libs/libdrm.so ./app diff --git a/tests/modedemo/Makefile b/tests/modedemo/Makefile new file mode 100644 index 00000000..467fb11a --- /dev/null +++ b/tests/modedemo/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/modedemo/demo.c b/tests/modedemo/demo.c new file mode 100644 index 00000000..3fad984d --- /dev/null +++ b/tests/modedemo/demo.c @@ -0,0 +1,634 @@ +/* + * Some defines to define the behavior of the program + */ + +#define CLEAN_FBDEV +#undef DEMO_CLONE + +#define SIZE_X 2048 +#define SIZE_Y 2048 +/* Pitch needs to be power of two */ +#define PITCH 2048 + +#include <assert.h> +#include <stdio.h> +#include <stdlib.h> +#include <stdint.h> +#include <unistd.h> +#include <string.h> +#ifdef CLEAN_FBDEV +#include <errno.h> +#include <fcntl.h> +#include <sys/ioctl.h> +#include <linux/fb.h> +#endif +#include <signal.h> + +#include "xf86drm.h" +#include "xf86drmMode.h" + +/* old functions to be replaced */ +drmModeFBPtr createFB(int fd, drmModeResPtr res); +void testCursor(int fd, uint32_t crtc); +void prettyColors(int fd, unsigned int handle); +void prettyCursor(int fd, unsigned int handle, unsigned int color); + +#ifdef CLEAN_FBDEV +struct fb_var_screeninfo var; +struct fb_fix_screeninfo fix; +#endif + +/* structs for the demo_driver */ + +struct demo_driver; + +struct demo_screen +{ +	/* drm stuff */ +	drmBO buffer; +	drmModeFBPtr fb; +	drmModeCrtcPtr crtc; + +	size_t num_outputs; +	uint32_t outputs_id[8]; +	drmModeOutputPtr outputs[8]; + +	struct drm_mode_modeinfo *mode; + +	/* virtual buffer */ +	uint32_t virt_x; +	uint32_t virt_y; +	uint32_t pitch; + +	/* parent */ +	struct demo_driver *driver; +}; + +#define DEMO_MAX_SCREENS 4 +#define MAX_FIND_OUTPUTS 8 + +struct demo_driver +{ +	/* drm stuff */ +	int fd; +	drmModeResPtr res; + +	/* screens */ +	size_t numScreens; +	struct demo_screen screens[DEMO_MAX_SCREENS]; +}; + +struct demo_driver* demoCreateDriver(void); +void demoUpdateRes(struct demo_driver *driver); +int demoCreateScreens(struct demo_driver *driver); +int demoCreateScreenCloned(struct demo_driver *driver); +void demoTakeDownScreen(struct demo_screen *screen); +int demoFindConnectedOutputs(struct demo_driver *driver, drmModeOutputPtr *out, size_t max_out); +drmModeCrtcPtr demoFindFreeCrtc(struct demo_driver *driver, drmModeOutputPtr output); +void demoPanScreen(struct demo_screen *screen, uint16_t x, uint16_t y); +/* yet to be implemented */ +void demoMouseActivate(struct demo_screen *screen); +void demoMouseMove(struct demo_screen *screen, uint16_t x, uint16_t y); + +static struct drm_mode_modeinfo mode = { +	.name = "Test 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, +}; + +int main(int argc, char **argv) +{ +	struct demo_driver *driver; +	int num; +	int i; + +#ifdef CLEAN_FBDEV +       int fbdev_fd; + +       fbdev_fd = open("/dev/fb0", O_RDWR); + +       memset(&var, 0, sizeof(struct fb_var_screeninfo)); +       memset(&fix, 0, sizeof(struct fb_fix_screeninfo)); + +       if (ioctl(fbdev_fd, FBIOGET_VSCREENINFO, &var)) +               printf("var  %s\n", strerror(errno)); +       if      (ioctl(fbdev_fd, FBIOGET_FSCREENINFO, &fix)) +               printf("fix %s\n", strerror(errno)); +#endif + +	printf("starting demo\n"); + +	driver = demoCreateDriver(); + +	if (!driver) { +		printf("failed to create driver\n"); +		return 1; +	} + +#ifndef DEMO_CLONE +	num = demoCreateScreens(driver); +#else +	num = demoCreateScreenCloned(driver); +#endif + +	if (num < 1) { +		printf("no screens attached or an error occured\n"); +		return 1; +	} +	printf("created %i screens\n", num); + +	for (i = 0; i < num; i++) { +		prettyColors(driver->fd, driver->screens[i].fb->handle); +	} +	sleep(1); + +	for (i = 0; i < num; i++) { +		printf("%i: 100 0\n", i); +		demoPanScreen(&driver->screens[i], 100, 0); +		sleep(1); + +		printf("%i: 0 100\n", i); +		demoPanScreen(&driver->screens[i], 0, 100); +		sleep(1); + +		printf("%i: 100 100\n", i); +		demoPanScreen(&driver->screens[i], 100, 100); +		sleep(1); + +		printf("%i: 0 0\n", i); +		demoPanScreen(&driver->screens[i], 0, 1); +		sleep(1); +		testCursor(driver->fd, driver->screens[i].crtc->crtc_id); +	} + +	sleep(2); +	printf("taking down screens\n"); +	for (i = 0; i < num; i++) { +		demoTakeDownScreen(&driver->screens[i]); +	} + +#ifdef CLEAN_FBDEV +	if (ioctl(fbdev_fd, FBIOPUT_VSCREENINFO, &var)) +		printf("var  %s\n", strerror(errno)); + +	close(fbdev_fd); +#endif + +	printf("ok\n"); +	return 0; +} + +int demoCreateScreens(struct demo_driver *driver) +{ +	drmModeOutputPtr out[MAX_FIND_OUTPUTS]; +	int num; +	int num_screens = 0; +	struct demo_screen *screen; +	int ret = 0; +	int i; + +	num = demoFindConnectedOutputs(driver, out, MAX_FIND_OUTPUTS); +	if (num < 0) +		return 0; + +	printf("found %i connected outputs\n", num); + +	for (i = 0; i < num; i++) { +		screen = &driver->screens[i]; + +		screen->crtc = demoFindFreeCrtc(driver, out[i]); +		if (!screen->crtc) { +			printf("found no free crtc for output\n"); +			drmModeFreeOutput(out[i]); +			continue; +		} + +		screen->fb = createFB(driver->fd, driver->res); +		if (!screen->fb) { +			drmModeFreeOutput(out[i]); +			drmModeFreeCrtc(screen->crtc); +			screen->crtc = 0; +			printf("could not create framebuffer\n"); +			continue; +		} + +		screen->virt_x = SIZE_X; +		screen->virt_y = SIZE_Y; +		screen->pitch = PITCH; + +		screen->outputs[0] = out[i]; +		screen->outputs_id[0] = out[i]->output_id; +		screen->num_outputs = 1; + +		screen->mode = &mode; +		screen->driver = driver; + +		ret = drmModeSetCrtc( +			driver->fd, +			screen->crtc->crtc_id, +			screen->fb->buffer_id, +			0, 0, +			screen->outputs_id, screen->num_outputs, +			screen->mode); + +		if (ret) { +			printf("failed to set mode\n"); +			demoTakeDownScreen(screen); +		} else { +			num_screens++; +		} + +		demoUpdateRes(driver); +	} + +	return num_screens; +} + +int demoCreateScreenCloned(struct demo_driver *driver) +{ +	drmModeOutputPtr out[MAX_FIND_OUTPUTS]; +	int num; +	struct demo_screen *screen; +	int ret = 0; +	int i; + +	num = demoFindConnectedOutputs(driver, out, MAX_FIND_OUTPUTS); +	if (num < 0) +		return 0; + +	printf("found %i connected outputs\n", num); + +	screen = &driver->screens[0]; + +	screen->fb = createFB(driver->fd, driver->res); +	if (!screen->fb) { +		printf("could not create framebuffer\n"); +		return 0; +	} + +	screen->mode = &mode; +	screen->driver = driver; + +	screen->virt_x = SIZE_X; +	screen->virt_y = SIZE_Y; +	screen->pitch = PITCH; + +	screen->num_outputs = 0; +	for (i = 0; i < num; i++) { +		screen->crtc = demoFindFreeCrtc(driver, out[i]); +		if (!screen->crtc) { +			printf("found no free crtc for output\n"); +			drmModeFreeOutput(out[i]); +			continue; +		} + +		screen->outputs[screen->num_outputs] = out[i]; +		screen->outputs_id[screen->num_outputs] = out[i]->output_id; +		screen->num_outputs++; +		printf("%u, %u\n", out[i]->output_id, screen->num_outputs); +	} + +	ret = drmModeSetCrtc( +			driver->fd, +			screen->crtc->crtc_id, +			screen->fb->buffer_id, +			0, 0, +			screen->outputs_id, screen->num_outputs, +			screen->mode); + +	if (ret) { +		printf("failed to set mode\n"); +		demoTakeDownScreen(screen); +		return 0; +	} + +	demoUpdateRes(driver); + +	return 1; +} + +void demoTakeDownScreen(struct demo_screen *screen) +{ +	int fd = screen->driver->fd; +	int i; +	drmBO bo; + +#if 0 +	/* This can bust the fbdev arrangement as it basically unhooks +	 * the outputs and the fbdev backend doesn't know how to put things +	 * back on track. Realistically, it's up to the crtc owner to restore +	 * things..... +	 * +	 * So if you are mixing API's make sure the modesetting owner puts +	 * back the original CRTC arrangement so fbdev can continue... +	 * +  	 * Ho-hum.. +	 */ +	if (screen->crtc) +		drmModeSetCrtc(fd, screen->crtc->crtc_id, 0, 0, 0, 0, 0, 0); +#endif + +	if (screen->fb) +		drmModeRmFB(fd, screen->fb->buffer_id); + +	/* maybe we should keep a pointer to the bo on the screen */ +	if (screen->fb && !drmBOReference(fd, screen->fb->handle, &bo)) { +		drmBOUnreference(fd, &bo); +		drmBOUnreference(fd, &bo); +	} else { +		printf("bo error\n"); +	} + +	for (i = 0; i < screen->num_outputs; i++) { +		drmModeFreeOutput(screen->outputs[i]); +		screen->outputs[i] = NULL; +	} + +	drmModeFreeCrtc(screen->crtc); +	drmModeFreeFB(screen->fb); + +	screen->crtc = NULL; +	screen->fb = NULL; +} + +drmModeCrtcPtr demoFindFreeCrtc(struct demo_driver *driver, drmModeOutputPtr output) +{ +	drmModeCrtcPtr crtc; +	int i, j, used = 0; +	drmModeResPtr res = driver->res; + +	for (i = 0; i < res->count_crtcs; i++) { +		used = 0; +		for (j = 0; j < DEMO_MAX_SCREENS; j++) { +			crtc = driver->screens[j].crtc; + +			if (crtc && crtc->crtc_id == res->crtcs[i]) +				used = 1; +		} + +		if (!used) { +			crtc = drmModeGetCrtc(driver->fd, res->crtcs[i]); +			break; +		} else { +			crtc = 0; +		} +	} + +	return crtc; +} + +static int driverfd; + +static void +hotplugSIGNAL(int sig, siginfo_t *si, void *d) +{ +	union drm_wait_hotplug hw; +	int ret; + +	printf("GOT HOTPLUG EVENT!\n"); + +	/* ask for another hotplug event ! */ +	memset(&hw, 0, sizeof(hw)); +	hw.request.type = _DRM_HOTPLUG_SIGNAL; +	hw.request.signal = SIGUSR1; +       	ret = ioctl(driverfd, DRM_IOCTL_WAIT_HOTPLUG, &hw); +} + +struct demo_driver* demoCreateDriver(void) +{ +	struct demo_driver* driver = malloc(sizeof(struct demo_driver)); +	union drm_wait_hotplug hw; +	int ret = 0; + +	memset(driver, 0, sizeof(struct demo_driver)); + +	driver->fd = drmOpen("i915",NULL); + +	if (driver->fd < 0) { +		printf("Failed to open the card fb\n"); +		goto err_driver; +	} + +#if 0 +	/* ioctl wait for hotplug */ +	do { +		memset(&hw, 0, sizeof(hw)); +       		ret = ioctl(driver->fd, DRM_IOCTL_WAIT_HOTPLUG, &hw); +		printf("HOTPLUG %d %d %d\n",ret,errno,hw.reply.counter); +	} while (ret && errno == EBUSY); +#else  +	/* signal for hotplug */ +	{ +		struct sigaction sa; +		struct sigaction osa; + +		sigemptyset(&sa.sa_mask); +		sa.sa_flags = SA_SIGINFO; +		sa.sa_sigaction = hotplugSIGNAL; +		sigaction(SIGUSR1, &sa, &osa); + +		driverfd = driver->fd; + +		memset(&hw, 0, sizeof(hw)); +		hw.request.type = _DRM_HOTPLUG_SIGNAL; +		hw.request.signal = SIGUSR1; +       		ret = ioctl(driver->fd, DRM_IOCTL_WAIT_HOTPLUG, &hw); +	} +#endif + +	demoUpdateRes(driver); +	if (!driver->res) { +		printf("could not retrive resources\n"); +		goto err_res; +	} + +	return driver; + +err_res: +	drmClose(driver->fd); +err_driver: +	free(driver); +	return NULL; +} + +void demoUpdateRes(struct demo_driver *driver) +{ +	if (driver->res) +		drmModeFreeResources(driver->res); + +	driver->res = drmModeGetResources(driver->fd); + +	if (!driver->res) +		printf("failed to get resources from kernel\n"); +} + +int demoFindConnectedOutputs(struct demo_driver *driver, drmModeOutputPtr *out, size_t max_out) +{ +	int count = 0; +	int i,j; +	int fd = driver->fd; +	drmModeResPtr res = driver->res; + +	drmModeOutputPtr output; + +	for (i = 0; i < res->count_outputs && count < max_out; i++) { +		output = drmModeGetOutput(fd, res->outputs[i]); + +		if (!output) +			continue; + +		if (output->connection == DRM_MODE_DISCONNECTED) { +			drmModeFreeOutput(output); +			continue; +		} +		 +		for (j = 0; j < output->count_props; j++) { +			drmModePropertyPtr prop; + +			prop = drmModeGetProperty(fd, output->props[j]); + +			printf("Property: %s\n",prop->name); +			if (prop->count_enums) +				printf("%s\n",prop->enums[output->prop_values[j]].name); +		} + +		out[count++] = output; +	} + +	return count; +} + +void demoPanScreen(struct demo_screen *screen, uint16_t x, uint16_t y) +{ +	drmModeSetCrtc( +		screen->driver->fd, +		screen->crtc->crtc_id, +		screen->fb->buffer_id, +		x, y, +		screen->outputs_id, screen->num_outputs, +		screen->mode); +} + +drmModeFBPtr createFB(int fd, drmModeResPtr res) +{ +	drmModeFBPtr frame; +	unsigned int fb = 0; +	int ret = 0; +	drmBO bo; + +	ret = drmBOCreate(fd, SIZE_X * SIZE_Y * 4, 0, 0, +		DRM_BO_FLAG_READ | +		DRM_BO_FLAG_WRITE | +		DRM_BO_FLAG_MEM_TT | +		DRM_BO_FLAG_MEM_VRAM | +		DRM_BO_FLAG_NO_EVICT, +		DRM_BO_HINT_DONT_FENCE, &bo); + +	if (ret) { +		printf("failed to create framebuffer (ret %d)\n",ret); +		goto err; +	} + +	ret = drmModeAddFB(fd, SIZE_X, SIZE_Y, 32, 32, PITCH * 4, bo.handle, &fb); + +	if (ret) +		goto err_bo; + +	frame = drmModeGetFB(fd, fb); + +	if (!frame) +		goto err_bo; + +	return frame; + +err_bo: +	drmBOUnreference(fd, &bo); +err: +	return 0; +} + +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 * PITCH) + j] = v; + +} + +void prettyColors(int fd, unsigned int handle) +{ +	drmBO bo; +	unsigned int *ptr; +	int i; + +	drmBOReference(fd, handle, &bo); +	drmBOMap(fd, &bo, DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE, 0, (void**)&ptr); + +	for (i = 0; i < (SIZE_X*SIZE_Y); i++) +		ptr[i] = 0xFFFFFFFF; + +	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); + +	drmBOUnmap(fd, &bo); +} + +void testCursor(int fd, uint32_t crtc) +{ +	drmBO bo; +	int ret; +	ret = drmBOCreate(fd, 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); + +	prettyCursor(fd, bo.handle, 0xFFFF00FF); +	printf("set cursor\n"); +	drmModeSetCursor(fd, crtc, &bo, 64, 64); +	printf("move cursor 0, 0\n"); +	drmModeMoveCursor(fd, crtc, 0, 0); +	sleep(1); +	prettyCursor(fd, bo.handle, 0xFFFF0000); +	printf("move cursor 40, 40\n"); +	drmModeMoveCursor(fd, crtc, 40, 40); +	sleep(1); +	printf("move cursor 100, 100\n"); +	drmModeMoveCursor(fd, crtc, 100, 100); +	sleep(1); +	drmModeSetCursor(fd, crtc, NULL, 0, 0); +} + +void prettyCursor(int fd, unsigned int handle, unsigned int color) +{ +	drmBO bo; +	unsigned int *ptr; +	int i; + +	drmBOReference(fd, handle, &bo); +	drmBOMap(fd, &bo, DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE, 0, (void**)&ptr); + +	for (i = 0; i < (64 * 64); i++) +		ptr[i] = color; + +	drmBOUnmap(fd, &bo); +	drmBOUnreference(fd, &bo); +} diff --git a/tests/modedemo/test b/tests/modedemo/test new file mode 100755 index 00000000..f98e3708 --- /dev/null +++ b/tests/modedemo/test @@ -0,0 +1 @@ +LD_PRELOAD=../../libdrm/.libs/libdrm.so ./app 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..b6d1f65b --- /dev/null +++ b/tests/modefb/demo.c @@ -0,0 +1,231 @@ +#include <stdio.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); + +extern void sleep(int); + +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, 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, NULL, 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 diff --git a/tests/modehotplug/Makefile b/tests/modehotplug/Makefile new file mode 100644 index 00000000..467fb11a --- /dev/null +++ b/tests/modehotplug/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/modehotplug/demo.c b/tests/modehotplug/demo.c new file mode 100644 index 00000000..4ef2e386 --- /dev/null +++ b/tests/modehotplug/demo.c @@ -0,0 +1,157 @@ + +#include <assert.h> +#include <stdio.h> +#include <stdlib.h> +#include <stdint.h> +#include <unistd.h> +#include <string.h> + +#include "xf86drm.h" +#include "xf86drmMode.h" + +/* structs for the demo_driver */ + +#define DEMO_MAX_OUTPUTS 8 + +struct demo_driver +{ +	/* drm stuff */ +	int fd; +	drmModeResPtr res; +	uint32_t counter; + +	drmModeOutputPtr outputs[DEMO_MAX_OUTPUTS]; +}; + +struct demo_driver* demoCreateDriver(void); +void demoUpdateRes(struct demo_driver *driver); + +void demoPopulateOutputs(struct demo_driver *driver); +void demoHotplug(struct demo_driver *driver); + +const char* demoGetStatus(drmModeOutputPtr out); + +int main(int argc, char **argv) +{ +	struct demo_driver *driver; +	uint32_t temp; +	int i; + +	printf("starting demo\n"); + +	driver = demoCreateDriver(); + +	if (!driver) { +		printf("failed to create driver\n"); +		return 1; +	} + +	driver->counter = drmModeGetHotplug(driver->fd); +	demoPopulateOutputs(driver); +	while (driver->counter != (temp = drmModeGetHotplug(driver->fd))) { +		demoPopulateOutputs(driver); +		driver->counter = temp; +	} + +	for (i = 0; i < driver->res->count_outputs && i < DEMO_MAX_OUTPUTS; i++) { +		printf("Output %u is %s\n", +			driver->outputs[i]->output_id, +			demoGetStatus(driver->outputs[i])); +	} + +	while(1) { +		usleep(100000); +		temp = drmModeGetHotplug(driver->fd); +		if (temp == driver->counter) +			continue; + +		demoHotplug(driver); +		driver->counter = temp; +	} + +	return 0; +} + +const char* demoGetStatus(drmModeOutputPtr output) +{ +	switch (output->connection) { +		case DRM_MODE_CONNECTED: +			return "connected"; +		case DRM_MODE_DISCONNECTED: +			return "disconnected"; +		default: +			return "unknown"; +	} +} + +void demoHotplug(struct demo_driver *driver) +{ +	drmModeResPtr res = driver->res; +	int i; +	drmModeOutputPtr temp, current; + +	for (i = 0; i < res->count_outputs && i < DEMO_MAX_OUTPUTS; i++) { +		temp = drmModeGetOutput(driver->fd, res->outputs[i]); +		current = driver->outputs[i]; + +		if (temp->connection != current->connection) { +			printf("Output %u became %s was %s\n", +				temp->output_id, +				demoGetStatus(temp), +				demoGetStatus(current)); +		} + +		drmModeFreeOutput(current); +		driver->outputs[i] = temp; +	} +} + +void demoPopulateOutputs(struct demo_driver *driver) +{ +	drmModeResPtr res = driver->res; +	int i; + +	for (i = 0; i < res->count_outputs && i < DEMO_MAX_OUTPUTS; i++) { +		drmModeFreeOutput(driver->outputs[i]); +		driver->outputs[i] = drmModeGetOutput(driver->fd, res->outputs[i]); +	} +} + +struct demo_driver* demoCreateDriver(void) +{ +	struct demo_driver* driver = malloc(sizeof(struct demo_driver)); + +	memset(driver, 0, sizeof(struct demo_driver)); + +	driver->fd = drmOpen("i915", NULL); + +	if (driver->fd < 0) { +		printf("Failed to open the card fb\n"); +		goto err_driver; +	} + +	demoUpdateRes(driver); +	if (!driver->res) { +		printf("could not retrive resources\n"); +		goto err_res; +	} + +	return driver; + +err_res: +	drmClose(driver->fd); +err_driver: +	free(driver); +	return NULL; +} + +void demoUpdateRes(struct demo_driver *driver) +{ +	if (driver->res) +		drmModeFreeResources(driver->res); + +	driver->res = drmModeGetResources(driver->fd); + +	if (!driver->res) +		printf("failed to get resources from kernel\n"); +} diff --git a/tests/modehotplug/test b/tests/modehotplug/test new file mode 100755 index 00000000..f98e3708 --- /dev/null +++ b/tests/modehotplug/test @@ -0,0 +1 @@ +LD_PRELOAD=../../libdrm/.libs/libdrm.so ./app | 
