mirror of
https://gitlab.freedesktop.org/mesa/drm.git
synced 2026-04-25 04:00:42 +02:00
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.
This commit is contained in:
parent
59d530a4a0
commit
f3cfadad57
11 changed files with 577 additions and 92 deletions
|
|
@ -42,6 +42,7 @@
|
|||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <signal.h>
|
||||
#include <time.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#define stat_t struct stat
|
||||
|
|
@ -177,7 +178,7 @@ static char *drmStrdup(const char *s)
|
|||
/**
|
||||
* Call ioctl, restarting if it is interupted
|
||||
*/
|
||||
static int
|
||||
int
|
||||
drmIoctl(int fd, unsigned long request, void *arg)
|
||||
{
|
||||
int ret;
|
||||
|
|
@ -395,7 +396,7 @@ static int drmOpenMinor(int minor, int create, int type)
|
|||
char buf[64];
|
||||
|
||||
if (create)
|
||||
return drmOpenDevice(makedev(DRM_MAJOR, minor), minor, type);
|
||||
return drmOpenDevice(makedev(DRM_MAJOR, minor), minor, type);
|
||||
|
||||
sprintf(buf, type ? DRM_DEV_NAME : DRM_CONTROL_DEV_NAME, DRM_DIR_NAME, minor);
|
||||
if ((fd = open(buf, O_RDWR, 0)) >= 0)
|
||||
|
|
@ -1896,13 +1897,33 @@ int drmScatterGatherFree(int fd, drm_handle_t handle)
|
|||
*/
|
||||
int drmWaitVBlank(int fd, drmVBlankPtr vbl)
|
||||
{
|
||||
struct timespec timeout, cur;
|
||||
int ret;
|
||||
|
||||
ret = clock_gettime(CLOCK_MONOTONIC, &timeout);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "clock_gettime failed: %s\n", strerror(ret));
|
||||
goto out;
|
||||
}
|
||||
timeout.tv_sec++;
|
||||
|
||||
do {
|
||||
ret = drmIoctl(fd, DRM_IOCTL_WAIT_VBLANK, vbl);
|
||||
ret = ioctl(fd, DRM_IOCTL_WAIT_VBLANK, vbl);
|
||||
vbl->request.type &= ~DRM_VBLANK_RELATIVE;
|
||||
if (ret && errno == EINTR) {
|
||||
clock_gettime(CLOCK_MONOTONIC, &cur);
|
||||
/* Timeout after 1s */
|
||||
if (cur.tv_sec > timeout.tv_sec + 1 ||
|
||||
(cur.tv_sec == timeout.tv_sec && cur.tv_nsec >=
|
||||
timeout.tv_nsec)) {
|
||||
errno = EBUSY;
|
||||
ret = -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} while (ret && errno == EINTR);
|
||||
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -75,6 +75,7 @@ typedef struct drmHashEntry {
|
|||
void *tagTable;
|
||||
} drmHashEntry;
|
||||
|
||||
extern int drmIoctl(int fd, unsigned long request, void *arg);
|
||||
extern void *drmGetHashTable(void);
|
||||
extern drmHashEntry *drmGetEntry(int fd);
|
||||
|
||||
|
|
|
|||
|
|
@ -9,7 +9,9 @@
|
|||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) <year> <copyright holders>
|
||||
* 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"),
|
||||
|
|
@ -135,7 +137,7 @@ drmModeResPtr drmModeGetResources(int fd)
|
|||
|
||||
memset(&res, 0, sizeof(struct drm_mode_card_res));
|
||||
|
||||
if (ioctl(fd, DRM_IOCTL_MODE_GETRESOURCES, &res))
|
||||
if (drmIoctl(fd, DRM_IOCTL_MODE_GETRESOURCES, &res))
|
||||
return 0;
|
||||
|
||||
if (res.count_fbs)
|
||||
|
|
@ -147,7 +149,7 @@ drmModeResPtr drmModeGetResources(int fd)
|
|||
if (res.count_encoders)
|
||||
res.encoder_id_ptr = VOID2U64(drmMalloc(res.count_encoders*sizeof(uint32_t)));
|
||||
|
||||
if (ioctl(fd, DRM_IOCTL_MODE_GETRESOURCES, &res)) {
|
||||
if (drmIoctl(fd, DRM_IOCTL_MODE_GETRESOURCES, &res)) {
|
||||
r = NULL;
|
||||
goto err_allocs;
|
||||
}
|
||||
|
|
@ -197,7 +199,7 @@ int drmModeAddFB(int fd, uint32_t width, uint32_t height, uint8_t depth,
|
|||
f.depth = depth;
|
||||
f.handle = bo_handle;
|
||||
|
||||
if ((ret = ioctl(fd, DRM_IOCTL_MODE_ADDFB, &f)))
|
||||
if ((ret = drmIoctl(fd, DRM_IOCTL_MODE_ADDFB, &f)))
|
||||
return ret;
|
||||
|
||||
*buf_id = f.fb_id;
|
||||
|
|
@ -206,7 +208,7 @@ int drmModeAddFB(int fd, uint32_t width, uint32_t height, uint8_t depth,
|
|||
|
||||
int drmModeRmFB(int fd, uint32_t bufferId)
|
||||
{
|
||||
return ioctl(fd, DRM_IOCTL_MODE_RMFB, &bufferId);
|
||||
return drmIoctl(fd, DRM_IOCTL_MODE_RMFB, &bufferId);
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -218,7 +220,7 @@ drmModeFBPtr drmModeGetFB(int fd, uint32_t buf)
|
|||
|
||||
info.fb_id = buf;
|
||||
|
||||
if (ioctl(fd, DRM_IOCTL_MODE_GETFB, &info))
|
||||
if (drmIoctl(fd, DRM_IOCTL_MODE_GETFB, &info))
|
||||
return NULL;
|
||||
|
||||
if (!(r = drmMalloc(sizeof(*r))))
|
||||
|
|
@ -247,7 +249,7 @@ drmModeCrtcPtr drmModeGetCrtc(int fd, uint32_t crtcId)
|
|||
|
||||
crtc.crtc_id = crtcId;
|
||||
|
||||
if (ioctl(fd, DRM_IOCTL_MODE_GETCRTC, &crtc))
|
||||
if (drmIoctl(fd, DRM_IOCTL_MODE_GETCRTC, &crtc))
|
||||
return 0;
|
||||
|
||||
/*
|
||||
|
|
@ -256,7 +258,7 @@ drmModeCrtcPtr drmModeGetCrtc(int fd, uint32_t crtcId)
|
|||
|
||||
if (!(r = drmMalloc(sizeof(*r))))
|
||||
return 0;
|
||||
|
||||
|
||||
r->crtc_id = crtc.crtc_id;
|
||||
r->x = crtc.x;
|
||||
r->y = crtc.y;
|
||||
|
|
@ -287,7 +289,7 @@ int drmModeSetCrtc(int fd, uint32_t crtcId, uint32_t bufferId,
|
|||
} else
|
||||
crtc.mode_valid = 0;
|
||||
|
||||
return ioctl(fd, DRM_IOCTL_MODE_SETCRTC, &crtc);
|
||||
return drmIoctl(fd, DRM_IOCTL_MODE_SETCRTC, &crtc);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -304,7 +306,7 @@ int drmModeSetCursor(int fd, uint32_t crtcId, uint32_t bo_handle, uint32_t width
|
|||
arg.height = height;
|
||||
arg.handle = bo_handle;
|
||||
|
||||
return ioctl(fd, DRM_IOCTL_MODE_CURSOR, &arg);
|
||||
return drmIoctl(fd, DRM_IOCTL_MODE_CURSOR, &arg);
|
||||
}
|
||||
|
||||
int drmModeMoveCursor(int fd, uint32_t crtcId, int x, int y)
|
||||
|
|
@ -316,11 +318,11 @@ int drmModeMoveCursor(int fd, uint32_t crtcId, int x, int y)
|
|||
arg.x = x;
|
||||
arg.y = y;
|
||||
|
||||
return ioctl(fd, DRM_IOCTL_MODE_CURSOR, &arg);
|
||||
return drmIoctl(fd, DRM_IOCTL_MODE_CURSOR, &arg);
|
||||
}
|
||||
|
||||
/*
|
||||
* Encoder get
|
||||
* Encoder get
|
||||
*/
|
||||
drmModeEncoderPtr drmModeGetEncoder(int fd, uint32_t encoder_id)
|
||||
{
|
||||
|
|
@ -332,7 +334,7 @@ drmModeEncoderPtr drmModeGetEncoder(int fd, uint32_t encoder_id)
|
|||
enc.possible_crtcs = 0;
|
||||
enc.possible_clones = 0;
|
||||
|
||||
if (ioctl(fd, DRM_IOCTL_MODE_GETENCODER, &enc))
|
||||
if (drmIoctl(fd, DRM_IOCTL_MODE_GETENCODER, &enc))
|
||||
return 0;
|
||||
|
||||
if (!(r = drmMalloc(sizeof(*r))))
|
||||
|
|
@ -367,7 +369,7 @@ drmModeConnectorPtr drmModeGetConnector(int fd, uint32_t connector_id)
|
|||
conn.count_encoders = 0;
|
||||
conn.encoders_ptr = 0;
|
||||
|
||||
if (ioctl(fd, DRM_IOCTL_MODE_GETCONNECTOR, &conn))
|
||||
if (drmIoctl(fd, DRM_IOCTL_MODE_GETCONNECTOR, &conn))
|
||||
return 0;
|
||||
|
||||
if (conn.count_props) {
|
||||
|
|
@ -381,7 +383,7 @@ drmModeConnectorPtr drmModeGetConnector(int fd, uint32_t connector_id)
|
|||
if (conn.count_encoders)
|
||||
conn.encoders_ptr = VOID2U64(drmMalloc(conn.count_encoders*sizeof(uint32_t)));
|
||||
|
||||
if (ioctl(fd, DRM_IOCTL_MODE_GETCONNECTOR, &conn))
|
||||
if (drmIoctl(fd, DRM_IOCTL_MODE_GETCONNECTOR, &conn))
|
||||
goto err_allocs;
|
||||
|
||||
if(!(r = drmMalloc(sizeof(*r)))) {
|
||||
|
|
@ -424,7 +426,7 @@ int drmModeAttachMode(int fd, uint32_t connector_id, struct drm_mode_modeinfo *m
|
|||
memcpy(&res.mode, mode_info, sizeof(struct drm_mode_modeinfo));
|
||||
res.connector_id = connector_id;
|
||||
|
||||
return ioctl(fd, DRM_IOCTL_MODE_ATTACHMODE, &res);
|
||||
return drmIoctl(fd, DRM_IOCTL_MODE_ATTACHMODE, &res);
|
||||
}
|
||||
|
||||
int drmModeDetachMode(int fd, uint32_t connector_id, struct drm_mode_modeinfo *mode_info)
|
||||
|
|
@ -434,7 +436,7 @@ int drmModeDetachMode(int fd, uint32_t connector_id, struct drm_mode_modeinfo *m
|
|||
memcpy(&res.mode, mode_info, sizeof(struct drm_mode_modeinfo));
|
||||
res.connector_id = connector_id;
|
||||
|
||||
return ioctl(fd, DRM_IOCTL_MODE_DETACHMODE, &res);
|
||||
return drmIoctl(fd, DRM_IOCTL_MODE_DETACHMODE, &res);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -450,7 +452,7 @@ drmModePropertyPtr drmModeGetProperty(int fd, uint32_t property_id)
|
|||
prop.enum_blob_ptr = 0;
|
||||
prop.values_ptr = 0;
|
||||
|
||||
if (ioctl(fd, DRM_IOCTL_MODE_GETPROPERTY, &prop))
|
||||
if (drmIoctl(fd, DRM_IOCTL_MODE_GETPROPERTY, &prop))
|
||||
return 0;
|
||||
|
||||
if (prop.count_values)
|
||||
|
|
@ -464,17 +466,17 @@ drmModePropertyPtr drmModeGetProperty(int fd, uint32_t property_id)
|
|||
prop.enum_blob_ptr = VOID2U64(drmMalloc(prop.count_enum_blobs * sizeof(uint32_t)));
|
||||
}
|
||||
|
||||
if (ioctl(fd, DRM_IOCTL_MODE_GETPROPERTY, &prop)) {
|
||||
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));
|
||||
|
|
@ -515,13 +517,13 @@ drmModePropertyBlobPtr drmModeGetPropertyBlob(int fd, uint32_t blob_id)
|
|||
blob.data = 0;
|
||||
blob.blob_id = blob_id;
|
||||
|
||||
if (ioctl(fd, DRM_IOCTL_MODE_GETPROPBLOB, &blob))
|
||||
if (drmIoctl(fd, DRM_IOCTL_MODE_GETPROPBLOB, &blob))
|
||||
return NULL;
|
||||
|
||||
if (blob.length)
|
||||
blob.data = VOID2U64(drmMalloc(blob.length));
|
||||
|
||||
if (ioctl(fd, DRM_IOCTL_MODE_GETPROPBLOB, &blob)) {
|
||||
if (drmIoctl(fd, DRM_IOCTL_MODE_GETPROPBLOB, &blob)) {
|
||||
r = NULL;
|
||||
goto err_allocs;
|
||||
}
|
||||
|
|
@ -557,7 +559,7 @@ int drmModeConnectorSetProperty(int fd, uint32_t connector_id, uint32_t property
|
|||
osp.prop_id = property_id;
|
||||
osp.value = value;
|
||||
|
||||
if ((ret = ioctl(fd, DRM_IOCTL_MODE_SETPROPERTY, &osp)))
|
||||
if ((ret = drmIoctl(fd, DRM_IOCTL_MODE_SETPROPERTY, &osp)))
|
||||
return ret;
|
||||
|
||||
return 0;
|
||||
|
|
@ -593,7 +595,7 @@ int drmCheckModesettingSupported(const char *busid)
|
|||
found = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
dent = readdir(sysdir);
|
||||
}
|
||||
closedir(sysdir);
|
||||
|
|
@ -614,10 +616,10 @@ int drmCheckModesettingSupported(const char *busid)
|
|||
found = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
dent = readdir(sysdir);
|
||||
}
|
||||
|
||||
|
||||
closedir(sysdir);
|
||||
if (found)
|
||||
return 0;
|
||||
|
|
@ -626,27 +628,6 @@ int drmCheckModesettingSupported(const char *busid)
|
|||
|
||||
}
|
||||
|
||||
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 = ioctl(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)
|
||||
{
|
||||
|
|
@ -658,8 +639,8 @@ int drmModeCrtcGetGamma(int fd, uint32_t crtc_id, uint32_t size,
|
|||
l.red = VOID2U64(red);
|
||||
l.green = VOID2U64(green);
|
||||
l.blue = VOID2U64(blue);
|
||||
|
||||
if ((ret = ioctl(fd, DRM_IOCTL_MODE_GETGAMMA, &l)))
|
||||
|
||||
if ((ret = drmIoctl(fd, DRM_IOCTL_MODE_GETGAMMA, &l)))
|
||||
return ret;
|
||||
|
||||
return 0;
|
||||
|
|
@ -676,8 +657,8 @@ int drmModeCrtcSetGamma(int fd, uint32_t crtc_id, uint32_t size,
|
|||
l.red = VOID2U64(red);
|
||||
l.green = VOID2U64(green);
|
||||
l.blue = VOID2U64(blue);
|
||||
|
||||
if ((ret = ioctl(fd, DRM_IOCTL_MODE_SETGAMMA, &l)))
|
||||
|
||||
if ((ret = drmIoctl(fd, DRM_IOCTL_MODE_SETGAMMA, &l)))
|
||||
return ret;
|
||||
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -9,7 +9,9 @@
|
|||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) <year> <copyright holders>
|
||||
* 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"),
|
||||
|
|
@ -178,13 +180,6 @@ extern int drmModeAddFB(int fd, uint32_t width, uint32_t height, uint8_t depth,
|
|||
*/
|
||||
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
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -769,6 +769,28 @@ struct drm_gem_open {
|
|||
#define DRM_IOCTL_MODE_RMFB DRM_IOWR(0xAF, uint32_t)
|
||||
#define DRM_IOCTL_MODE_REPLACEFB DRM_IOWR(0xB0, struct drm_mode_fb_cmd)
|
||||
|
||||
#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)
|
||||
|
||||
/*@}*/
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -15,6 +15,10 @@ libdrmtest_la_LIBADD = \
|
|||
|
||||
LDADD = libdrmtest.la
|
||||
|
||||
noinst_SUBDIRS = \
|
||||
modeprint \
|
||||
modetest
|
||||
|
||||
TESTS = auth \
|
||||
openclose \
|
||||
getversion \
|
||||
|
|
|
|||
|
|
@ -1,14 +0,0 @@
|
|||
|
||||
all: app
|
||||
|
||||
#CFLAGS = -g -ansi -pedantic -DPOSIX_C_SOURCE=199309L \
|
||||
# -D_POSIX_SOURCE -D_XOPEN_SOURCE -D_BSD_SOURCE -D_SVID_SOURCE \
|
||||
|
||||
app: modetest.c
|
||||
@gcc $(CFLAGS) -o app -Wall -I../../libdrm -I../../shared-core -L../../libdrm/.libs -ldrm modetest.c
|
||||
|
||||
clean:
|
||||
@rm -f app
|
||||
|
||||
run: app
|
||||
@sudo ./test
|
||||
13
tests/modeprint/Makefile.am
Normal file
13
tests/modeprint/Makefile.am
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
AM_CFLAGS = \
|
||||
-I$(top_srcdir)/shared-core \
|
||||
-I$(top_srcdir)/libdrm/intel/ \
|
||||
-I$(top_srcdir)/libdrm
|
||||
|
||||
noinst_PROGRAMS = \
|
||||
modeprint
|
||||
|
||||
modeprint_SOURCES = \
|
||||
modeprint.c
|
||||
modeprint_LDADD = \
|
||||
$(top_builddir)/libdrm/libdrm.la \
|
||||
$(top_builddir)/libdrm/intel/libdrm_intel.la
|
||||
BIN
tests/modeprint/app
Executable file
BIN
tests/modeprint/app
Executable file
Binary file not shown.
402
tests/modeprint/modeprint.c
Normal file
402
tests/modeprint/modeprint.c
Normal file
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -4,6 +4,38 @@
|
|||
* 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>
|
||||
|
|
@ -96,6 +128,22 @@ void dump_encoders(void)
|
|||
encoder->possible_clones);
|
||||
drmModeFreeEncoder(encoder);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
void dump_mode(struct drm_mode_modeinfo *mode)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
void dump_connectors(void)
|
||||
|
|
@ -128,24 +176,12 @@ void dump_connectors(void)
|
|||
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;
|
||||
for (j = 0; j < connector->count_modes; j++)
|
||||
dump_mode(&connector->modes[j]);
|
||||
|
||||
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);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
void dump_crtcs(void)
|
||||
|
|
@ -153,6 +189,8 @@ void dump_crtcs(void)
|
|||
drmModeCrtc *crtc;
|
||||
int i;
|
||||
|
||||
printf("CRTCs:\n");
|
||||
printf("id\tfb\tpos\tsize\n");
|
||||
for (i = 0; i < resources->count_crtcs; i++) {
|
||||
crtc = drmModeGetCrtc(fd, resources->crtcs[i]);
|
||||
|
||||
|
|
@ -161,8 +199,16 @@ void dump_crtcs(void)
|
|||
resources->crtcs[i], strerror(errno));
|
||||
continue;
|
||||
}
|
||||
printf("%d\t%d\t(%d,%d)\t(%dx%d)\n",
|
||||
crtc->crtc_id,
|
||||
crtc->buffer_id,
|
||||
crtc->x, crtc->y,
|
||||
crtc->width, crtc->height);
|
||||
dump_mode(&crtc->mode);
|
||||
|
||||
drmModeFreeCrtc(crtc);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
void dump_framebuffers(void)
|
||||
|
|
@ -170,6 +216,8 @@ void dump_framebuffers(void)
|
|||
drmModeFB *fb;
|
||||
int i;
|
||||
|
||||
printf("Frame buffers:\n");
|
||||
printf("id\tsize\tpitch\n");
|
||||
for (i = 0; i < resources->count_fbs; i++) {
|
||||
fb = drmModeGetFB(fd, resources->fbs[i]);
|
||||
|
||||
|
|
@ -178,10 +226,22 @@ void dump_framebuffers(void)
|
|||
resources->fbs[i], strerror(errno));
|
||||
continue;
|
||||
}
|
||||
printf("%d\t(%dx%d)\t%d\n",
|
||||
fb->fb_id,
|
||||
fb->width, fb->height);
|
||||
|
||||
drmModeFreeFB(fb);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
/*
|
||||
* 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;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue