diff options
| author | Alan Hourihane <alanh@fairlite.demon.co.uk> | 2007-04-12 15:10:08 +0100 | 
|---|---|---|
| committer | Alan Hourihane <alanh@fairlite.demon.co.uk> | 2007-04-12 15:10:08 +0100 | 
| commit | 9420ab4b419458605c678d179de6c80de23b8ee1 (patch) | |
| tree | 9fb796bbcc3b80f7e89029bc5fd4668554d698ea /libdrm | |
| parent | 9b7211dd6793dc62d11ad1ae980b22fa2d61f9dd (diff) | |
| parent | b1f0fd6dfbd1495aa08c6358e936582eeca042c8 (diff) | |
Merge remote branch 'origin/modesetting-101' into modesetting-101
Diffstat (limited to 'libdrm')
| -rw-r--r-- | libdrm/Makefile.am | 4 | ||||
| -rw-r--r-- | libdrm/xf86drmMode.c | 412 | ||||
| -rw-r--r-- | libdrm/xf86drmMode.h | 284 | 
3 files changed, 698 insertions, 2 deletions
| diff --git a/libdrm/Makefile.am b/libdrm/Makefile.am index e7e07e47..24c32038 100644 --- a/libdrm/Makefile.am +++ b/libdrm/Makefile.am @@ -23,9 +23,9 @@ libdrm_ladir = $(libdir)  libdrm_la_LDFLAGS = -version-number 2:3:0 -no-undefined  AM_CFLAGS = -I$(top_srcdir)/shared-core -libdrm_la_SOURCES = xf86drm.c xf86drmHash.c xf86drmRandom.c xf86drmSL.c +libdrm_la_SOURCES = xf86drm.c xf86drmHash.c xf86drmRandom.c xf86drmSL.c xf86drmMode.c  libdrmincludedir = ${includedir} -libdrminclude_HEADERS = xf86drm.h xf86mm.h +libdrminclude_HEADERS = xf86drm.h xf86mm.h xf86drmMode.h  EXTRA_DIST = ChangeLog TODO diff --git a/libdrm/xf86drmMode.c b/libdrm/xf86drmMode.c new file mode 100644 index 00000000..b695467b --- /dev/null +++ b/libdrm/xf86drmMode.c @@ -0,0 +1,412 @@ +/* + * \file xf86drmMode.c + * Header for DRM modesetting interface. + * + * \author Jakob Bornecrantz <wallbraker@gmail.com> + * + * \par Acknowledgements: + * Feb 2007, Dave Airlie <airlied@linux.ie> + */ + +/* + * Copyright (c) <year> <copyright holders> + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + * + */ + +/* + * TODO the types we are after are defined in diffrent headers on diffrent + * platforms find which headers to include to get uint32_t + */ +#include <stdint.h> + +#include "xf86drmMode.h" +#include "xf86drm.h" +#include <drm.h> +#include <string.h> + +/* + * Util functions + */ + +void* drmAllocCpy(void *array, int count, int entry_size) +{ +	char *r; +	int i; + +	if (!count || !array || !entry_size) +		return 0; + +	if (!(r = drmMalloc(count*entry_size))) +		return 0; + +	for (i = 0; i < count; i++) +		memcpy(r+(entry_size*i), array+(entry_size*i), entry_size); + +	return r; +} + +/** + * Generate crtc and output ids. + * + * Will generate ids starting from 1 up to count if count is greater then 0. + */ +static uint32_t* drmAllocGenerate(int count) +{ +	uint32_t *r; +	int i; + +	if(0 <= count) +		return 0; + +	if (!(r = drmMalloc(count*sizeof(*r)))) +		return 0; + +	for (i = 0; i < count; r[i] = ++i); + +	return 0; +} + +/* + * A couple of free functions. + */ + +void drmModeFreeModeInfo(struct drm_mode_modeinfo *ptr) +{ +	if (!ptr) +		return; + +	drmFree(ptr); +} + +void drmModeFreeResources(drmModeResPtr ptr) +{ +	if (!ptr) +		return; + +	drmFree(ptr->modes); +	drmFree(ptr); + +} + +void drmModeFreeFB(drmModeFBPtr ptr) +{ +	if (!ptr) +		return; + +	/* we might add more frees later. */ +	drmFree(ptr); +} + +void drmModeFreeCrtc(drmModeCrtcPtr ptr) +{ +	if (!ptr) +		return; + +	drmFree(ptr); + +} + +void drmModeFreeOutput(drmModeOutputPtr ptr) +{ +	if (!ptr) +		return; + +	drmFree(ptr->modes); +	drmFree(ptr); + +} + +/* + * ModeSetting functions. + */ + +drmModeResPtr drmModeGetResources(int fd) +{ +	struct drm_mode_card_res res; +	int i; +	drmModeResPtr r = 0; + +	memset(&res, 0, sizeof(struct drm_mode_card_res)); + +	if (ioctl(fd, DRM_IOCTL_MODE_GETRESOURCES, &res)) +		return 0; + +	if (res.count_fbs) +		res.fb_id = drmMalloc(res.count_fbs*sizeof(uint32_t)); +	if (res.count_crtcs) +		res.crtc_id = drmMalloc(res.count_crtcs*sizeof(uint32_t)); +	if (res.count_outputs) +		res.output_id = drmMalloc(res.count_outputs*sizeof(uint32_t)); +	if (res.count_modes) +		res.modes = drmMalloc(res.count_modes*sizeof(*res.modes)); + +	if (ioctl(fd, DRM_IOCTL_MODE_GETRESOURCES, &res)) { +		r = NULL; +		goto err_allocs; +	} + +	/* +	 * return +	 */ + + +	if (!(r = drmMalloc(sizeof(*r)))) +		return 0; + +	r->count_fbs     = res.count_fbs; +	r->count_crtcs   = res.count_crtcs; +	r->count_outputs = res.count_outputs; +	r->count_modes   = res.count_modes; +	/* TODO we realy should test if these allocs fails. */ +	r->fbs           = drmAllocCpy(res.fb_id, res.count_fbs, sizeof(uint32_t)); +	r->crtcs         = drmAllocCpy(res.crtc_id, res.count_crtcs, sizeof(uint32_t)); +	r->outputs       = drmAllocCpy(res.output_id, res.count_outputs, sizeof(uint32_t)); +	r->modes         = drmAllocCpy(res.modes, res.count_modes, sizeof(struct drm_mode_modeinfo)); + +err_allocs: +	drmFree(res.fb_id); +	drmFree(res.crtc_id); +	drmFree(res.output_id); +	drmFree(res.modes); + +	return r; +} + +int drmModeAddFB(int fd, uint32_t width, uint32_t height, uint8_t depth, +                 uint8_t bpp, uint32_t pitch, drmBO *bo, uint32_t *buf_id) +{ +	struct drm_mode_fb_cmd f; +	int ret; + +	f.width  = width; +	f.height = height; +	f.pitch  = pitch; +	f.bpp    = bpp; +	f.depth  = depth; +	f.handle = bo->handle; + +	if (ret = ioctl(fd, DRM_IOCTL_MODE_ADDFB, &f)) +		return ret; + +	*buf_id = f.buffer_id; +	return 0; +} + +int drmModeRmFB(int fd, uint32_t bufferId) +{ +	return ioctl(fd, DRM_IOCTL_MODE_RMFB, bufferId); +} + +drmModeFBPtr drmModeGetFB(int fd, uint32_t buf) +{ +	struct drm_mode_fb_cmd info; +	drmModeFBPtr r; + +	info.buffer_id = buf; + +	if (ioctl(fd, DRM_IOCTL_MODE_GETFB, &info)) +		return NULL; + +	if (!(r = drmMalloc(sizeof(*r)))) +		return NULL; + +	r->buffer_id = info.buffer_id; +	r->width = info.width; +	r->height = info.height; +	r->pitch = info.pitch; +	r->bpp = info.bpp; +	r->handle = info.handle; +	r->depth = info.depth; + +	return r; +} +#if 0 +int drmModeForceProbe(int fd, uint32_t outputId) +{ +	/* TODO impl/keep? */ +} + +#endif +/* + * Crtc function. + */ + +drmModeCrtcPtr drmModeGetCrtc(int fd, uint32_t crtcId) +{ +	struct drm_mode_crtc crtc; +	drmModeCrtcPtr r; +	int i = 0; + +	crtc.count_outputs   = 0; +	crtc.outputs         = 0; +	crtc.count_possibles = 0; +	crtc.possibles       = 0; +	crtc.crtc_id = crtcId; + +	if (ioctl(fd, DRM_IOCTL_MODE_GETCRTC, &crtc)) +		return 0; + +	/* +	 * return +	 */ + +	if (!(r = drmMalloc(sizeof(*r)))) +		return 0; + +	r->x               = crtc.x; +	r->y               = crtc.y; +	r->mode            = crtc.mode; +//	r->width           = crtc.width; +//	r->height          = crtc.height; +	r->buffer_id        = crtc.fb_id; +	r->gamma_size      = crtc.gamma_size; +	r->count_outputs   = crtc.count_outputs; +	r->count_possibles = crtc.count_possibles; +	/* TODO we realy should test if these alloc & cpy fails. */ +	r->outputs         = crtc.outputs; +	r->possibles       = crtc.possibles; + +	return r; + +err_allocs: + +	return 0; +} + + +int drmModeSetCrtc(int fd, uint32_t crtcId, uint32_t bufferId, +                   uint32_t x, uint32_t y, uint32_t modeId, +                   uint32_t *outputs, int count) +{ +	struct drm_mode_crtc crtc; + +	crtc.count_outputs   = 0; +	crtc.outputs         = 0; +	crtc.count_possibles = 0; +	crtc.possibles       = 0; + +	crtc.x             = x; +	crtc.y             = y; +	crtc.crtc_id        = crtcId; +	crtc.fb_id      = bufferId; +	crtc.set_outputs   = outputs; +	crtc.count_outputs = count; +	crtc.mode          = modeId; + +	return ioctl(fd, DRM_IOCTL_MODE_SETCRTC, &crtc); +} + +#if 0 +drmModeGammaTriplePtr drmModeGetCrtcGamma(int fd, uint32_t crtc, int *count) +{ +	/* TODO impl */ +} + +int drmModeSetCrtcGamma(int fd, uint32_t crtcId, +		drmModeGammaTriplePtr ptr, int count) +{ +	/* TODO impl */ +} + +#endif +/* + * Output manipulation + */ +drmModeOutputPtr drmModeGetOutput(int fd, uint32_t output_id) +{ +	struct drm_mode_get_output out; +	drmModeOutputPtr r = 0; + +	out.output = output_id; +	out.count_crtcs  = 0; +	out.crtcs        = 0; +	out.count_clones = 0; +	out.clones       = 0; +	out.count_modes  = 0; +	out.modes        = 0; + +	if (ioctl(fd, DRM_IOCTL_MODE_GETOUTPUT, &out)) +		return 0; + +	if (out.count_modes) +		out.modes = drmMalloc(out.count_modes*sizeof(uint32_t)); + +	if (ioctl(fd, DRM_IOCTL_MODE_GETOUTPUT, &out)) +		goto err_allocs; + +	if(!(r = drmMalloc(sizeof(*r)))) +		return 0; + +	r->connection   = out.connection; +	r->mmWidth      = out.mm_width; +	r->mmHeight     = out.mm_height; +	r->subpixel     = out.subpixel; +	r->count_crtcs  = out.count_crtcs; +	r->count_clones = out.count_clones; +	r->count_modes  = out.count_modes; +	/* TODO we should test if these alloc & cpy fails. */ +	r->crtcs        = out.crtcs; +	r->clones       = out.clones; +	r->modes        = drmAllocCpy(out.modes, out.count_modes, sizeof(uint32_t)); +	strncpy(r->name, out.name, DRM_OUTPUT_NAME_LEN); +	r->name[DRM_OUTPUT_NAME_LEN-1] = 0; +	return r; + +err_allocs: +	drmFree(out.modes); + +	return 0; +} + +#if 0 +uint32_t drmModeNewMode(int fd, struct drm_mode_modeinfo *modeInfo) +{ +	/* TODO impl */ +} + +int drmModeDesMode(int fd, uint32_t modeId) +{ +  //	return ioctl(fd, DRM_IOCTL_MODE_DESMODE, modeId); +} + +int drmModeAddMode(int fd, uint32_t outputId, uint32_t modeId) +{ + +	drm_mode_outputmode_t res; + +	res.outputId = outputId; +	res.modeId = modeId; + +	//	return ioctl(fd, DRM_IOCTL_MODE_ADDMODE, &res); +} + +int drmModeDelMode(int fd, uint32_t outputId, uint32_t modeId) +{ +	drm_mode_outputmode_t res; + +	res.outputId = outputId; +	res.modeId = modeId; + +	//	return ioctl(fd, DRM_IOCTL_MODE_DELMODE, &res); +} + +#endif + diff --git a/libdrm/xf86drmMode.h b/libdrm/xf86drmMode.h new file mode 100644 index 00000000..6aa104a9 --- /dev/null +++ b/libdrm/xf86drmMode.h @@ -0,0 +1,284 @@ +/* + * \file xf86drmMode.h + * Header for DRM modesetting interface. + * + * \author Jakob Bornecrantz <wallbraker@gmail.com> + * + * \par Acknowledgements: + * Feb 2007, Dave Airlie <airlied@linux.ie> + */ + +/* + * Copyright (c) <year> <copyright holders> + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + * + */ + +#include <drm.h> +#include "xf86mm.h" + +/* + * This is the interface for modesetting for drm. + * + * In order to use this interface you must include either <stdint.h> or another + * header defining uint32_t, int32_t and uint16_t. + * + * It aims to provide a randr compatible interface for modesettings in the + * kernel, the interface is also ment to be used by libraries like EGL. + * + * More information can be found in randrproto.txt which can be found here: + * http://gitweb.freedesktop.org/?p=xorg/proto/randrproto.git + * + * All framebuffer, crtc and output ids start at 1 while 0 is either an invalid + * parameter or used to indicate that the command should disconnect from the + * currently bound target, as with drmModeMapOutput. + * + * Currently only one framebuffer exist and has a id of 1, which is also the + * default framebuffer and should allways be avaible to the client, unless + * it is locked/used or any other limiting state is applied on it. + * + */ + +typedef struct _drmModeGammaTriple { +	uint16_t r, g, b; +} drmModeGammaTriple, *drmModeGammaTriplePtr; + +typedef struct _drmModeRes { + +	int count_fbs; +	uint32_t *fbs; + +	int count_crtcs; +	uint32_t *crtcs; + +	int count_outputs; +	uint32_t *outputs; + +	int count_modes; +	struct drm_mode_modeinfo *modes; + +} drmModeRes, *drmModeResPtr; + +typedef struct drm_mode_fb_cmd drmModeFB, *drmModeFBPtr; + +typedef struct _drmModeCrtc { + +	unsigned int buffer_id; /**< FB id to connect to 0 = disconnect*/ + +	uint32_t x, y; /**< Position on the frameuffer */ +	uint32_t width, height; +	uint32_t mode; /**< Current mode used */ + +	int count_outputs; +	uint32_t outputs; /**< Outputs that are connected */ + +	int count_possibles; +	uint32_t possibles; /**< Outputs that can be connected */ + +	int gamma_size; /**< Number of gamma stops */ + +} drmModeCrtc, *drmModeCrtcPtr; + +typedef enum { +	DRM_MODE_CONNECTED         = 1, +	DRM_MODE_DISCONNECTED      = 2, +	DRM_MODE_UNKNOWNCONNECTION = 3 +} drmModeConnection; + +typedef enum { +	DRM_MODE_SUBPIXEL_UNKNOWN        = 1, +	DRM_MODE_SUBPIXEL_HORIZONTAL_RGB = 2, +	DRM_MODE_SUBPIXEL_HORIZONTAL_BGR = 3, +	DRM_MODE_SUBPIXEL_VERTICAL_RGB   = 4, +	DRM_MODE_SUBPIXEL_VERTICAL_BGR   = 5, +	DRM_MODE_SUBPIXEL_NONE           = 6 +} drmModeSubPixel; + +typedef struct _drmModeOutput { + +	unsigned int crtc; /**< Crtc currently connected to */ +	unsigned char name[DRM_OUTPUT_NAME_LEN]; +	drmModeConnection connection; +	uint32_t mmWidth, mmHeight; /**< HxW in millimeters */ +	drmModeSubPixel subpixel; + +	int count_crtcs; +	uint32_t crtcs; /**< Possible crtc to connect to */ + +	int count_clones; +	uint32_t clones; /**< Mask of clones */ + +	int count_modes; +	uint32_t *modes; /**< List of modes ids */ + +} drmModeOutput, *drmModeOutputPtr; + +/* + * RRSetScreenConfig o + * RRGetScreenInfo o + * + * RRGetScreenSizeRange - see frameBuffer info + * RRSetScreenSize + * RRGetScreenResources + * + * RRGetOutputInfo + * + * RRListOutputProperties * + * RRQueryOutputProperty * + * RRConfigureOutputProperty * + * RRChangeOutputProperty * + * RRDeleteOutputProperty * + * RRGetOutputProperty * + * + * RRCreateMode + * RRDestroyMode + * RRAddOutputMode + * RRDeleteOutputMode + * + * RRGetCrtcInfo + * RRSetCrtcConfig + * + * RRGetCrtcGammaSize - see crtc info + * RRGetCrtcGamma + * RRSetCrtcGamma + * + * drmModeGetResources + * drmModeForceProbe + * + * drmModeGetFrameBufferInfo + * drmModeSetFrameBufferSize + * + * drmModeGetCrtcInfo + * drmModeSetCrtcConfig + * drmModeGetCrtcGamma + * drmModeSetCrtcGamma + * + * drmModeGetOutputInfo + * + * drmModeAddMode + * drmModeDestroyMode + * drmModeAddOutputMode + * drmModeDeleteOutputMode + */ + +extern void drmModeFreeModeInfo( struct drm_mode_modeinfo *ptr ); +extern void drmModeFreeResources( drmModeResPtr ptr ); +extern void drmModeFreeFB( drmModeFBPtr ptr ); +extern void drmModeFreeCrtc( drmModeCrtcPtr ptr ); +extern void drmModeFreeOutput( drmModeOutputPtr ptr ); + +/** + * Retrives all of the resources associated with a card. + */ +extern drmModeResPtr drmModeGetResources(int fd); + +/** + * Forces a probe of the give output outputId, on 0 all will be probed. + */ +extern int drmModeForceProbe(int fd, uint32_t outputId); + + +/* + * FrameBuffer manipulation. + */ + +/** + * Retrive information about framebuffer bufferId + */ +extern drmModeFBPtr drmModeGetFB(int fd, uint32_t bufferId); + +/** + * Creates a new framebuffer with an buffer object as its scanout buffer. + */ +extern int drmModeAddFB(int fd, uint32_t width, uint32_t height, uint8_t depth, +			uint8_t bpp, uint32_t pitch, drmBO *bo, +			uint32_t *buf_id); +/** + * Destroies the given framebuffer. + */ +extern int drmModeRmFB(int fd, uint32_t bufferId); + +/** + * Changes the scanout buffer to the given buffer object. + */ +extern int drmModeFlipFrameBuffer(int fd, uint32_t bufferId, drmBO *bo); + +/* + * Crtc function. + */ + +/** + * Retrive information about the ctrt crtcId + */ +extern drmModeCrtcPtr drmModeGetCrtc(int fd, uint32_t crtcId); + +/** + * Set the mode on a crtc crtcId with the given mode modeId. + */ +extern int drmModeSetCrtc(int fd, uint32_t crtcId, uint32_t bufferId, +		uint32_t x, uint32_t y, uint32_t modeId, +		uint32_t *outputs, int count); + +/** + * Gets the gamma from a crtc + */ +extern drmModeGammaTriplePtr drmModeGetCrtcGamma(int fd, uint32_t crtcId, +		int *count); + +/** + * Sets the gamma on a crtc + */ +extern int drmModeSetCrtcGamma(int fd, uint32_t crtcId, +		drmModeGammaTriplePtr ptr, int count); + + + +/* + * Output manipulation + */ + +/** + * Retrive information about the output outputId. + */ +extern drmModeOutputPtr drmModeGetOutput(int fd, +		uint32_t outputId); + +/** + * Creates a new mode from the given mode info. + * Name must be unique. + */ +extern uint32_t drmModeNewMode(int fd, struct drm_mode_modeinfo *modeInfo); + +/** + * Destroys a mode created with CreateMode, must be unused. + */ +extern int drmModeDesMode(int fd, uint32_t modeId); + +/** + * Adds the given mode to an output. + */ +extern int drmModeAddMode(int fd, uint32_t outputId, uint32_t modeId); + +/** + * Deletes a mode Added with AddOutputMode from the output, + * must be unused, by the given mode. + */ +extern int drmModeDelMode(int fd, uint32_t outputId, uint32_t modeId); + | 
