libdrm: add mode setting files
Add mode setting files to libdrm, including xf86drmMode.* and the new drm_mode.h header. Also add a couple of tests to sanity check the kernel interfaces and update code to support them.main
parent
c86d431fe6
commit
731cd5526e
|
@ -26,9 +26,10 @@ libdrm_la_LDFLAGS = -version-number 2:4:0 -no-undefined
|
||||||
|
|
||||||
AM_CFLAGS = -I$(top_srcdir)/shared-core
|
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 libdrm_lists.h
|
||||||
libdrm_lists.h
|
libdrm_lists.h
|
||||||
|
|
||||||
libdrmincludedir = ${includedir}
|
libdrmincludedir = ${includedir}
|
||||||
libdrminclude_HEADERS = xf86drm.h
|
libdrminclude_HEADERS = xf86drm.h xf86drmMode.h
|
||||||
|
|
||||||
EXTRA_DIST = ChangeLog TODO
|
EXTRA_DIST = ChangeLog TODO
|
||||||
|
|
|
@ -66,6 +66,11 @@ struct _drm_intel_bo {
|
||||||
|
|
||||||
/** Buffer manager context associated with this buffer object */
|
/** Buffer manager context associated with this buffer object */
|
||||||
drm_intel_bufmgr *bufmgr;
|
drm_intel_bufmgr *bufmgr;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* MM-specific handle for accessing object
|
||||||
|
*/
|
||||||
|
int handle;
|
||||||
};
|
};
|
||||||
|
|
||||||
drm_intel_bo *drm_intel_bo_alloc(drm_intel_bufmgr *bufmgr, const char *name,
|
drm_intel_bo *drm_intel_bo_alloc(drm_intel_bufmgr *bufmgr, const char *name,
|
||||||
|
|
|
@ -351,6 +351,7 @@ drm_intel_gem_bo_alloc(drm_intel_bufmgr *bufmgr, const char *name,
|
||||||
|
|
||||||
ret = ioctl(bufmgr_gem->fd, DRM_IOCTL_I915_GEM_CREATE, &create);
|
ret = ioctl(bufmgr_gem->fd, DRM_IOCTL_I915_GEM_CREATE, &create);
|
||||||
bo_gem->gem_handle = create.handle;
|
bo_gem->gem_handle = create.handle;
|
||||||
|
bo_gem->bo.handle = bo_gem->gem_handle;
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
free(bo_gem);
|
free(bo_gem);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
|
@ -87,6 +87,9 @@
|
||||||
|
|
||||||
#define DRM_MSG_VERBOSITY 3
|
#define DRM_MSG_VERBOSITY 3
|
||||||
|
|
||||||
|
#define DRM_NODE_CONTROL 0
|
||||||
|
#define DRM_NODE_RENDER 1
|
||||||
|
|
||||||
static drmServerInfoPtr drm_server_info;
|
static drmServerInfoPtr drm_server_info;
|
||||||
|
|
||||||
void drmSetServerInfo(drmServerInfoPtr info)
|
void drmSetServerInfo(drmServerInfoPtr info)
|
||||||
|
@ -174,7 +177,7 @@ static char *drmStrdup(const char *s)
|
||||||
/**
|
/**
|
||||||
* Call ioctl, restarting if it is interupted
|
* Call ioctl, restarting if it is interupted
|
||||||
*/
|
*/
|
||||||
static int
|
int
|
||||||
drmIoctl(int fd, unsigned long request, void *arg)
|
drmIoctl(int fd, unsigned long request, void *arg)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
@ -277,7 +280,7 @@ static int drmMatchBusID(const char *id1, const char *id2)
|
||||||
* special file node with the major and minor numbers specified by \p dev and
|
* special file node with the major and minor numbers specified by \p dev and
|
||||||
* parent directory if necessary and was called by root.
|
* parent directory if necessary and was called by root.
|
||||||
*/
|
*/
|
||||||
static int drmOpenDevice(long dev, int minor)
|
static int drmOpenDevice(long dev, int minor, int type)
|
||||||
{
|
{
|
||||||
stat_t st;
|
stat_t st;
|
||||||
char buf[64];
|
char buf[64];
|
||||||
|
@ -287,7 +290,7 @@ static int drmOpenDevice(long dev, int minor)
|
||||||
uid_t user = DRM_DEV_UID;
|
uid_t user = DRM_DEV_UID;
|
||||||
gid_t group = DRM_DEV_GID, serv_group;
|
gid_t group = DRM_DEV_GID, serv_group;
|
||||||
|
|
||||||
sprintf(buf, DRM_DEV_NAME, DRM_DIR_NAME, minor);
|
sprintf(buf, type ? DRM_DEV_NAME : DRM_CONTROL_DEV_NAME, DRM_DIR_NAME, minor);
|
||||||
drmMsg("drmOpenDevice: node name is %s\n", buf);
|
drmMsg("drmOpenDevice: node name is %s\n", buf);
|
||||||
|
|
||||||
if (drm_server_info) {
|
if (drm_server_info) {
|
||||||
|
@ -386,15 +389,15 @@ wait_for_udev:
|
||||||
* Calls drmOpenDevice() if \p create is set, otherwise assembles the device
|
* Calls drmOpenDevice() if \p create is set, otherwise assembles the device
|
||||||
* name from \p minor and opens it.
|
* name from \p minor and opens it.
|
||||||
*/
|
*/
|
||||||
static int drmOpenMinor(int minor, int create)
|
static int drmOpenMinor(int minor, int create, int type)
|
||||||
{
|
{
|
||||||
int fd;
|
int fd;
|
||||||
char buf[64];
|
char buf[64];
|
||||||
|
|
||||||
if (create)
|
if (create)
|
||||||
return drmOpenDevice(makedev(DRM_MAJOR, minor), minor);
|
return drmOpenDevice(makedev(DRM_MAJOR, minor), minor, type);
|
||||||
|
|
||||||
sprintf(buf, DRM_DEV_NAME, DRM_DIR_NAME, minor);
|
sprintf(buf, type ? DRM_DEV_NAME : DRM_CONTROL_DEV_NAME, DRM_DIR_NAME, minor);
|
||||||
if ((fd = open(buf, O_RDWR, 0)) >= 0)
|
if ((fd = open(buf, O_RDWR, 0)) >= 0)
|
||||||
return fd;
|
return fd;
|
||||||
return -errno;
|
return -errno;
|
||||||
|
@ -417,7 +420,7 @@ int drmAvailable(void)
|
||||||
int retval = 0;
|
int retval = 0;
|
||||||
int fd;
|
int fd;
|
||||||
|
|
||||||
if ((fd = drmOpenMinor(0, 1)) < 0) {
|
if ((fd = drmOpenMinor(0, 1, DRM_NODE_RENDER)) < 0) {
|
||||||
#ifdef __linux__
|
#ifdef __linux__
|
||||||
/* Try proc for backward Linux compatibility */
|
/* Try proc for backward Linux compatibility */
|
||||||
if (!access("/proc/dri/0", R_OK))
|
if (!access("/proc/dri/0", R_OK))
|
||||||
|
@ -458,7 +461,7 @@ static int drmOpenByBusid(const char *busid)
|
||||||
|
|
||||||
drmMsg("drmOpenByBusid: Searching for BusID %s\n", busid);
|
drmMsg("drmOpenByBusid: Searching for BusID %s\n", busid);
|
||||||
for (i = 0; i < DRM_MAX_MINOR; i++) {
|
for (i = 0; i < DRM_MAX_MINOR; i++) {
|
||||||
fd = drmOpenMinor(i, 1);
|
fd = drmOpenMinor(i, 1, DRM_NODE_RENDER);
|
||||||
drmMsg("drmOpenByBusid: drmOpenMinor returns %d\n", fd);
|
drmMsg("drmOpenByBusid: drmOpenMinor returns %d\n", fd);
|
||||||
if (fd >= 0) {
|
if (fd >= 0) {
|
||||||
sv.drm_di_major = 1;
|
sv.drm_di_major = 1;
|
||||||
|
@ -520,7 +523,7 @@ static int drmOpenByName(const char *name)
|
||||||
* already in use. If it's in use it will have a busid assigned already.
|
* already in use. If it's in use it will have a busid assigned already.
|
||||||
*/
|
*/
|
||||||
for (i = 0; i < DRM_MAX_MINOR; i++) {
|
for (i = 0; i < DRM_MAX_MINOR; i++) {
|
||||||
if ((fd = drmOpenMinor(i, 1)) >= 0) {
|
if ((fd = drmOpenMinor(i, 1, DRM_NODE_RENDER)) >= 0) {
|
||||||
if ((version = drmGetVersion(fd))) {
|
if ((version = drmGetVersion(fd))) {
|
||||||
if (!strcmp(version->name, name)) {
|
if (!strcmp(version->name, name)) {
|
||||||
drmFreeVersion(version);
|
drmFreeVersion(version);
|
||||||
|
@ -564,7 +567,7 @@ static int drmOpenByName(const char *name)
|
||||||
if (*pt) { /* Found busid */
|
if (*pt) { /* Found busid */
|
||||||
return drmOpenByBusid(++pt);
|
return drmOpenByBusid(++pt);
|
||||||
} else { /* No busid */
|
} else { /* No busid */
|
||||||
return drmOpenDevice(strtol(devstring, NULL, 0),i);
|
return drmOpenDevice(strtol(devstring, NULL, 0),i, DRM_NODE_RENDER);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -614,6 +617,10 @@ int drmOpen(const char *name, const char *busid)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int drmOpenControl(int minor)
|
||||||
|
{
|
||||||
|
return drmOpenMinor(minor, 0, DRM_NODE_CONTROL);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Free the version information returned by drmGetVersion().
|
* Free the version information returned by drmGetVersion().
|
||||||
|
@ -2434,3 +2441,20 @@ void drmCloseOnce(int fd)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int drmSetMaster(int fd)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
fprintf(stderr,"Setting master \n");
|
||||||
|
ret = ioctl(fd, DRM_IOCTL_SET_MASTER, 0);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int drmDropMaster(int fd)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
fprintf(stderr,"Dropping master \n");
|
||||||
|
ret = ioctl(fd, DRM_IOCTL_DROP_MASTER, 0);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
|
@ -49,6 +49,7 @@
|
||||||
|
|
||||||
#define DRM_DIR_NAME "/dev/dri"
|
#define DRM_DIR_NAME "/dev/dri"
|
||||||
#define DRM_DEV_NAME "%s/card%d"
|
#define DRM_DEV_NAME "%s/card%d"
|
||||||
|
#define DRM_CONTROL_DEV_NAME "%s/controlD%d"
|
||||||
#define DRM_PROC_NAME "/proc/dri/" /* For backward Linux compatibility */
|
#define DRM_PROC_NAME "/proc/dri/" /* For backward Linux compatibility */
|
||||||
|
|
||||||
#define DRM_ERR_NO_DEVICE (-1001)
|
#define DRM_ERR_NO_DEVICE (-1001)
|
||||||
|
@ -74,6 +75,7 @@ typedef struct drmHashEntry {
|
||||||
void *tagTable;
|
void *tagTable;
|
||||||
} drmHashEntry;
|
} drmHashEntry;
|
||||||
|
|
||||||
|
extern int drmIoctl(int fd, unsigned long request, void *arg);
|
||||||
extern void *drmGetHashTable(void);
|
extern void *drmGetHashTable(void);
|
||||||
extern drmHashEntry *drmGetEntry(int fd);
|
extern drmHashEntry *drmGetEntry(int fd);
|
||||||
|
|
||||||
|
@ -508,6 +510,7 @@ do { register unsigned int __old __asm("o0"); \
|
||||||
/* General user-level programmer's API: unprivileged */
|
/* General user-level programmer's API: unprivileged */
|
||||||
extern int drmAvailable(void);
|
extern int drmAvailable(void);
|
||||||
extern int drmOpen(const char *name, const char *busid);
|
extern int drmOpen(const char *name, const char *busid);
|
||||||
|
extern int drmOpenControl(int minor);
|
||||||
extern int drmClose(int fd);
|
extern int drmClose(int fd);
|
||||||
extern drmVersionPtr drmGetVersion(int fd);
|
extern drmVersionPtr drmGetVersion(int fd);
|
||||||
extern drmVersionPtr drmGetLibVersion(int fd);
|
extern drmVersionPtr drmGetLibVersion(int fd);
|
||||||
|
@ -659,4 +662,7 @@ extern int drmOpenOnce(void *unused, const char *BusID, int *newlyopened);
|
||||||
extern void drmCloseOnce(int fd);
|
extern void drmCloseOnce(int fd);
|
||||||
extern void drmMsg(const char *format, ...);
|
extern void drmMsg(const char *format, ...);
|
||||||
|
|
||||||
|
extern int drmSetMaster(int fd);
|
||||||
|
extern int drmDropMaster(int fd);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -0,0 +1,686 @@
|
||||||
|
/*
|
||||||
|
* \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) 2007-2008 Tungsten Graphics, Inc., Cedar Park, Texas.
|
||||||
|
* Copyright (c) 2007-2008 Dave Airlie <airlied@linux.ie>
|
||||||
|
* Copyright (c) 2007-2008 Jakob Bornecrantz <wallbraker@gmail.com>
|
||||||
|
*
|
||||||
|
* 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 <sys/ioctl.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include "xf86drmMode.h"
|
||||||
|
#include "xf86drm.h"
|
||||||
|
#include <drm.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <dirent.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
#define U642VOID(x) ((void *)(unsigned long)(x))
|
||||||
|
#define VOID2U64(x) ((uint64_t)(unsigned long)(x))
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
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 drmModeFreeConnector(drmModeConnectorPtr ptr)
|
||||||
|
{
|
||||||
|
if (!ptr)
|
||||||
|
return;
|
||||||
|
|
||||||
|
drmFree(ptr->modes);
|
||||||
|
drmFree(ptr);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void drmModeFreeEncoder(drmModeEncoderPtr ptr)
|
||||||
|
{
|
||||||
|
drmFree(ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ModeSetting functions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
drmModeResPtr drmModeGetResources(int fd)
|
||||||
|
{
|
||||||
|
struct drm_mode_card_res res;
|
||||||
|
drmModeResPtr r = 0;
|
||||||
|
|
||||||
|
memset(&res, 0, sizeof(struct drm_mode_card_res));
|
||||||
|
|
||||||
|
if (drmIoctl(fd, DRM_IOCTL_MODE_GETRESOURCES, &res))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (res.count_fbs)
|
||||||
|
res.fb_id_ptr = VOID2U64(drmMalloc(res.count_fbs*sizeof(uint32_t)));
|
||||||
|
if (res.count_crtcs)
|
||||||
|
res.crtc_id_ptr = VOID2U64(drmMalloc(res.count_crtcs*sizeof(uint32_t)));
|
||||||
|
if (res.count_connectors)
|
||||||
|
res.connector_id_ptr = VOID2U64(drmMalloc(res.count_connectors*sizeof(uint32_t)));
|
||||||
|
if (res.count_encoders)
|
||||||
|
res.encoder_id_ptr = VOID2U64(drmMalloc(res.count_encoders*sizeof(uint32_t)));
|
||||||
|
|
||||||
|
if (drmIoctl(fd, DRM_IOCTL_MODE_GETRESOURCES, &res)) {
|
||||||
|
r = NULL;
|
||||||
|
goto err_allocs;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* return
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
if (!(r = drmMalloc(sizeof(*r))))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
r->min_width = res.min_width;
|
||||||
|
r->max_width = res.max_width;
|
||||||
|
r->min_height = res.min_height;
|
||||||
|
r->max_height = res.max_height;
|
||||||
|
r->count_fbs = res.count_fbs;
|
||||||
|
r->count_crtcs = res.count_crtcs;
|
||||||
|
r->count_connectors = res.count_connectors;
|
||||||
|
r->count_encoders = res.count_encoders;
|
||||||
|
/* TODO we realy should test if these allocs fails. */
|
||||||
|
r->fbs = drmAllocCpy(U642VOID(res.fb_id_ptr), res.count_fbs, sizeof(uint32_t));
|
||||||
|
r->crtcs = drmAllocCpy(U642VOID(res.crtc_id_ptr), res.count_crtcs, sizeof(uint32_t));
|
||||||
|
r->connectors = drmAllocCpy(U642VOID(res.connector_id_ptr), res.count_connectors, sizeof(uint32_t));
|
||||||
|
r->encoders = drmAllocCpy(U642VOID(res.encoder_id_ptr), res.count_encoders, sizeof(uint32_t));
|
||||||
|
|
||||||
|
err_allocs:
|
||||||
|
drmFree(U642VOID(res.fb_id_ptr));
|
||||||
|
drmFree(U642VOID(res.crtc_id_ptr));
|
||||||
|
drmFree(U642VOID(res.connector_id_ptr));
|
||||||
|
drmFree(U642VOID(res.encoder_id_ptr));
|
||||||
|
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
int drmModeAddFB(int fd, uint32_t width, uint32_t height, uint8_t depth,
|
||||||
|
uint8_t bpp, uint32_t pitch, uint32_t bo_handle,
|
||||||
|
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 = drmIoctl(fd, DRM_IOCTL_MODE_ADDFB, &f)))
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
*buf_id = f.fb_id;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int drmModeRmFB(int fd, uint32_t bufferId)
|
||||||
|
{
|
||||||
|
return drmIoctl(fd, DRM_IOCTL_MODE_RMFB, &bufferId);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
drmModeFBPtr drmModeGetFB(int fd, uint32_t buf)
|
||||||
|
{
|
||||||
|
struct drm_mode_fb_cmd info;
|
||||||
|
drmModeFBPtr r;
|
||||||
|
|
||||||
|
info.fb_id = buf;
|
||||||
|
|
||||||
|
if (drmIoctl(fd, DRM_IOCTL_MODE_GETFB, &info))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (!(r = drmMalloc(sizeof(*r))))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
r->fb_id = info.fb_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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Crtc functions
|
||||||
|
*/
|
||||||
|
|
||||||
|
drmModeCrtcPtr drmModeGetCrtc(int fd, uint32_t crtcId)
|
||||||
|
{
|
||||||
|
struct drm_mode_crtc crtc;
|
||||||
|
drmModeCrtcPtr r;
|
||||||
|
|
||||||
|
crtc.crtc_id = crtcId;
|
||||||
|
|
||||||
|
if (drmIoctl(fd, DRM_IOCTL_MODE_GETCRTC, &crtc))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* return
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (!(r = drmMalloc(sizeof(*r))))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
r->crtc_id = crtc.crtc_id;
|
||||||
|
r->x = crtc.x;
|
||||||
|
r->y = crtc.y;
|
||||||
|
r->mode_valid = crtc.mode_valid;
|
||||||
|
if (r->mode_valid)
|
||||||
|
memcpy(&r->mode, &crtc.mode, sizeof(struct drm_mode_modeinfo));
|
||||||
|
r->buffer_id = crtc.fb_id;
|
||||||
|
r->gamma_size = crtc.gamma_size;
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int drmModeSetCrtc(int fd, uint32_t crtcId, uint32_t bufferId,
|
||||||
|
uint32_t x, uint32_t y, uint32_t *connectors, int count,
|
||||||
|
struct drm_mode_modeinfo *mode)
|
||||||
|
{
|
||||||
|
struct drm_mode_crtc crtc;
|
||||||
|
|
||||||
|
crtc.x = x;
|
||||||
|
crtc.y = y;
|
||||||
|
crtc.crtc_id = crtcId;
|
||||||
|
crtc.fb_id = bufferId;
|
||||||
|
crtc.set_connectors_ptr = VOID2U64(connectors);
|
||||||
|
crtc.count_connectors = count;
|
||||||
|
if (mode) {
|
||||||
|
memcpy(&crtc.mode, mode, sizeof(struct drm_mode_modeinfo));
|
||||||
|
crtc.mode_valid = 1;
|
||||||
|
} else
|
||||||
|
crtc.mode_valid = 0;
|
||||||
|
|
||||||
|
return drmIoctl(fd, DRM_IOCTL_MODE_SETCRTC, &crtc);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Cursor manipulation
|
||||||
|
*/
|
||||||
|
|
||||||
|
int drmModeSetCursor(int fd, uint32_t crtcId, uint32_t bo_handle, uint32_t width, uint32_t height)
|
||||||
|
{
|
||||||
|
struct drm_mode_cursor arg;
|
||||||
|
|
||||||
|
arg.flags = DRM_MODE_CURSOR_BO;
|
||||||
|
arg.crtc_id = crtcId;
|
||||||
|
arg.width = width;
|
||||||
|
arg.height = height;
|
||||||
|
arg.handle = bo_handle;
|
||||||
|
|
||||||
|
return drmIoctl(fd, DRM_IOCTL_MODE_CURSOR, &arg);
|
||||||
|
}
|
||||||
|
|
||||||
|
int drmModeMoveCursor(int fd, uint32_t crtcId, int x, int y)
|
||||||
|
{
|
||||||
|
struct drm_mode_cursor arg;
|
||||||
|
|
||||||
|
arg.flags = DRM_MODE_CURSOR_MOVE;
|
||||||
|
arg.crtc_id = crtcId;
|
||||||
|
arg.x = x;
|
||||||
|
arg.y = y;
|
||||||
|
|
||||||
|
return drmIoctl(fd, DRM_IOCTL_MODE_CURSOR, &arg);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Encoder get
|
||||||
|
*/
|
||||||
|
drmModeEncoderPtr drmModeGetEncoder(int fd, uint32_t encoder_id)
|
||||||
|
{
|
||||||
|
struct drm_mode_get_encoder enc;
|
||||||
|
drmModeEncoderPtr r = NULL;
|
||||||
|
|
||||||
|
enc.encoder_id = encoder_id;
|
||||||
|
enc.encoder_type = 0;
|
||||||
|
enc.possible_crtcs = 0;
|
||||||
|
enc.possible_clones = 0;
|
||||||
|
|
||||||
|
if (drmIoctl(fd, DRM_IOCTL_MODE_GETENCODER, &enc))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (!(r = drmMalloc(sizeof(*r))))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
r->encoder_id = enc.encoder_id;
|
||||||
|
r->crtc_id = enc.crtc_id;
|
||||||
|
r->encoder_type = enc.encoder_type;
|
||||||
|
r->possible_crtcs = enc.possible_crtcs;
|
||||||
|
r->possible_clones = enc.possible_clones;
|
||||||
|
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Connector manipulation
|
||||||
|
*/
|
||||||
|
|
||||||
|
drmModeConnectorPtr drmModeGetConnector(int fd, uint32_t connector_id)
|
||||||
|
{
|
||||||
|
struct drm_mode_get_connector conn;
|
||||||
|
drmModeConnectorPtr r = NULL;
|
||||||
|
|
||||||
|
conn.connector_id = connector_id;
|
||||||
|
conn.connector_type_id = 0;
|
||||||
|
conn.connector_type = 0;
|
||||||
|
conn.count_modes = 0;
|
||||||
|
conn.modes_ptr = 0;
|
||||||
|
conn.count_props = 0;
|
||||||
|
conn.props_ptr = 0;
|
||||||
|
conn.prop_values_ptr = 0;
|
||||||
|
conn.count_encoders = 0;
|
||||||
|
conn.encoders_ptr = 0;
|
||||||
|
|
||||||
|
if (drmIoctl(fd, DRM_IOCTL_MODE_GETCONNECTOR, &conn))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (conn.count_props) {
|
||||||
|
conn.props_ptr = VOID2U64(drmMalloc(conn.count_props*sizeof(uint32_t)));
|
||||||
|
conn.prop_values_ptr = VOID2U64(drmMalloc(conn.count_props*sizeof(uint64_t)));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (conn.count_modes)
|
||||||
|
conn.modes_ptr = VOID2U64(drmMalloc(conn.count_modes*sizeof(struct drm_mode_modeinfo)));
|
||||||
|
|
||||||
|
if (conn.count_encoders)
|
||||||
|
conn.encoders_ptr = VOID2U64(drmMalloc(conn.count_encoders*sizeof(uint32_t)));
|
||||||
|
|
||||||
|
if (drmIoctl(fd, DRM_IOCTL_MODE_GETCONNECTOR, &conn))
|
||||||
|
goto err_allocs;
|
||||||
|
|
||||||
|
if(!(r = drmMalloc(sizeof(*r)))) {
|
||||||
|
goto err_allocs;
|
||||||
|
}
|
||||||
|
|
||||||
|
r->connector_id = conn.connector_id;
|
||||||
|
r->encoder_id = conn.encoder_id;
|
||||||
|
r->connection = conn.connection;
|
||||||
|
r->mmWidth = conn.mm_width;
|
||||||
|
r->mmHeight = conn.mm_height;
|
||||||
|
r->subpixel = conn.subpixel;
|
||||||
|
r->count_modes = conn.count_modes;
|
||||||
|
/* TODO we should test if these alloc & cpy fails. */
|
||||||
|
r->count_props = conn.count_props;
|
||||||
|
r->props = drmAllocCpy(U642VOID(conn.props_ptr), conn.count_props, sizeof(uint32_t));
|
||||||
|
r->prop_values = drmAllocCpy(U642VOID(conn.prop_values_ptr), conn.count_props, sizeof(uint64_t));
|
||||||
|
r->modes = drmAllocCpy(U642VOID(conn.modes_ptr), conn.count_modes, sizeof(struct drm_mode_modeinfo));
|
||||||
|
r->count_encoders = conn.count_encoders;
|
||||||
|
r->encoders = drmAllocCpy(U642VOID(conn.encoders_ptr), conn.count_encoders, sizeof(uint32_t));
|
||||||
|
r->connector_type = conn.connector_type;
|
||||||
|
r->connector_type_id = conn.connector_type_id;
|
||||||
|
|
||||||
|
if (!r->props || !r->prop_values || !r->modes || !r->encoders)
|
||||||
|
goto err_allocs;
|
||||||
|
|
||||||
|
err_allocs:
|
||||||
|
drmFree(U642VOID(conn.prop_values_ptr));
|
||||||
|
drmFree(U642VOID(conn.props_ptr));
|
||||||
|
drmFree(U642VOID(conn.modes_ptr));
|
||||||
|
drmFree(U642VOID(conn.encoders_ptr));
|
||||||
|
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
int drmModeAttachMode(int fd, uint32_t connector_id, struct drm_mode_modeinfo *mode_info)
|
||||||
|
{
|
||||||
|
struct drm_mode_mode_cmd res;
|
||||||
|
|
||||||
|
memcpy(&res.mode, mode_info, sizeof(struct drm_mode_modeinfo));
|
||||||
|
res.connector_id = connector_id;
|
||||||
|
|
||||||
|
return drmIoctl(fd, DRM_IOCTL_MODE_ATTACHMODE, &res);
|
||||||
|
}
|
||||||
|
|
||||||
|
int drmModeDetachMode(int fd, uint32_t connector_id, struct drm_mode_modeinfo *mode_info)
|
||||||
|
{
|
||||||
|
struct drm_mode_mode_cmd res;
|
||||||
|
|
||||||
|
memcpy(&res.mode, mode_info, sizeof(struct drm_mode_modeinfo));
|
||||||
|
res.connector_id = connector_id;
|
||||||
|
|
||||||
|
return drmIoctl(fd, DRM_IOCTL_MODE_DETACHMODE, &res);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
drmModePropertyPtr drmModeGetProperty(int fd, uint32_t property_id)
|
||||||
|
{
|
||||||
|
struct drm_mode_get_property prop;
|
||||||
|
drmModePropertyPtr r;
|
||||||
|
|
||||||
|
prop.prop_id = property_id;
|
||||||
|
prop.count_enum_blobs = 0;
|
||||||
|
prop.count_values = 0;
|
||||||
|
prop.flags = 0;
|
||||||
|
prop.enum_blob_ptr = 0;
|
||||||
|
prop.values_ptr = 0;
|
||||||
|
|
||||||
|
if (drmIoctl(fd, DRM_IOCTL_MODE_GETPROPERTY, &prop))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (prop.count_values)
|
||||||
|
prop.values_ptr = VOID2U64(drmMalloc(prop.count_values * sizeof(uint64_t)));
|
||||||
|
|
||||||
|
if (prop.count_enum_blobs && (prop.flags & DRM_MODE_PROP_ENUM))
|
||||||
|
prop.enum_blob_ptr = VOID2U64(drmMalloc(prop.count_enum_blobs * sizeof(struct drm_mode_property_enum)));
|
||||||
|
|
||||||
|
if (prop.count_enum_blobs && (prop.flags & DRM_MODE_PROP_BLOB)) {
|
||||||
|
prop.values_ptr = VOID2U64(drmMalloc(prop.count_enum_blobs * sizeof(uint32_t)));
|
||||||
|
prop.enum_blob_ptr = VOID2U64(drmMalloc(prop.count_enum_blobs * sizeof(uint32_t)));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (drmIoctl(fd, DRM_IOCTL_MODE_GETPROPERTY, &prop)) {
|
||||||
|
r = NULL;
|
||||||
|
goto err_allocs;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(r = drmMalloc(sizeof(*r))))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
r->prop_id = prop.prop_id;
|
||||||
|
r->count_values = prop.count_values;
|
||||||
|
|
||||||
|
r->flags = prop.flags;
|
||||||
|
if (prop.count_values)
|
||||||
|
r->values = drmAllocCpy(U642VOID(prop.values_ptr), prop.count_values, sizeof(uint64_t));
|
||||||
|
if (prop.flags & DRM_MODE_PROP_ENUM) {
|
||||||
|
r->count_enums = prop.count_enum_blobs;
|
||||||
|
r->enums = drmAllocCpy(U642VOID(prop.enum_blob_ptr), prop.count_enum_blobs, sizeof(struct drm_mode_property_enum));
|
||||||
|
} else if (prop.flags & DRM_MODE_PROP_BLOB) {
|
||||||
|
r->values = drmAllocCpy(U642VOID(prop.values_ptr), prop.count_enum_blobs, sizeof(uint32_t));
|
||||||
|
r->blob_ids = drmAllocCpy(U642VOID(prop.enum_blob_ptr), prop.count_enum_blobs, sizeof(uint32_t));
|
||||||
|
r->count_blobs = prop.count_enum_blobs;
|
||||||
|
}
|
||||||
|
strncpy(r->name, prop.name, DRM_PROP_NAME_LEN);
|
||||||
|
r->name[DRM_PROP_NAME_LEN-1] = 0;
|
||||||
|
|
||||||
|
err_allocs:
|
||||||
|
drmFree(U642VOID(prop.values_ptr));
|
||||||
|
drmFree(U642VOID(prop.enum_blob_ptr));
|
||||||
|
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
void drmModeFreeProperty(drmModePropertyPtr ptr)
|
||||||
|
{
|
||||||
|
if (!ptr)
|
||||||
|
return;
|
||||||
|
|
||||||
|
drmFree(ptr->values);
|
||||||
|
drmFree(ptr->enums);
|
||||||
|
drmFree(ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
drmModePropertyBlobPtr drmModeGetPropertyBlob(int fd, uint32_t blob_id)
|
||||||
|
{
|
||||||
|
struct drm_mode_get_blob blob;
|
||||||
|
drmModePropertyBlobPtr r;
|
||||||
|
|
||||||
|
blob.length = 0;
|
||||||
|
blob.data = 0;
|
||||||
|
blob.blob_id = blob_id;
|
||||||
|
|
||||||
|
if (drmIoctl(fd, DRM_IOCTL_MODE_GETPROPBLOB, &blob))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (blob.length)
|
||||||
|
blob.data = VOID2U64(drmMalloc(blob.length));
|
||||||
|
|
||||||
|
if (drmIoctl(fd, DRM_IOCTL_MODE_GETPROPBLOB, &blob)) {
|
||||||
|
r = NULL;
|
||||||
|
goto err_allocs;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(r = drmMalloc(sizeof(*r))))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
r->id = blob.blob_id;
|
||||||
|
r->length = blob.length;
|
||||||
|
r->data = drmAllocCpy(U642VOID(blob.data), 1, blob.length);
|
||||||
|
|
||||||
|
err_allocs:
|
||||||
|
drmFree(U642VOID(blob.data));
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
void drmModeFreePropertyBlob(drmModePropertyBlobPtr ptr)
|
||||||
|
{
|
||||||
|
if (!ptr)
|
||||||
|
return;
|
||||||
|
|
||||||
|
drmFree(ptr->data);
|
||||||
|
drmFree(ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
int drmModeConnectorSetProperty(int fd, uint32_t connector_id, uint32_t property_id,
|
||||||
|
uint64_t value)
|
||||||
|
{
|
||||||
|
struct drm_mode_connector_set_property osp;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
osp.connector_id = connector_id;
|
||||||
|
osp.prop_id = property_id;
|
||||||
|
osp.value = value;
|
||||||
|
|
||||||
|
if ((ret = drmIoctl(fd, DRM_IOCTL_MODE_SETPROPERTY, &osp)))
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* checks if a modesetting capable driver has attached to the pci id
|
||||||
|
* returns 0 if modesetting supported.
|
||||||
|
* -EINVAL or invalid bus id
|
||||||
|
* -ENOSYS if no modesetting support
|
||||||
|
*/
|
||||||
|
int drmCheckModesettingSupported(const char *busid)
|
||||||
|
{
|
||||||
|
#ifdef __linux__
|
||||||
|
char pci_dev_dir[1024];
|
||||||
|
int domain, bus, dev, func;
|
||||||
|
DIR *sysdir;
|
||||||
|
struct dirent *dent;
|
||||||
|
int found = 0, ret;
|
||||||
|
|
||||||
|
ret = sscanf(busid, "pci:%04x:%02x:%02x.%d", &domain, &bus, &dev, &func);
|
||||||
|
if (ret != 4)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
sprintf(pci_dev_dir, "/sys/bus/pci/devices/%04x:%02x:%02x.%d/drm",
|
||||||
|
domain, bus, dev, func);
|
||||||
|
|
||||||
|
sysdir = opendir(pci_dev_dir);
|
||||||
|
if (sysdir) {
|
||||||
|
dent = readdir(sysdir);
|
||||||
|
while (dent) {
|
||||||
|
if (!strncmp(dent->d_name, "controlD", 8)) {
|
||||||
|
found = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
dent = readdir(sysdir);
|
||||||
|
}
|
||||||
|
closedir(sysdir);
|
||||||
|
if (found)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
sprintf(pci_dev_dir, "/sys/bus/pci/devices/%04x:%02x:%02x.%d/",
|
||||||
|
domain, bus, dev, func);
|
||||||
|
|
||||||
|
sysdir = opendir(pci_dev_dir);
|
||||||
|
if (!sysdir)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
dent = readdir(sysdir);
|
||||||
|
while (dent) {
|
||||||
|
if (!strncmp(dent->d_name, "drm:controlD", 12)) {
|
||||||
|
found = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
dent = readdir(sysdir);
|
||||||
|
}
|
||||||
|
|
||||||
|
closedir(sysdir);
|
||||||
|
if (found)
|
||||||
|
return 0;
|
||||||
|
#endif
|
||||||
|
return -ENOSYS;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
int drmModeReplaceFB(int fd, uint32_t buffer_id,
|
||||||
|
uint32_t width, uint32_t height, uint8_t depth,
|
||||||
|
uint8_t bpp, uint32_t pitch, uint32_t bo_handle)
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
f.fb_id = buffer_id;
|
||||||
|
|
||||||
|
if ((ret = drmIoctl(fd, DRM_IOCTL_MODE_REPLACEFB, &f)))
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int drmModeCrtcGetGamma(int fd, uint32_t crtc_id, uint32_t size,
|
||||||
|
uint16_t *red, uint16_t *green, uint16_t *blue)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
struct drm_mode_crtc_lut l;
|
||||||
|
|
||||||
|
l.crtc_id = crtc_id;
|
||||||
|
l.gamma_size = size;
|
||||||
|
l.red = VOID2U64(red);
|
||||||
|
l.green = VOID2U64(green);
|
||||||
|
l.blue = VOID2U64(blue);
|
||||||
|
|
||||||
|
if ((ret = drmIoctl(fd, DRM_IOCTL_MODE_GETGAMMA, &l)))
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int drmModeCrtcSetGamma(int fd, uint32_t crtc_id, uint32_t size,
|
||||||
|
uint16_t *red, uint16_t *green, uint16_t *blue)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
struct drm_mode_crtc_lut l;
|
||||||
|
|
||||||
|
l.crtc_id = crtc_id;
|
||||||
|
l.gamma_size = size;
|
||||||
|
l.red = VOID2U64(red);
|
||||||
|
l.green = VOID2U64(green);
|
||||||
|
l.blue = VOID2U64(blue);
|
||||||
|
|
||||||
|
if ((ret = drmIoctl(fd, DRM_IOCTL_MODE_SETGAMMA, &l)))
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -0,0 +1,258 @@
|
||||||
|
/*
|
||||||
|
* \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) 2007-2008 Tungsten Graphics, Inc., Cedar Park, Texas.
|
||||||
|
* Copyright (c) 2007-2008 Dave Airlie <airlied@linux.ie>
|
||||||
|
* Copyright (c) 2007-2008 Jakob Bornecrantz <wallbraker@gmail.com>
|
||||||
|
*
|
||||||
|
* 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>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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 randr1.2 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
|
||||||
|
*
|
||||||
|
* There are some major diffrences to be noted. Unlike the randr1.2 proto you
|
||||||
|
* need to create the memory object of the framebuffer yourself with the ttm
|
||||||
|
* buffer object interface. This object needs to be pinned.
|
||||||
|
*/
|
||||||
|
|
||||||
|
typedef struct _drmModeRes {
|
||||||
|
|
||||||
|
int count_fbs;
|
||||||
|
uint32_t *fbs;
|
||||||
|
|
||||||
|
int count_crtcs;
|
||||||
|
uint32_t *crtcs;
|
||||||
|
|
||||||
|
int count_connectors;
|
||||||
|
uint32_t *connectors;
|
||||||
|
|
||||||
|
int count_encoders;
|
||||||
|
uint32_t *encoders;
|
||||||
|
|
||||||
|
uint32_t min_width, max_width;
|
||||||
|
uint32_t min_height, max_height;
|
||||||
|
} drmModeRes, *drmModeResPtr;
|
||||||
|
|
||||||
|
typedef struct drm_mode_fb_cmd drmModeFB, *drmModeFBPtr;
|
||||||
|
|
||||||
|
typedef struct _drmModePropertyBlob {
|
||||||
|
uint32_t id;
|
||||||
|
uint32_t length;
|
||||||
|
void *data;
|
||||||
|
} drmModePropertyBlobRes, *drmModePropertyBlobPtr;
|
||||||
|
|
||||||
|
typedef struct _drmModeProperty {
|
||||||
|
uint32_t prop_id;
|
||||||
|
uint32_t flags;
|
||||||
|
char name[DRM_PROP_NAME_LEN];
|
||||||
|
int count_values;
|
||||||
|
uint64_t *values; // store the blob lengths
|
||||||
|
int count_enums;
|
||||||
|
struct drm_mode_property_enum *enums;
|
||||||
|
int count_blobs;
|
||||||
|
uint32_t *blob_ids; // store the blob IDs
|
||||||
|
} drmModePropertyRes, *drmModePropertyPtr;
|
||||||
|
|
||||||
|
typedef struct _drmModeCrtc {
|
||||||
|
uint32_t crtc_id;
|
||||||
|
uint32_t buffer_id; /**< FB id to connect to 0 = disconnect */
|
||||||
|
|
||||||
|
uint32_t x, y; /**< Position on the framebuffer */
|
||||||
|
uint32_t width, height;
|
||||||
|
int mode_valid;
|
||||||
|
struct drm_mode_modeinfo mode;
|
||||||
|
|
||||||
|
int gamma_size; /**< Number of gamma stops */
|
||||||
|
|
||||||
|
} drmModeCrtc, *drmModeCrtcPtr;
|
||||||
|
|
||||||
|
typedef struct _drmModeEncoder {
|
||||||
|
uint32_t encoder_id;
|
||||||
|
uint32_t encoder_type;
|
||||||
|
uint32_t crtc_id;
|
||||||
|
uint32_t possible_crtcs;
|
||||||
|
uint32_t possible_clones;
|
||||||
|
} drmModeEncoder, *drmModeEncoderPtr;
|
||||||
|
|
||||||
|
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 _drmModeConnector {
|
||||||
|
uint32_t connector_id;
|
||||||
|
uint32_t encoder_id; /**< Encoder currently connected to */
|
||||||
|
uint32_t connector_type;
|
||||||
|
uint32_t connector_type_id;
|
||||||
|
drmModeConnection connection;
|
||||||
|
uint32_t mmWidth, mmHeight; /**< HxW in millimeters */
|
||||||
|
drmModeSubPixel subpixel;
|
||||||
|
|
||||||
|
int count_modes;
|
||||||
|
struct drm_mode_modeinfo *modes;
|
||||||
|
|
||||||
|
int count_props;
|
||||||
|
uint32_t *props; /**< List of property ids */
|
||||||
|
uint64_t *prop_values; /**< List of property values */
|
||||||
|
|
||||||
|
int count_encoders;
|
||||||
|
uint32_t *encoders; /**< List of encoder ids */
|
||||||
|
} drmModeConnector, *drmModeConnectorPtr;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
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 drmModeFreeConnector( drmModeConnectorPtr ptr );
|
||||||
|
extern void drmModeFreeEncoder( drmModeEncoderPtr ptr );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrives all of the resources associated with a card.
|
||||||
|
*/
|
||||||
|
extern drmModeResPtr drmModeGetResources(int fd);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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, uint32_t bo_handle,
|
||||||
|
uint32_t *buf_id);
|
||||||
|
/**
|
||||||
|
* Destroies the given framebuffer.
|
||||||
|
*/
|
||||||
|
extern int drmModeRmFB(int fd, uint32_t bufferId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Replace a framebuffer object with a new one - for resizing the screen.
|
||||||
|
*/
|
||||||
|
extern int drmModeReplaceFB(int fd, uint32_t buffer_id,
|
||||||
|
uint32_t width, uint32_t height, uint8_t depth,
|
||||||
|
uint8_t bpp, uint32_t pitch, uint32_t bo_handle);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Crtc functions
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
int drmModeSetCrtc(int fd, uint32_t crtcId, uint32_t bufferId,
|
||||||
|
uint32_t x, uint32_t y, uint32_t *connectors, int count,
|
||||||
|
struct drm_mode_modeinfo *mode);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Cursor functions
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the cursor on crtc
|
||||||
|
*/
|
||||||
|
int drmModeSetCursor(int fd, uint32_t crtcId, uint32_t bo_handle, uint32_t width, uint32_t height);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Move the cursor on crtc
|
||||||
|
*/
|
||||||
|
int drmModeMoveCursor(int fd, uint32_t crtcId, int x, int y);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Encoder functions
|
||||||
|
*/
|
||||||
|
drmModeEncoderPtr drmModeGetEncoder(int fd, uint32_t encoder_id);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Connector manipulation
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrive information about the connector connectorId.
|
||||||
|
*/
|
||||||
|
extern drmModeConnectorPtr drmModeGetConnector(int fd,
|
||||||
|
uint32_t connectorId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Attaches the given mode to an connector.
|
||||||
|
*/
|
||||||
|
extern int drmModeAttachMode(int fd, uint32_t connectorId, struct drm_mode_modeinfo *mode_info);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Detaches a mode from the connector
|
||||||
|
* must be unused, by the given mode.
|
||||||
|
*/
|
||||||
|
extern int drmModeDetachMode(int fd, uint32_t connectorId, struct drm_mode_modeinfo *mode_info);
|
||||||
|
|
||||||
|
extern drmModePropertyPtr drmModeGetProperty(int fd, uint32_t propertyId);
|
||||||
|
extern void drmModeFreeProperty(drmModePropertyPtr ptr);
|
||||||
|
|
||||||
|
extern drmModePropertyBlobPtr drmModeGetPropertyBlob(int fd, uint32_t blob_id);
|
||||||
|
extern void drmModeFreePropertyBlob(drmModePropertyBlobPtr ptr);
|
||||||
|
extern int drmModeConnectorSetProperty(int fd, uint32_t connector_id, uint32_t property_id,
|
||||||
|
uint64_t value);
|
||||||
|
extern int drmCheckModesettingSupported(const char *busid);
|
||||||
|
|
||||||
|
extern int drmModeCrtcSetGamma(int fd, uint32_t crtc_id, uint32_t size,
|
||||||
|
uint16_t *red, uint16_t *green, uint16_t *blue);
|
||||||
|
extern int drmModeCrtcGetGamma(int fd, uint32_t crtc_id, uint32_t size,
|
||||||
|
uint16_t *red, uint16_t *green, uint16_t *blue);
|
|
@ -0,0 +1 @@
|
||||||
|
../shared-core/drm_mode.h
|
|
@ -25,6 +25,7 @@
|
||||||
klibdrmincludedir = ${includedir}/drm
|
klibdrmincludedir = ${includedir}/drm
|
||||||
klibdrminclude_HEADERS = \
|
klibdrminclude_HEADERS = \
|
||||||
drm.h \
|
drm.h \
|
||||||
|
drm_mode.h \
|
||||||
drm_sarea.h \
|
drm_sarea.h \
|
||||||
i915_drm.h \
|
i915_drm.h \
|
||||||
mach64_drm.h \
|
mach64_drm.h \
|
||||||
|
|
|
@ -985,6 +985,8 @@ struct drm_gem_open {
|
||||||
uint64_t size;
|
uint64_t size;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#include "drm_mode.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \name Ioctls Definitions
|
* \name Ioctls Definitions
|
||||||
*/
|
*/
|
||||||
|
@ -1027,6 +1029,9 @@ struct drm_gem_open {
|
||||||
#define DRM_IOCTL_SET_SAREA_CTX DRM_IOW( 0x1c, struct drm_ctx_priv_map)
|
#define DRM_IOCTL_SET_SAREA_CTX DRM_IOW( 0x1c, struct drm_ctx_priv_map)
|
||||||
#define DRM_IOCTL_GET_SAREA_CTX DRM_IOWR(0x1d, struct drm_ctx_priv_map)
|
#define DRM_IOCTL_GET_SAREA_CTX DRM_IOWR(0x1d, struct drm_ctx_priv_map)
|
||||||
|
|
||||||
|
#define DRM_IOCTL_SET_MASTER DRM_IO(0x1e)
|
||||||
|
#define DRM_IOCTL_DROP_MASTER DRM_IO(0x1f)
|
||||||
|
|
||||||
#define DRM_IOCTL_ADD_CTX DRM_IOWR(0x20, struct drm_ctx)
|
#define DRM_IOCTL_ADD_CTX DRM_IOWR(0x20, struct drm_ctx)
|
||||||
#define DRM_IOCTL_RM_CTX DRM_IOWR(0x21, struct drm_ctx)
|
#define DRM_IOCTL_RM_CTX DRM_IOWR(0x21, struct drm_ctx)
|
||||||
#define DRM_IOCTL_MOD_CTX DRM_IOW( 0x22, struct drm_ctx)
|
#define DRM_IOCTL_MOD_CTX DRM_IOW( 0x22, struct drm_ctx)
|
||||||
|
@ -1082,6 +1087,28 @@ struct drm_gem_open {
|
||||||
#define DRM_IOCTL_BO_VERSION DRM_IOR(0xd6, struct drm_bo_version_arg)
|
#define DRM_IOCTL_BO_VERSION DRM_IOR(0xd6, struct drm_bo_version_arg)
|
||||||
#define DRM_IOCTL_MM_INFO DRM_IOWR(0xd7, struct drm_mm_info_arg)
|
#define DRM_IOCTL_MM_INFO DRM_IOWR(0xd7, struct drm_mm_info_arg)
|
||||||
|
|
||||||
|
#define DRM_IOCTL_MODE_GETRESOURCES DRM_IOWR(0xA0, struct drm_mode_card_res)
|
||||||
|
|
||||||
|
#define DRM_IOCTL_MODE_GETCRTC DRM_IOWR(0xA1, struct drm_mode_crtc)
|
||||||
|
#define DRM_IOCTL_MODE_SETCRTC DRM_IOWR(0xA2, struct drm_mode_crtc)
|
||||||
|
#define DRM_IOCTL_MODE_CURSOR DRM_IOWR(0xA3, struct drm_mode_cursor)
|
||||||
|
#define DRM_IOCTL_MODE_GETGAMMA DRM_IOWR(0xA4, struct drm_mode_crtc_lut)
|
||||||
|
#define DRM_IOCTL_MODE_SETGAMMA DRM_IOWR(0xA5, struct drm_mode_crtc_lut)
|
||||||
|
|
||||||
|
#define DRM_IOCTL_MODE_GETENCODER DRM_IOWR(0xA6, struct drm_mode_get_encoder)
|
||||||
|
|
||||||
|
#define DRM_IOCTL_MODE_GETCONNECTOR DRM_IOWR(0xA7, struct drm_mode_get_connector)
|
||||||
|
#define DRM_IOCTL_MODE_ATTACHMODE DRM_IOWR(0xA8, struct drm_mode_mode_cmd)
|
||||||
|
#define DRM_IOCTL_MODE_DETACHMODE DRM_IOWR(0xA9, struct drm_mode_mode_cmd)
|
||||||
|
#define DRM_IOCTL_MODE_GETPROPERTY DRM_IOWR(0xAA, struct drm_mode_get_property)
|
||||||
|
#define DRM_IOCTL_MODE_SETPROPERTY DRM_IOWR(0xAB, struct drm_mode_connector_set_property)
|
||||||
|
#define DRM_IOCTL_MODE_GETPROPBLOB DRM_IOWR(0xAC, struct drm_mode_get_blob)
|
||||||
|
|
||||||
|
#define DRM_IOCTL_MODE_GETFB DRM_IOWR(0xAD, struct drm_mode_fb_cmd)
|
||||||
|
#define DRM_IOCTL_MODE_ADDFB DRM_IOWR(0xAE, struct drm_mode_fb_cmd)
|
||||||
|
#define DRM_IOCTL_MODE_RMFB DRM_IOWR(0xAF, uint32_t)
|
||||||
|
#define DRM_IOCTL_MODE_REPLACEFB DRM_IOWR(0xB0, struct drm_mode_fb_cmd)
|
||||||
|
|
||||||
/*@}*/
|
/*@}*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -0,0 +1,271 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2007 Dave Airlie <airlied@linux.ie>
|
||||||
|
* Copyright (c) 2007 Jakob Bornecrantz <wallbraker@gmail.com>
|
||||||
|
* Copyright (c) 2008 Red Hat Inc.
|
||||||
|
* Copyright (c) 2007-2008 Tungsten Graphics, Inc., Cedar Park, TX., USA
|
||||||
|
* Copyright (c) 2007-2008 Intel Corporation
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _DRM_MODE_H
|
||||||
|
#define _DRM_MODE_H
|
||||||
|
|
||||||
|
#if !defined(__KERNEL__) && !defined(_KERNEL)
|
||||||
|
#include <stdint.h>
|
||||||
|
#else
|
||||||
|
#include <linux/kernel.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define DRM_DISPLAY_INFO_LEN 32
|
||||||
|
#define DRM_CONNECTOR_NAME_LEN 32
|
||||||
|
#define DRM_DISPLAY_MODE_LEN 32
|
||||||
|
#define DRM_PROP_NAME_LEN 32
|
||||||
|
|
||||||
|
#define DRM_MODE_TYPE_BUILTIN (1<<0)
|
||||||
|
#define DRM_MODE_TYPE_CLOCK_C ((1<<1) | DRM_MODE_TYPE_BUILTIN)
|
||||||
|
#define DRM_MODE_TYPE_CRTC_C ((1<<2) | DRM_MODE_TYPE_BUILTIN)
|
||||||
|
#define DRM_MODE_TYPE_PREFERRED (1<<3)
|
||||||
|
#define DRM_MODE_TYPE_DEFAULT (1<<4)
|
||||||
|
#define DRM_MODE_TYPE_USERDEF (1<<5)
|
||||||
|
#define DRM_MODE_TYPE_DRIVER (1<<6)
|
||||||
|
|
||||||
|
/* Video mode flags */
|
||||||
|
/* bit compatible with the xorg definitions. */
|
||||||
|
#define DRM_MODE_FLAG_PHSYNC (1<<0)
|
||||||
|
#define DRM_MODE_FLAG_NHSYNC (1<<1)
|
||||||
|
#define DRM_MODE_FLAG_PVSYNC (1<<2)
|
||||||
|
#define DRM_MODE_FLAG_NVSYNC (1<<3)
|
||||||
|
#define DRM_MODE_FLAG_INTERLACE (1<<4)
|
||||||
|
#define DRM_MODE_FLAG_DBLSCAN (1<<5)
|
||||||
|
#define DRM_MODE_FLAG_CSYNC (1<<6)
|
||||||
|
#define DRM_MODE_FLAG_PCSYNC (1<<7)
|
||||||
|
#define DRM_MODE_FLAG_NCSYNC (1<<8)
|
||||||
|
#define DRM_MODE_FLAG_HSKEW (1<<9) /* hskew provided */
|
||||||
|
#define DRM_MODE_FLAG_BCAST (1<<10)
|
||||||
|
#define DRM_MODE_FLAG_PIXMUX (1<<11)
|
||||||
|
#define DRM_MODE_FLAG_DBLCLK (1<<12)
|
||||||
|
#define DRM_MODE_FLAG_CLKDIV2 (1<<13)
|
||||||
|
|
||||||
|
/* DPMS flags */
|
||||||
|
/* bit compatible with the xorg definitions. */
|
||||||
|
#define DRM_MODE_DPMS_ON 0
|
||||||
|
#define DRM_MODE_DPMS_STANDBY 1
|
||||||
|
#define DRM_MODE_DPMS_SUSPEND 2
|
||||||
|
#define DRM_MODE_DPMS_OFF 3
|
||||||
|
|
||||||
|
/* Scaling mode options */
|
||||||
|
#define DRM_MODE_SCALE_NON_GPU 0
|
||||||
|
#define DRM_MODE_SCALE_FULLSCREEN 1
|
||||||
|
#define DRM_MODE_SCALE_NO_SCALE 2
|
||||||
|
#define DRM_MODE_SCALE_ASPECT 3
|
||||||
|
|
||||||
|
/* Dithering mode options */
|
||||||
|
#define DRM_MODE_DITHERING_OFF 0
|
||||||
|
#define DRM_MODE_DITHERING_ON 1
|
||||||
|
|
||||||
|
struct drm_mode_modeinfo {
|
||||||
|
uint32_t clock;
|
||||||
|
uint16_t hdisplay, hsync_start, hsync_end, htotal, hskew;
|
||||||
|
uint16_t vdisplay, vsync_start, vsync_end, vtotal, vscan;
|
||||||
|
|
||||||
|
uint32_t vrefresh; /* vertical refresh * 1000 */
|
||||||
|
|
||||||
|
uint32_t flags;
|
||||||
|
uint32_t type;
|
||||||
|
char name[DRM_DISPLAY_MODE_LEN];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct drm_mode_card_res {
|
||||||
|
uint64_t fb_id_ptr;
|
||||||
|
uint64_t crtc_id_ptr;
|
||||||
|
uint64_t connector_id_ptr;
|
||||||
|
uint64_t encoder_id_ptr;
|
||||||
|
uint32_t count_fbs;
|
||||||
|
uint32_t count_crtcs;
|
||||||
|
uint32_t count_connectors;
|
||||||
|
uint32_t count_encoders;
|
||||||
|
uint32_t min_width, max_width;
|
||||||
|
uint32_t min_height, max_height;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct drm_mode_crtc {
|
||||||
|
uint64_t set_connectors_ptr;
|
||||||
|
uint32_t count_connectors;
|
||||||
|
|
||||||
|
uint32_t crtc_id; /**< Id */
|
||||||
|
uint32_t fb_id; /**< Id of framebuffer */
|
||||||
|
|
||||||
|
uint32_t x, y; /**< Position on the frameuffer */
|
||||||
|
|
||||||
|
uint32_t gamma_size;
|
||||||
|
uint32_t mode_valid;
|
||||||
|
struct drm_mode_modeinfo mode;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define DRM_MODE_ENCODER_NONE 0
|
||||||
|
#define DRM_MODE_ENCODER_DAC 1
|
||||||
|
#define DRM_MODE_ENCODER_TMDS 2
|
||||||
|
#define DRM_MODE_ENCODER_LVDS 3
|
||||||
|
#define DRM_MODE_ENCODER_TVDAC 4
|
||||||
|
|
||||||
|
struct drm_mode_get_encoder {
|
||||||
|
uint32_t encoder_id;
|
||||||
|
uint32_t encoder_type;
|
||||||
|
|
||||||
|
uint32_t crtc_id; /**< Id of crtc */
|
||||||
|
|
||||||
|
uint32_t possible_crtcs;
|
||||||
|
uint32_t possible_clones;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* This is for connectors with multiple signal types. */
|
||||||
|
/* Try to match DRM_MODE_CONNECTOR_X as closely as possible. */
|
||||||
|
#define DRM_MODE_SUBCONNECTOR_Automatic 0
|
||||||
|
#define DRM_MODE_SUBCONNECTOR_Unknown 0
|
||||||
|
#define DRM_MODE_SUBCONNECTOR_DVID 3
|
||||||
|
#define DRM_MODE_SUBCONNECTOR_DVIA 4
|
||||||
|
#define DRM_MODE_SUBCONNECTOR_Composite 5
|
||||||
|
#define DRM_MODE_SUBCONNECTOR_SVIDEO 6
|
||||||
|
#define DRM_MODE_SUBCONNECTOR_Component 8
|
||||||
|
|
||||||
|
#define DRM_MODE_CONNECTOR_Unknown 0
|
||||||
|
#define DRM_MODE_CONNECTOR_VGA 1
|
||||||
|
#define DRM_MODE_CONNECTOR_DVII 2
|
||||||
|
#define DRM_MODE_CONNECTOR_DVID 3
|
||||||
|
#define DRM_MODE_CONNECTOR_DVIA 4
|
||||||
|
#define DRM_MODE_CONNECTOR_Composite 5
|
||||||
|
#define DRM_MODE_CONNECTOR_SVIDEO 6
|
||||||
|
#define DRM_MODE_CONNECTOR_LVDS 7
|
||||||
|
#define DRM_MODE_CONNECTOR_Component 8
|
||||||
|
#define DRM_MODE_CONNECTOR_9PinDIN 9
|
||||||
|
#define DRM_MODE_CONNECTOR_DisplayPort 10
|
||||||
|
#define DRM_MODE_CONNECTOR_HDMIA 11
|
||||||
|
#define DRM_MODE_CONNECTOR_HDMIB 12
|
||||||
|
|
||||||
|
struct drm_mode_get_connector {
|
||||||
|
|
||||||
|
uint64_t encoders_ptr;
|
||||||
|
uint64_t modes_ptr;
|
||||||
|
uint64_t props_ptr;
|
||||||
|
uint64_t prop_values_ptr;
|
||||||
|
|
||||||
|
uint32_t count_modes;
|
||||||
|
uint32_t count_props;
|
||||||
|
uint32_t count_encoders;
|
||||||
|
|
||||||
|
uint32_t encoder_id; /**< Current Encoder */
|
||||||
|
uint32_t connector_id; /**< Id */
|
||||||
|
uint32_t connector_type;
|
||||||
|
uint32_t connector_type_id;
|
||||||
|
|
||||||
|
uint32_t connection;
|
||||||
|
uint32_t mm_width, mm_height; /**< HxW in millimeters */
|
||||||
|
uint32_t subpixel;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define DRM_MODE_PROP_PENDING (1<<0)
|
||||||
|
#define DRM_MODE_PROP_RANGE (1<<1)
|
||||||
|
#define DRM_MODE_PROP_IMMUTABLE (1<<2)
|
||||||
|
#define DRM_MODE_PROP_ENUM (1<<3) /* enumerated type with text strings */
|
||||||
|
#define DRM_MODE_PROP_BLOB (1<<4)
|
||||||
|
|
||||||
|
struct drm_mode_property_enum {
|
||||||
|
uint64_t value;
|
||||||
|
char name[DRM_PROP_NAME_LEN];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct drm_mode_get_property {
|
||||||
|
uint64_t values_ptr; /* values and blob lengths */
|
||||||
|
uint64_t enum_blob_ptr; /* enum and blob id ptrs */
|
||||||
|
|
||||||
|
uint32_t prop_id;
|
||||||
|
uint32_t flags;
|
||||||
|
char name[DRM_PROP_NAME_LEN];
|
||||||
|
|
||||||
|
uint32_t count_values;
|
||||||
|
uint32_t count_enum_blobs;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct drm_mode_connector_set_property {
|
||||||
|
uint64_t value;
|
||||||
|
uint32_t prop_id;
|
||||||
|
uint32_t connector_id;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct drm_mode_get_blob {
|
||||||
|
uint32_t blob_id;
|
||||||
|
uint32_t length;
|
||||||
|
uint64_t data;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct drm_mode_fb_cmd {
|
||||||
|
uint32_t fb_id;
|
||||||
|
uint32_t width, height;
|
||||||
|
uint32_t pitch;
|
||||||
|
uint32_t bpp;
|
||||||
|
uint32_t depth;
|
||||||
|
/* driver specific handle */
|
||||||
|
uint32_t handle;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct drm_mode_mode_cmd {
|
||||||
|
uint32_t connector_id;
|
||||||
|
struct drm_mode_modeinfo mode;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define DRM_MODE_CURSOR_BO (1<<0)
|
||||||
|
#define DRM_MODE_CURSOR_MOVE (1<<1)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* depending on the value in flags diffrent members are used.
|
||||||
|
*
|
||||||
|
* CURSOR_BO uses
|
||||||
|
* crtc
|
||||||
|
* width
|
||||||
|
* height
|
||||||
|
* handle - if 0 turns the cursor of
|
||||||
|
*
|
||||||
|
* CURSOR_MOVE uses
|
||||||
|
* crtc
|
||||||
|
* x
|
||||||
|
* y
|
||||||
|
*/
|
||||||
|
struct drm_mode_cursor {
|
||||||
|
uint32_t flags;
|
||||||
|
uint32_t crtc_id;
|
||||||
|
int32_t x;
|
||||||
|
int32_t y;
|
||||||
|
uint32_t width;
|
||||||
|
uint32_t height;
|
||||||
|
/* driver specific handle */
|
||||||
|
uint32_t handle;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct drm_mode_crtc_lut {
|
||||||
|
uint32_t crtc_id;
|
||||||
|
uint32_t gamma_size;
|
||||||
|
|
||||||
|
/* pointers to arrays */
|
||||||
|
uint64_t red;
|
||||||
|
uint64_t green;
|
||||||
|
uint64_t blue;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
|
@ -15,6 +15,10 @@ libdrmtest_la_LIBADD = \
|
||||||
|
|
||||||
LDADD = libdrmtest.la
|
LDADD = libdrmtest.la
|
||||||
|
|
||||||
|
noinst_SUBDIRS = \
|
||||||
|
modeprint \
|
||||||
|
modetest
|
||||||
|
|
||||||
TESTS = auth \
|
TESTS = auth \
|
||||||
openclose \
|
openclose \
|
||||||
getversion \
|
getversion \
|
||||||
|
|
|
@ -263,7 +263,7 @@ int main(int argc, char **argv)
|
||||||
|
|
||||||
for (i = 0; i < 16; i++) if (!minor || i == minor) {
|
for (i = 0; i < 16; i++) if (!minor || i == minor) {
|
||||||
sprintf(buf, DRM_DEV_NAME, DRM_DIR_NAME, i);
|
sprintf(buf, DRM_DEV_NAME, DRM_DIR_NAME, i);
|
||||||
fd = drmOpenMinor(i, 1);
|
fd = drmOpenMinor(i, 1, DRM_NODE_RENDER);
|
||||||
if (fd >= 0) {
|
if (fd >= 0) {
|
||||||
printf("%s\n", buf);
|
printf("%s\n", buf);
|
||||||
if (mask & DRM_BUSID) getbusid(fd);
|
if (mask & DRM_BUSID) getbusid(fd);
|
||||||
|
|
|
@ -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: modeprint.c
|
||||||
|
@gcc $(CFLAGS) -o app -Wall -I../../libdrm -I../../shared-core -L../../libdrm/.libs -ldrm modeprint.c
|
||||||
|
|
||||||
|
clean:
|
||||||
|
@rm -f app
|
||||||
|
|
||||||
|
run: app
|
||||||
|
@sudo ./test
|
Binary file not shown.
|
@ -0,0 +1,402 @@
|
||||||
|
/*
|
||||||
|
* \file modedemo.c
|
||||||
|
* Test program to dump DRM kernel mode setting related information.
|
||||||
|
* Queries the kernel for all available information and dumps it to stdout.
|
||||||
|
*
|
||||||
|
* \author Jakob Bornecrantz <wallbraker@gmail.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2007-2008 Tungsten Graphics, Inc., Cedar Park, Texas.
|
||||||
|
* Copyright (c) 2007-2008 Jakob Bornecrantz <wallbraker@gmail.com>
|
||||||
|
*
|
||||||
|
* 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 <assert.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "xf86drm.h"
|
||||||
|
#include "xf86drmMode.h"
|
||||||
|
|
||||||
|
int connectors;
|
||||||
|
int full_props;
|
||||||
|
int edid;
|
||||||
|
int modes;
|
||||||
|
int full_modes;
|
||||||
|
int encoders;
|
||||||
|
int crtcs;
|
||||||
|
int fbs;
|
||||||
|
char *module_name;
|
||||||
|
|
||||||
|
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 (full_modes) {
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int printProperty(int fd, drmModeResPtr res, drmModePropertyPtr props, uint64_t value)
|
||||||
|
{
|
||||||
|
const unsigned char *name = NULL;
|
||||||
|
int j;
|
||||||
|
|
||||||
|
printf("Property: %s\n", props->name);
|
||||||
|
printf("\tid : %i\n", props->prop_id);
|
||||||
|
printf("\tflags : %i\n", props->flags);
|
||||||
|
printf("\tcount_values : %d\n", props->count_values);
|
||||||
|
|
||||||
|
|
||||||
|
if (props->count_values) {
|
||||||
|
printf("\tvalues :");
|
||||||
|
for (j = 0; j < props->count_values; j++)
|
||||||
|
printf(" %lld", props->values[j]);
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
printf("\tcount_enums : %d\n", props->count_enums);
|
||||||
|
|
||||||
|
if (props->flags & DRM_MODE_PROP_BLOB) {
|
||||||
|
drmModePropertyBlobPtr blob;
|
||||||
|
|
||||||
|
blob = drmModeGetPropertyBlob(fd, value);
|
||||||
|
if (blob) {
|
||||||
|
printf("blob is %d length, %08X\n", blob->length, *(uint32_t *)blob->data);
|
||||||
|
drmModeFreePropertyBlob(blob);
|
||||||
|
} else {
|
||||||
|
printf("error getting blob %lld\n", value);
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
if (!strncmp(props->name, "DPMS", 4))
|
||||||
|
;
|
||||||
|
|
||||||
|
for (j = 0; j < props->count_enums; j++) {
|
||||||
|
printf("\t\t%lld = %s\n", props->enums[j].value, props->enums[j].name);
|
||||||
|
if (props->enums[j].value == value)
|
||||||
|
name = props->enums[j].name;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (props->count_enums && name) {
|
||||||
|
printf("\tcon_value : %s\n", name);
|
||||||
|
} else {
|
||||||
|
printf("\tcon_value : %lld\n", value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int printConnector(int fd, drmModeResPtr res, drmModeConnectorPtr connector, uint32_t id)
|
||||||
|
{
|
||||||
|
int i = 0;
|
||||||
|
struct drm_mode_modeinfo *mode = NULL;
|
||||||
|
drmModePropertyPtr props;
|
||||||
|
|
||||||
|
printf("Connector: %d-%d\n", connector->connector_type, connector->connector_type_id);
|
||||||
|
printf("\tid : %i\n", id);
|
||||||
|
printf("\tencoder id : %i\n", connector->encoder_id);
|
||||||
|
printf("\tconn : %s\n", getConnectionText(connector->connection));
|
||||||
|
printf("\tsize : %ix%i (mm)\n", connector->mmWidth, connector->mmHeight);
|
||||||
|
printf("\tcount_modes : %i\n", connector->count_modes);
|
||||||
|
printf("\tcount_props : %i\n", connector->count_props);
|
||||||
|
if (connector->count_props) {
|
||||||
|
printf("\tprops :");
|
||||||
|
for (i = 0; i < connector->count_props; i++)
|
||||||
|
printf(" %i", connector->props[i]);
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("\tcount_encoders : %i\n", connector->count_encoders);
|
||||||
|
if (connector->count_encoders) {
|
||||||
|
printf("\tencoders :");
|
||||||
|
for (i = 0; i < connector->count_encoders; i++)
|
||||||
|
printf(" %i", connector->encoders[i]);
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (modes) {
|
||||||
|
for (i = 0; i < connector->count_modes; i++) {
|
||||||
|
mode = &connector->modes[i];
|
||||||
|
printMode(mode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (full_props) {
|
||||||
|
for (i = 0; i < connector->count_props; i++) {
|
||||||
|
props = drmModeGetProperty(fd, connector->props[i]);
|
||||||
|
if (props) {
|
||||||
|
printProperty(fd, res, props, connector->prop_values[i]);
|
||||||
|
drmModeFreeProperty(props);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int printEncoder(int fd, drmModeResPtr res, drmModeEncoderPtr encoder, uint32_t id)
|
||||||
|
{
|
||||||
|
printf("Encoder\n");
|
||||||
|
printf("\tid :%i\n", id);
|
||||||
|
printf("\tcrtc_id :%d\n", encoder->crtc_id);
|
||||||
|
printf("\ttype :%d\n", encoder->encoder_type);
|
||||||
|
printf("\tpossible_crtcs :%d\n", encoder->possible_crtcs);
|
||||||
|
printf("\tpossible_clones :%d\n", encoder->possible_clones);
|
||||||
|
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("\tgamma size : %d\n", crtc->gamma_size);
|
||||||
|
|
||||||
|
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->handle);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int printRes(int fd, drmModeResPtr res)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
drmModeFBPtr fb;
|
||||||
|
drmModeCrtcPtr crtc;
|
||||||
|
drmModeEncoderPtr encoder;
|
||||||
|
drmModeConnectorPtr connector;
|
||||||
|
|
||||||
|
printf("Resources\n\n");
|
||||||
|
|
||||||
|
printf("count_connectors : %i\n", res->count_connectors);
|
||||||
|
printf("count_encoders : %i\n", res->count_encoders);
|
||||||
|
printf("count_crtcs : %i\n", res->count_crtcs);
|
||||||
|
printf("count_fbs : %i\n", res->count_fbs);
|
||||||
|
|
||||||
|
printf("\n");
|
||||||
|
|
||||||
|
if (connectors) {
|
||||||
|
for (i = 0; i < res->count_connectors; i++) {
|
||||||
|
connector = drmModeGetConnector(fd, res->connectors[i]);
|
||||||
|
|
||||||
|
if (!connector)
|
||||||
|
printf("Could not get connector %i\n", res->connectors[i]);
|
||||||
|
else {
|
||||||
|
printConnector(fd, res, connector, res->connectors[i]);
|
||||||
|
drmModeFreeConnector(connector);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (encoders) {
|
||||||
|
for (i = 0; i < res->count_encoders; i++) {
|
||||||
|
encoder = drmModeGetEncoder(fd, res->encoders[i]);
|
||||||
|
|
||||||
|
if (!encoder)
|
||||||
|
printf("Could not get encoder %i\n", res->encoders[i]);
|
||||||
|
else {
|
||||||
|
printEncoder(fd, res, encoder, res->encoders[i]);
|
||||||
|
drmModeFreeEncoder(encoder);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (crtcs) {
|
||||||
|
for (i = 0; i < res->count_crtcs; i++) {
|
||||||
|
crtc = drmModeGetCrtc(fd, res->crtcs[i]);
|
||||||
|
|
||||||
|
if (!crtc)
|
||||||
|
printf("Could not get crtc %i\n", res->crtcs[i]);
|
||||||
|
else {
|
||||||
|
printCrtc(fd, res, crtc, res->crtcs[i]);
|
||||||
|
drmModeFreeCrtc(crtc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fbs) {
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
void args(int argc, char **argv)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
fbs = 0;
|
||||||
|
edid = 0;
|
||||||
|
crtcs = 0;
|
||||||
|
modes = 0;
|
||||||
|
encoders = 0;
|
||||||
|
full_modes = 0;
|
||||||
|
full_props = 0;
|
||||||
|
connectors = 0;
|
||||||
|
|
||||||
|
module_name = argv[1];
|
||||||
|
|
||||||
|
for (i = 2; i < argc; i++) {
|
||||||
|
if (strcmp(argv[i], "-fb") == 0) {
|
||||||
|
fbs = 1;
|
||||||
|
} else if (strcmp(argv[i], "-crtcs") == 0) {
|
||||||
|
crtcs = 1;
|
||||||
|
} else if (strcmp(argv[i], "-cons") == 0) {
|
||||||
|
connectors = 1;
|
||||||
|
modes = 1;
|
||||||
|
} else if (strcmp(argv[i], "-modes") == 0) {
|
||||||
|
connectors = 1;
|
||||||
|
modes = 1;
|
||||||
|
} else if (strcmp(argv[i], "-full") == 0) {
|
||||||
|
connectors = 1;
|
||||||
|
modes = 1;
|
||||||
|
full_modes = 1;
|
||||||
|
} else if (strcmp(argv[i], "-props") == 0) {
|
||||||
|
connectors = 1;
|
||||||
|
full_props = 1;
|
||||||
|
} else if (strcmp(argv[i], "-edids") == 0) {
|
||||||
|
connectors = 1;
|
||||||
|
edid = 1;
|
||||||
|
} else if (strcmp(argv[i], "-encoders") == 0) {
|
||||||
|
encoders = 1;
|
||||||
|
} else if (strcmp(argv[i], "-v") == 0) {
|
||||||
|
fbs = 1;
|
||||||
|
edid = 1;
|
||||||
|
crtcs = 1;
|
||||||
|
modes = 1;
|
||||||
|
encoders = 1;
|
||||||
|
full_modes = 1;
|
||||||
|
full_props = 1;
|
||||||
|
connectors = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (argc == 2) {
|
||||||
|
fbs = 1;
|
||||||
|
edid = 1;
|
||||||
|
crtcs = 1;
|
||||||
|
modes = 1;
|
||||||
|
encoders = 1;
|
||||||
|
full_modes = 0;
|
||||||
|
full_props = 0;
|
||||||
|
connectors = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
int fd;
|
||||||
|
drmModeResPtr res;
|
||||||
|
|
||||||
|
if (argc == 1) {
|
||||||
|
printf("Please add modulename as first argument\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
args(argc, argv);
|
||||||
|
|
||||||
|
printf("Starting test\n");
|
||||||
|
|
||||||
|
fd = drmOpen(module_name, NULL);
|
||||||
|
|
||||||
|
if (fd < 0) {
|
||||||
|
printf("Failed to open the card fd (%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);
|
||||||
|
|
||||||
|
drmModeFreeResources(res);
|
||||||
|
|
||||||
|
printf("Ok\n");
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -0,0 +1 @@
|
||||||
|
LD_PRELOAD=../../libdrm/.libs/libdrm.so ./app $@
|
|
@ -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../../libdrm/intel -I../../shared-core -L../../libdrm/.libs -L../../libdrm/intel/.libs -ldrm -ldrm_intel modetest.c
|
||||||
|
|
||||||
|
clean:
|
||||||
|
@rm -f app
|
||||||
|
|
||||||
|
run: app
|
||||||
|
sudo ./test
|
|
@ -0,0 +1,449 @@
|
||||||
|
/*
|
||||||
|
* DRM based mode setting test program
|
||||||
|
* Copyright 2008 Tungsten Graphics
|
||||||
|
* Jakob Bornecrantz <jakob@tungstengraphics.com>
|
||||||
|
* Copyright 2008 Intel Corporation
|
||||||
|
* Jesse Barnes <jesse.barnes@intel.com>
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This fairly simple test program dumps output in a similar format to the
|
||||||
|
* "xrandr" tool everyone knows & loves. It's necessarily slightly different
|
||||||
|
* since the kernel separates outputs into encoder and connector structures,
|
||||||
|
* each with their own unique ID. The program also allows test testing of the
|
||||||
|
* memory management and mode setting APIs by allowing the user to specify a
|
||||||
|
* connector and mode to use for mode setting. If all works as expected, a
|
||||||
|
* blue background should be painted on the monitor attached to the specified
|
||||||
|
* connector after the selected mode is set.
|
||||||
|
*
|
||||||
|
* TODO: use cairo to write the mode info on the selected output once
|
||||||
|
* the mode has been programmed, along with possible test patterns.
|
||||||
|
*/
|
||||||
|
#include <assert.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
#include "xf86drm.h"
|
||||||
|
#include "xf86drmMode.h"
|
||||||
|
#include "intel_bufmgr.h"
|
||||||
|
|
||||||
|
drmModeRes *resources;
|
||||||
|
int fd, modes;
|
||||||
|
|
||||||
|
#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
|
||||||
|
|
||||||
|
struct type_name {
|
||||||
|
int type;
|
||||||
|
char *name;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define type_name_fn(res) \
|
||||||
|
char * res##_str(int type) { \
|
||||||
|
int i; \
|
||||||
|
for (i = 0; i < ARRAY_SIZE(res##_names); i++) { \
|
||||||
|
if (res##_names[i].type == type) \
|
||||||
|
return res##_names[i].name; \
|
||||||
|
} \
|
||||||
|
return "(invalid)"; \
|
||||||
|
}
|
||||||
|
|
||||||
|
struct type_name encoder_type_names[] = {
|
||||||
|
{ DRM_MODE_ENCODER_NONE, "none" },
|
||||||
|
{ DRM_MODE_ENCODER_DAC, "DAC" },
|
||||||
|
{ DRM_MODE_ENCODER_TMDS, "TMDS" },
|
||||||
|
{ DRM_MODE_ENCODER_LVDS, "LVDS" },
|
||||||
|
{ DRM_MODE_ENCODER_TVDAC, "TVDAC" },
|
||||||
|
};
|
||||||
|
|
||||||
|
type_name_fn(encoder_type)
|
||||||
|
|
||||||
|
struct type_name connector_status_names[] = {
|
||||||
|
{ DRM_MODE_CONNECTED, "connected" },
|
||||||
|
{ DRM_MODE_DISCONNECTED, "disconnected" },
|
||||||
|
{ DRM_MODE_UNKNOWNCONNECTION, "unknown" },
|
||||||
|
};
|
||||||
|
|
||||||
|
type_name_fn(connector_status)
|
||||||
|
|
||||||
|
struct type_name connector_type_names[] = {
|
||||||
|
{ DRM_MODE_CONNECTOR_Unknown, "unknown" },
|
||||||
|
{ DRM_MODE_CONNECTOR_VGA, "VGA" },
|
||||||
|
{ DRM_MODE_CONNECTOR_DVII, "DVI-I" },
|
||||||
|
{ DRM_MODE_CONNECTOR_DVID, "DVI-D" },
|
||||||
|
{ DRM_MODE_CONNECTOR_DVIA, "DVI-A" },
|
||||||
|
{ DRM_MODE_CONNECTOR_Composite, "composite" },
|
||||||
|
{ DRM_MODE_CONNECTOR_SVIDEO, "s-video" },
|
||||||
|
{ DRM_MODE_CONNECTOR_LVDS, "LVDS" },
|
||||||
|
{ DRM_MODE_CONNECTOR_Component, "component" },
|
||||||
|
{ DRM_MODE_CONNECTOR_9PinDIN, "9-pin DIN" },
|
||||||
|
{ DRM_MODE_CONNECTOR_DisplayPort, "displayport" },
|
||||||
|
{ DRM_MODE_CONNECTOR_HDMIA, "HDMI-A" },
|
||||||
|
{ DRM_MODE_CONNECTOR_HDMIB, "HDMI-B" },
|
||||||
|
};
|
||||||
|
|
||||||
|
type_name_fn(connector_type)
|
||||||
|
|
||||||
|
void dump_encoders(void)
|
||||||
|
{
|
||||||
|
drmModeEncoder *encoder;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
printf("Encoders:\n");
|
||||||
|
printf("id\tcrtc\ttype\tpossible crtcs\tpossible clones\t\n");
|
||||||
|
for (i = 0; i < resources->count_encoders; i++) {
|
||||||
|
encoder = drmModeGetEncoder(fd, resources->encoders[i]);
|
||||||
|
|
||||||
|
if (!encoder) {
|
||||||
|
fprintf(stderr, "could not get encoder %i: %s\n",
|
||||||
|
resources->encoders[i], strerror(errno));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
printf("%d\t%d\t%s\t0x%08x\t0x%08x\n",
|
||||||
|
encoder->encoder_id,
|
||||||
|
encoder->crtc_id,
|
||||||
|
encoder_type_str(encoder->encoder_type),
|
||||||
|
encoder->possible_crtcs,
|
||||||
|
encoder->possible_clones);
|
||||||
|
drmModeFreeEncoder(encoder);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void dump_connectors(void)
|
||||||
|
{
|
||||||
|
drmModeConnector *connector;
|
||||||
|
int i, j;
|
||||||
|
|
||||||
|
printf("Connectors:\n");
|
||||||
|
printf("id\tencoder\tstatus\t\ttype\tsize (mm)\tmodes\n");
|
||||||
|
for (i = 0; i < resources->count_connectors; i++) {
|
||||||
|
connector = drmModeGetConnector(fd, resources->connectors[i]);
|
||||||
|
|
||||||
|
if (!connector) {
|
||||||
|
fprintf(stderr, "could not get connector %i: %s\n",
|
||||||
|
resources->connectors[i], strerror(errno));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("%d\t%d\t%s\t%s\t%dx%d\t\t%d\n",
|
||||||
|
connector->connector_id,
|
||||||
|
connector->encoder_id,
|
||||||
|
connector_status_str(connector->connection),
|
||||||
|
connector_type_str(connector->connector_type),
|
||||||
|
connector->mmWidth, connector->mmHeight,
|
||||||
|
connector->count_modes);
|
||||||
|
|
||||||
|
if (!connector->count_modes)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
printf(" modes:\n");
|
||||||
|
printf(" name refresh (Hz) hdisp hss hse htot vdisp "
|
||||||
|
"vss vse vtot)\n");
|
||||||
|
for (j = 0; j < connector->count_modes; j++) {
|
||||||
|
struct drm_mode_modeinfo *mode;
|
||||||
|
|
||||||
|
mode = &connector->modes[j];
|
||||||
|
printf(" %s %.02f %d %d %d %d %d %d %d %d\n",
|
||||||
|
mode->name,
|
||||||
|
(float)mode->vrefresh / 1000,
|
||||||
|
mode->hdisplay,
|
||||||
|
mode->hsync_start,
|
||||||
|
mode->hsync_end,
|
||||||
|
mode->htotal,
|
||||||
|
mode->vdisplay,
|
||||||
|
mode->vsync_start,
|
||||||
|
mode->vsync_end,
|
||||||
|
mode->vtotal);
|
||||||
|
}
|
||||||
|
drmModeFreeConnector(connector);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void dump_crtcs(void)
|
||||||
|
{
|
||||||
|
drmModeCrtc *crtc;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < resources->count_crtcs; i++) {
|
||||||
|
crtc = drmModeGetCrtc(fd, resources->crtcs[i]);
|
||||||
|
|
||||||
|
if (!crtc) {
|
||||||
|
fprintf(stderr, "could not get crtc %i: %s\n",
|
||||||
|
resources->crtcs[i], strerror(errno));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
drmModeFreeCrtc(crtc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void dump_framebuffers(void)
|
||||||
|
{
|
||||||
|
drmModeFB *fb;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < resources->count_fbs; i++) {
|
||||||
|
fb = drmModeGetFB(fd, resources->fbs[i]);
|
||||||
|
|
||||||
|
if (!fb) {
|
||||||
|
fprintf(stderr, "could not get fb %i: %s\n",
|
||||||
|
resources->fbs[i], strerror(errno));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
drmModeFreeFB(fb);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Mode setting with the kernel interfaces is a bit of a chore.
|
||||||
|
* First you have to find the connector in question and make sure the
|
||||||
|
* requested mode is available.
|
||||||
|
* Then you need to find the encoder attached to that connector so you
|
||||||
|
* can bind it with a free crtc.
|
||||||
|
*/
|
||||||
|
void set_mode(int connector_id, char *mode_str)
|
||||||
|
{
|
||||||
|
drmModeConnector *connector;
|
||||||
|
drmModeEncoder *encoder = NULL;
|
||||||
|
struct drm_mode_modeinfo *mode = NULL;
|
||||||
|
drm_intel_bufmgr *bufmgr;
|
||||||
|
drm_intel_bo *bo;
|
||||||
|
unsigned int fb_id, *fb_ptr;
|
||||||
|
int i, j, size, ret, width, height;
|
||||||
|
|
||||||
|
/* First, find the connector & mode */
|
||||||
|
for (i = 0; i < resources->count_connectors; i++) {
|
||||||
|
connector = drmModeGetConnector(fd, resources->connectors[i]);
|
||||||
|
|
||||||
|
if (!connector) {
|
||||||
|
fprintf(stderr, "could not get connector %i: %s\n",
|
||||||
|
resources->connectors[i], strerror(errno));
|
||||||
|
drmModeFreeConnector(connector);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!connector->count_modes) {
|
||||||
|
drmModeFreeConnector(connector);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (connector->connector_id != connector_id) {
|
||||||
|
drmModeFreeConnector(connector);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (j = 0; j < connector->count_modes; j++) {
|
||||||
|
mode = &connector->modes[j];
|
||||||
|
if (!strcmp(mode->name, mode_str))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Found it, break out */
|
||||||
|
if (mode)
|
||||||
|
break;
|
||||||
|
|
||||||
|
drmModeFreeConnector(connector);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!mode) {
|
||||||
|
fprintf(stderr, "failed to find mode \"%s\"\n", mode_str);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
width = mode->hdisplay;
|
||||||
|
height = mode->vdisplay;
|
||||||
|
|
||||||
|
/* Now get the encoder */
|
||||||
|
for (i = 0; i < resources->count_encoders; i++) {
|
||||||
|
encoder = drmModeGetEncoder(fd, resources->encoders[i]);
|
||||||
|
|
||||||
|
if (!encoder) {
|
||||||
|
fprintf(stderr, "could not get encoder %i: %s\n",
|
||||||
|
resources->encoders[i], strerror(errno));
|
||||||
|
drmModeFreeEncoder(encoder);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (encoder->encoder_id == connector->encoder_id)
|
||||||
|
break;
|
||||||
|
|
||||||
|
drmModeFreeEncoder(encoder);
|
||||||
|
}
|
||||||
|
|
||||||
|
bufmgr = drm_intel_bufmgr_gem_init(fd, 2<<20);
|
||||||
|
if (!bufmgr) {
|
||||||
|
fprintf(stderr, "failed to init bufmgr: %s\n", strerror(errno));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Mode size at 32 bpp */
|
||||||
|
size = width * height * 4;
|
||||||
|
|
||||||
|
bo = drm_intel_bo_alloc(bufmgr, "frontbuffer", size, 4096);
|
||||||
|
if (!bo) {
|
||||||
|
fprintf(stderr, "failed to alloc buffer: %s\n",
|
||||||
|
strerror(errno));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = drm_intel_bo_pin(bo, 4096);
|
||||||
|
if (ret) {
|
||||||
|
fprintf(stderr, "failed to pin buffer: %s\n", strerror(errno));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = drm_intel_gem_bo_map_gtt(bo);
|
||||||
|
if (ret) {
|
||||||
|
fprintf(stderr, "failed to GTT map buffer: %s\n",
|
||||||
|
strerror(errno));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
fb_ptr = bo->virtual;
|
||||||
|
|
||||||
|
/* paint the buffer blue */
|
||||||
|
for (i = 0; i < width * height; i++)
|
||||||
|
fb_ptr[i] = 0xff;
|
||||||
|
|
||||||
|
ret = drmModeAddFB(fd, width, height, 32, 32, width * 4, bo->handle,
|
||||||
|
&fb_id);
|
||||||
|
if (ret) {
|
||||||
|
fprintf(stderr, "failed to add fb: %s\n", strerror(errno));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = drmModeSetCrtc(fd, encoder->crtc_id, fb_id, 0, 0,
|
||||||
|
&connector->connector_id, 1, mode);
|
||||||
|
if (ret) {
|
||||||
|
fprintf(stderr, "failed to set mode: %s\n", strerror(errno));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extern char *optarg;
|
||||||
|
extern int optind, opterr, optopt;
|
||||||
|
static char optstr[] = "ecpmfs:";
|
||||||
|
|
||||||
|
void usage(char *name)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "usage: %s [-ecpmf]\n", name);
|
||||||
|
fprintf(stderr, "\t-e\tlist encoders\n");
|
||||||
|
fprintf(stderr, "\t-c\tlist connectors\n");
|
||||||
|
fprintf(stderr, "\t-p\tlist CRTCs (pipes)\n");
|
||||||
|
fprintf(stderr, "\t-m\tlist modes\n");
|
||||||
|
fprintf(stderr, "\t-f\tlist framebuffers\n");
|
||||||
|
fprintf(stderr, "\t-s <connector_id>:<mode>\tset a mode\n");
|
||||||
|
fprintf(stderr, "\n\tDefault is to dump all info.\n");
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define dump_resource(res) if (res) dump_##res()
|
||||||
|
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
int c;
|
||||||
|
int encoders = 0, connectors = 0, crtcs = 0, framebuffers = 0;
|
||||||
|
char *modules[] = { "i915", "radeon" };
|
||||||
|
char *modeset = NULL, *mode, *connector;
|
||||||
|
int i, connector_id;
|
||||||
|
|
||||||
|
opterr = 0;
|
||||||
|
while ((c = getopt(argc, argv, optstr)) != -1) {
|
||||||
|
switch (c) {
|
||||||
|
case 'e':
|
||||||
|
encoders = 1;
|
||||||
|
break;
|
||||||
|
case 'c':
|
||||||
|
connectors = 1;
|
||||||
|
break;
|
||||||
|
case 'p':
|
||||||
|
crtcs = 1;
|
||||||
|
break;
|
||||||
|
case 'm':
|
||||||
|
modes = 1;
|
||||||
|
break;
|
||||||
|
case 'f':
|
||||||
|
framebuffers = 1;
|
||||||
|
break;
|
||||||
|
case 's':
|
||||||
|
modeset = strdup(optarg);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
usage(argv[0]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (argc == 1)
|
||||||
|
encoders = connectors = crtcs = modes = framebuffers = 1;
|
||||||
|
|
||||||
|
for (i = 0; i < ARRAY_SIZE(modules); i++) {
|
||||||
|
printf("trying to load module %s...", modules[i]);
|
||||||
|
fd = drmOpen(modules[i], NULL);
|
||||||
|
if (fd < 0) {
|
||||||
|
printf("failed.\n");
|
||||||
|
} else {
|
||||||
|
printf("success.\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i == ARRAY_SIZE(modules)) {
|
||||||
|
fprintf(stderr, "failed to load any modules, aborting.\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
resources = drmModeGetResources(fd);
|
||||||
|
if (!resources) {
|
||||||
|
fprintf(stderr, "drmModeGetResources failed: %s\n",
|
||||||
|
strerror(errno));
|
||||||
|
drmClose(fd);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
dump_resource(encoders);
|
||||||
|
dump_resource(connectors);
|
||||||
|
dump_resource(crtcs);
|
||||||
|
dump_resource(framebuffers);
|
||||||
|
|
||||||
|
if (modeset) {
|
||||||
|
connector = strtok(modeset, ":");
|
||||||
|
if (!connector)
|
||||||
|
usage(argv[0]);
|
||||||
|
connector_id = atoi(connector);
|
||||||
|
|
||||||
|
mode = strtok(NULL, ":");
|
||||||
|
if (!mode)
|
||||||
|
usage(argv[0]);
|
||||||
|
printf("setting connector %d to mode %s\n", connector_id,
|
||||||
|
mode);
|
||||||
|
set_mode(connector_id, mode);
|
||||||
|
sleep(3);
|
||||||
|
}
|
||||||
|
|
||||||
|
sleep(3);
|
||||||
|
|
||||||
|
drmModeFreeResources(resources);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -0,0 +1,2 @@
|
||||||
|
export LD_LIBRARY_PATH=../../libdrm/.libs:../../libdrm/intel/.libs
|
||||||
|
LD_PRELOAD=../../libdrm/.libs/libdrm.so ./app $@
|
Loading…
Reference in New Issue