aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--libdrm/Makefile.am3
-rw-r--r--libdrm/intel/intel_bufmgr.h5
-rw-r--r--libdrm/intel/intel_bufmgr_gem.c1
-rw-r--r--libdrm/xf86drm.c44
-rw-r--r--libdrm/xf86drm.h6
-rw-r--r--libdrm/xf86drmMode.c686
-rw-r--r--libdrm/xf86drmMode.h258
l---------linux-core/drm_mode.h1
-rw-r--r--shared-core/Makefile.am1
-rw-r--r--shared-core/drm.h27
-rw-r--r--shared-core/drm_mode.h271
-rw-r--r--tests/Makefile.am4
-rw-r--r--tests/dristat.c2
-rw-r--r--tests/modeprint/Makefile14
-rwxr-xr-xtests/modeprint/appbin0 -> 16233 bytes
-rw-r--r--tests/modeprint/modeprint.c402
-rw-r--r--tests/modeprint/test1
-rw-r--r--tests/modetest/Makefile14
-rw-r--r--tests/modetest/modetest.c449
-rw-r--r--tests/modetest/test2
20 files changed, 2179 insertions, 12 deletions
diff --git a/libdrm/Makefile.am b/libdrm/Makefile.am
index a5be36e0..eb63abe1 100644
--- a/libdrm/Makefile.am
+++ b/libdrm/Makefile.am
@@ -26,9 +26,10 @@ libdrm_la_LDFLAGS = -version-number 2:4:0 -no-undefined
26 26
27AM_CFLAGS = -I$(top_srcdir)/shared-core 27AM_CFLAGS = -I$(top_srcdir)/shared-core
28libdrm_la_SOURCES = xf86drm.c xf86drmHash.c xf86drmRandom.c xf86drmSL.c \ 28libdrm_la_SOURCES = xf86drm.c xf86drmHash.c xf86drmRandom.c xf86drmSL.c \
29 xf86drmMode.c libdrm_lists.h
29 libdrm_lists.h 30 libdrm_lists.h
30 31
31libdrmincludedir = ${includedir} 32libdrmincludedir = ${includedir}
32libdrminclude_HEADERS = xf86drm.h 33libdrminclude_HEADERS = xf86drm.h xf86drmMode.h
33 34
34EXTRA_DIST = ChangeLog TODO 35EXTRA_DIST = ChangeLog TODO
diff --git a/libdrm/intel/intel_bufmgr.h b/libdrm/intel/intel_bufmgr.h
index f134f169..e8c2e063 100644
--- a/libdrm/intel/intel_bufmgr.h
+++ b/libdrm/intel/intel_bufmgr.h
@@ -66,6 +66,11 @@ struct _drm_intel_bo {
66 66
67 /** Buffer manager context associated with this buffer object */ 67 /** Buffer manager context associated with this buffer object */
68 drm_intel_bufmgr *bufmgr; 68 drm_intel_bufmgr *bufmgr;
69
70 /**
71 * MM-specific handle for accessing object
72 */
73 int handle;
69}; 74};
70 75
71drm_intel_bo *drm_intel_bo_alloc(drm_intel_bufmgr *bufmgr, const char *name, 76drm_intel_bo *drm_intel_bo_alloc(drm_intel_bufmgr *bufmgr, const char *name,
diff --git a/libdrm/intel/intel_bufmgr_gem.c b/libdrm/intel/intel_bufmgr_gem.c
index e5a1375e..9605cc7c 100644
--- a/libdrm/intel/intel_bufmgr_gem.c
+++ b/libdrm/intel/intel_bufmgr_gem.c
@@ -351,6 +351,7 @@ drm_intel_gem_bo_alloc(drm_intel_bufmgr *bufmgr, const char *name,
351 351
352 ret = ioctl(bufmgr_gem->fd, DRM_IOCTL_I915_GEM_CREATE, &create); 352 ret = ioctl(bufmgr_gem->fd, DRM_IOCTL_I915_GEM_CREATE, &create);
353 bo_gem->gem_handle = create.handle; 353 bo_gem->gem_handle = create.handle;
354 bo_gem->bo.handle = bo_gem->gem_handle;
354 if (ret != 0) { 355 if (ret != 0) {
355 free(bo_gem); 356 free(bo_gem);
356 return NULL; 357 return NULL;
diff --git a/libdrm/xf86drm.c b/libdrm/xf86drm.c
index c36f1964..0b5d31fe 100644
--- a/libdrm/xf86drm.c
+++ b/libdrm/xf86drm.c
@@ -87,6 +87,9 @@
87 87
88#define DRM_MSG_VERBOSITY 3 88#define DRM_MSG_VERBOSITY 3
89 89
90#define DRM_NODE_CONTROL 0
91#define DRM_NODE_RENDER 1
92
90static drmServerInfoPtr drm_server_info; 93static drmServerInfoPtr drm_server_info;
91 94
92void drmSetServerInfo(drmServerInfoPtr info) 95void drmSetServerInfo(drmServerInfoPtr info)
@@ -174,7 +177,7 @@ static char *drmStrdup(const char *s)
174/** 177/**
175 * Call ioctl, restarting if it is interupted 178 * Call ioctl, restarting if it is interupted
176 */ 179 */
177static int 180int
178drmIoctl(int fd, unsigned long request, void *arg) 181drmIoctl(int fd, unsigned long request, void *arg)
179{ 182{
180 int ret; 183 int ret;
@@ -277,7 +280,7 @@ static int drmMatchBusID(const char *id1, const char *id2)
277 * special file node with the major and minor numbers specified by \p dev and 280 * special file node with the major and minor numbers specified by \p dev and
278 * parent directory if necessary and was called by root. 281 * parent directory if necessary and was called by root.
279 */ 282 */
280static int drmOpenDevice(long dev, int minor) 283static int drmOpenDevice(long dev, int minor, int type)
281{ 284{
282 stat_t st; 285 stat_t st;
283 char buf[64]; 286 char buf[64];
@@ -287,7 +290,7 @@ static int drmOpenDevice(long dev, int minor)
287 uid_t user = DRM_DEV_UID; 290 uid_t user = DRM_DEV_UID;
288 gid_t group = DRM_DEV_GID, serv_group; 291 gid_t group = DRM_DEV_GID, serv_group;
289 292
290 sprintf(buf, DRM_DEV_NAME, DRM_DIR_NAME, minor); 293 sprintf(buf, type ? DRM_DEV_NAME : DRM_CONTROL_DEV_NAME, DRM_DIR_NAME, minor);
291 drmMsg("drmOpenDevice: node name is %s\n", buf); 294 drmMsg("drmOpenDevice: node name is %s\n", buf);
292 295
293 if (drm_server_info) { 296 if (drm_server_info) {
@@ -386,15 +389,15 @@ wait_for_udev:
386 * Calls drmOpenDevice() if \p create is set, otherwise assembles the device 389 * Calls drmOpenDevice() if \p create is set, otherwise assembles the device
387 * name from \p minor and opens it. 390 * name from \p minor and opens it.
388 */ 391 */
389static int drmOpenMinor(int minor, int create) 392static int drmOpenMinor(int minor, int create, int type)
390{ 393{
391 int fd; 394 int fd;
392 char buf[64]; 395 char buf[64];
393 396
394 if (create) 397 if (create)
395 return drmOpenDevice(makedev(DRM_MAJOR, minor), minor); 398 return drmOpenDevice(makedev(DRM_MAJOR, minor), minor, type);
396 399
397 sprintf(buf, DRM_DEV_NAME, DRM_DIR_NAME, minor); 400 sprintf(buf, type ? DRM_DEV_NAME : DRM_CONTROL_DEV_NAME, DRM_DIR_NAME, minor);
398 if ((fd = open(buf, O_RDWR, 0)) >= 0) 401 if ((fd = open(buf, O_RDWR, 0)) >= 0)
399 return fd; 402 return fd;
400 return -errno; 403 return -errno;
@@ -417,7 +420,7 @@ int drmAvailable(void)
417 int retval = 0; 420 int retval = 0;
418 int fd; 421 int fd;
419 422
420 if ((fd = drmOpenMinor(0, 1)) < 0) { 423 if ((fd = drmOpenMinor(0, 1, DRM_NODE_RENDER)) < 0) {
421#ifdef __linux__ 424#ifdef __linux__
422 /* Try proc for backward Linux compatibility */ 425 /* Try proc for backward Linux compatibility */
423 if (!access("/proc/dri/0", R_OK)) 426 if (!access("/proc/dri/0", R_OK))
@@ -458,7 +461,7 @@ static int drmOpenByBusid(const char *busid)
458 461
459 drmMsg("drmOpenByBusid: Searching for BusID %s\n", busid); 462 drmMsg("drmOpenByBusid: Searching for BusID %s\n", busid);
460 for (i = 0; i < DRM_MAX_MINOR; i++) { 463 for (i = 0; i < DRM_MAX_MINOR; i++) {
461 fd = drmOpenMinor(i, 1); 464 fd = drmOpenMinor(i, 1, DRM_NODE_RENDER);
462 drmMsg("drmOpenByBusid: drmOpenMinor returns %d\n", fd); 465 drmMsg("drmOpenByBusid: drmOpenMinor returns %d\n", fd);
463 if (fd >= 0) { 466 if (fd >= 0) {
464 sv.drm_di_major = 1; 467 sv.drm_di_major = 1;
@@ -520,7 +523,7 @@ static int drmOpenByName(const char *name)
520 * already in use. If it's in use it will have a busid assigned already. 523 * already in use. If it's in use it will have a busid assigned already.
521 */ 524 */
522 for (i = 0; i < DRM_MAX_MINOR; i++) { 525 for (i = 0; i < DRM_MAX_MINOR; i++) {
523 if ((fd = drmOpenMinor(i, 1)) >= 0) { 526 if ((fd = drmOpenMinor(i, 1, DRM_NODE_RENDER)) >= 0) {
524 if ((version = drmGetVersion(fd))) { 527 if ((version = drmGetVersion(fd))) {
525 if (!strcmp(version->name, name)) { 528 if (!strcmp(version->name, name)) {
526 drmFreeVersion(version); 529 drmFreeVersion(version);
@@ -564,7 +567,7 @@ static int drmOpenByName(const char *name)
564 if (*pt) { /* Found busid */ 567 if (*pt) { /* Found busid */
565 return drmOpenByBusid(++pt); 568 return drmOpenByBusid(++pt);
566 } else { /* No busid */ 569 } else { /* No busid */
567 return drmOpenDevice(strtol(devstring, NULL, 0),i); 570 return drmOpenDevice(strtol(devstring, NULL, 0),i, DRM_NODE_RENDER);
568 } 571 }
569 } 572 }
570 } 573 }
@@ -614,6 +617,10 @@ int drmOpen(const char *name, const char *busid)
614 return -1; 617 return -1;
615} 618}
616 619
620int drmOpenControl(int minor)
621{
622 return drmOpenMinor(minor, 0, DRM_NODE_CONTROL);
623}
617 624
618/** 625/**
619 * Free the version information returned by drmGetVersion(). 626 * Free the version information returned by drmGetVersion().
@@ -2434,3 +2441,20 @@ void drmCloseOnce(int fd)
2434 } 2441 }
2435 } 2442 }
2436} 2443}
2444
2445int drmSetMaster(int fd)
2446{
2447 int ret;
2448
2449 fprintf(stderr,"Setting master \n");
2450 ret = ioctl(fd, DRM_IOCTL_SET_MASTER, 0);
2451 return ret;
2452}
2453
2454int drmDropMaster(int fd)
2455{
2456 int ret;
2457 fprintf(stderr,"Dropping master \n");
2458 ret = ioctl(fd, DRM_IOCTL_DROP_MASTER, 0);
2459 return ret;
2460}
diff --git a/libdrm/xf86drm.h b/libdrm/xf86drm.h
index f4fa71b0..f9dd1bfc 100644
--- a/libdrm/xf86drm.h
+++ b/libdrm/xf86drm.h
@@ -49,6 +49,7 @@
49 49
50#define DRM_DIR_NAME "/dev/dri" 50#define DRM_DIR_NAME "/dev/dri"
51#define DRM_DEV_NAME "%s/card%d" 51#define DRM_DEV_NAME "%s/card%d"
52#define DRM_CONTROL_DEV_NAME "%s/controlD%d"
52#define DRM_PROC_NAME "/proc/dri/" /* For backward Linux compatibility */ 53#define DRM_PROC_NAME "/proc/dri/" /* For backward Linux compatibility */
53 54
54#define DRM_ERR_NO_DEVICE (-1001) 55#define DRM_ERR_NO_DEVICE (-1001)
@@ -74,6 +75,7 @@ typedef struct drmHashEntry {
74 void *tagTable; 75 void *tagTable;
75} drmHashEntry; 76} drmHashEntry;
76 77
78extern int drmIoctl(int fd, unsigned long request, void *arg);
77extern void *drmGetHashTable(void); 79extern void *drmGetHashTable(void);
78extern drmHashEntry *drmGetEntry(int fd); 80extern drmHashEntry *drmGetEntry(int fd);
79 81
@@ -508,6 +510,7 @@ do { register unsigned int __old __asm("o0"); \
508/* General user-level programmer's API: unprivileged */ 510/* General user-level programmer's API: unprivileged */
509extern int drmAvailable(void); 511extern int drmAvailable(void);
510extern int drmOpen(const char *name, const char *busid); 512extern int drmOpen(const char *name, const char *busid);
513extern int drmOpenControl(int minor);
511extern int drmClose(int fd); 514extern int drmClose(int fd);
512extern drmVersionPtr drmGetVersion(int fd); 515extern drmVersionPtr drmGetVersion(int fd);
513extern drmVersionPtr drmGetLibVersion(int fd); 516extern drmVersionPtr drmGetLibVersion(int fd);
@@ -659,4 +662,7 @@ extern int drmOpenOnce(void *unused, const char *BusID, int *newlyopened);
659extern void drmCloseOnce(int fd); 662extern void drmCloseOnce(int fd);
660extern void drmMsg(const char *format, ...); 663extern void drmMsg(const char *format, ...);
661 664
665extern int drmSetMaster(int fd);
666extern int drmDropMaster(int fd);
667
662#endif 668#endif
diff --git a/libdrm/xf86drmMode.c b/libdrm/xf86drmMode.c
new file mode 100644
index 00000000..f481428e
--- /dev/null
+++ b/libdrm/xf86drmMode.c
@@ -0,0 +1,686 @@
1/*
2 * \file xf86drmMode.c
3 * Header for DRM modesetting interface.
4 *
5 * \author Jakob Bornecrantz <wallbraker@gmail.com>
6 *
7 * \par Acknowledgements:
8 * Feb 2007, Dave Airlie <airlied@linux.ie>
9 */
10
11/*
12 * Copyright (c) 2007-2008 Tungsten Graphics, Inc., Cedar Park, Texas.
13 * Copyright (c) 2007-2008 Dave Airlie <airlied@linux.ie>
14 * Copyright (c) 2007-2008 Jakob Bornecrantz <wallbraker@gmail.com>
15 *
16 * Permission is hereby granted, free of charge, to any person obtaining a
17 * copy of this software and associated documentation files (the "Software"),
18 * to deal in the Software without restriction, including without limitation
19 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
20 * and/or sell copies of the Software, and to permit persons to whom the
21 * Software is furnished to do so, subject to the following conditions:
22 *
23 * The above copyright notice and this permission notice shall be included in
24 * all copies or substantial portions of the Software.
25 *
26 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
27 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
28 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
29 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
30 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
31 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
32 * IN THE SOFTWARE.
33 *
34 */
35
36/*
37 * TODO the types we are after are defined in diffrent headers on diffrent
38 * platforms find which headers to include to get uint32_t
39 */
40#include <stdint.h>
41#include <sys/ioctl.h>
42#include <stdio.h>
43
44#include "xf86drmMode.h"
45#include "xf86drm.h"
46#include <drm.h>
47#include <string.h>
48#include <dirent.h>
49#include <errno.h>
50
51#define U642VOID(x) ((void *)(unsigned long)(x))
52#define VOID2U64(x) ((uint64_t)(unsigned long)(x))
53
54/*
55 * Util functions
56 */
57
58void* drmAllocCpy(void *array, int count, int entry_size)
59{
60 char *r;
61 int i;
62
63 if (!count || !array || !entry_size)
64 return 0;
65
66 if (!(r = drmMalloc(count*entry_size)))
67 return 0;
68
69 for (i = 0; i < count; i++)
70 memcpy(r+(entry_size*i), array+(entry_size*i), entry_size);
71
72 return r;
73}
74
75/*
76 * A couple of free functions.
77 */
78
79void drmModeFreeModeInfo(struct drm_mode_modeinfo *ptr)
80{
81 if (!ptr)
82 return;
83
84 drmFree(ptr);
85}
86
87void drmModeFreeResources(drmModeResPtr ptr)
88{
89 if (!ptr)
90 return;
91
92 drmFree(ptr);
93
94}
95
96void drmModeFreeFB(drmModeFBPtr ptr)
97{
98 if (!ptr)
99 return;
100
101 /* we might add more frees later. */
102 drmFree(ptr);
103}
104
105void drmModeFreeCrtc(drmModeCrtcPtr ptr)
106{
107 if (!ptr)
108 return;
109
110 drmFree(ptr);
111
112}
113
114void drmModeFreeConnector(drmModeConnectorPtr ptr)
115{
116 if (!ptr)
117 return;
118
119 drmFree(ptr->modes);
120 drmFree(ptr);
121
122}
123
124void drmModeFreeEncoder(drmModeEncoderPtr ptr)
125{
126 drmFree(ptr);
127}
128
129/*
130 * ModeSetting functions.
131 */
132
133drmModeResPtr drmModeGetResources(int fd)
134{
135 struct drm_mode_card_res res;
136 drmModeResPtr r = 0;
137
138 memset(&res, 0, sizeof(struct drm_mode_card_res));
139
140 if (drmIoctl(fd, DRM_IOCTL_MODE_GETRESOURCES, &res))
141 return 0;
142
143 if (res.count_fbs)
144 res.fb_id_ptr = VOID2U64(drmMalloc(res.count_fbs*sizeof(uint32_t)));
145 if (res.count_crtcs)
146 res.crtc_id_ptr = VOID2U64(drmMalloc(res.count_crtcs*sizeof(uint32_t)));
147 if (res.count_connectors)
148 res.connector_id_ptr = VOID2U64(drmMalloc(res.count_connectors*sizeof(uint32_t)));
149 if (res.count_encoders)
150 res.encoder_id_ptr = VOID2U64(drmMalloc(res.count_encoders*sizeof(uint32_t)));
151
152 if (drmIoctl(fd, DRM_IOCTL_MODE_GETRESOURCES, &res)) {
153 r = NULL;
154 goto err_allocs;
155 }
156
157 /*
158 * return
159 */
160
161
162 if (!(r = drmMalloc(sizeof(*r))))
163 return 0;
164
165 r->min_width = res.min_width;
166 r->max_width = res.max_width;
167 r->min_height = res.min_height;
168 r->max_height = res.max_height;
169 r->count_fbs = res.count_fbs;
170 r->count_crtcs = res.count_crtcs;
171 r->count_connectors = res.count_connectors;
172 r->count_encoders = res.count_encoders;
173 /* TODO we realy should test if these allocs fails. */
174 r->fbs = drmAllocCpy(U642VOID(res.fb_id_ptr), res.count_fbs, sizeof(uint32_t));
175 r->crtcs = drmAllocCpy(U642VOID(res.crtc_id_ptr), res.count_crtcs, sizeof(uint32_t));
176 r->connectors = drmAllocCpy(U642VOID(res.connector_id_ptr), res.count_connectors, sizeof(uint32_t));
177 r->encoders = drmAllocCpy(U642VOID(res.encoder_id_ptr), res.count_encoders, sizeof(uint32_t));
178
179err_allocs:
180 drmFree(U642VOID(res.fb_id_ptr));
181 drmFree(U642VOID(res.crtc_id_ptr));
182 drmFree(U642VOID(res.connector_id_ptr));
183 drmFree(U642VOID(res.encoder_id_ptr));
184
185 return r;
186}
187
188int drmModeAddFB(int fd, uint32_t width, uint32_t height, uint8_t depth,
189 uint8_t bpp, uint32_t pitch, uint32_t bo_handle,
190 uint32_t *buf_id)
191{
192 struct drm_mode_fb_cmd f;
193 int ret;
194
195 f.width = width;
196 f.height = height;
197 f.pitch = pitch;
198 f.bpp = bpp;
199 f.depth = depth;
200 f.handle = bo_handle;
201
202 if ((ret = drmIoctl(fd, DRM_IOCTL_MODE_ADDFB, &f)))
203 return ret;
204
205 *buf_id = f.fb_id;
206 return 0;
207}
208
209int drmModeRmFB(int fd, uint32_t bufferId)
210{
211 return drmIoctl(fd, DRM_IOCTL_MODE_RMFB, &bufferId);
212
213
214}
215
216drmModeFBPtr drmModeGetFB(int fd, uint32_t buf)
217{
218 struct drm_mode_fb_cmd info;
219 drmModeFBPtr r;
220
221 info.fb_id = buf;
222
223 if (drmIoctl(fd, DRM_IOCTL_MODE_GETFB, &info))
224 return NULL;
225
226 if (!(r = drmMalloc(sizeof(*r))))
227 return NULL;
228
229 r->fb_id = info.fb_id;
230 r->width = info.width;
231 r->height = info.height;
232 r->pitch = info.pitch;
233 r->bpp = info.bpp;
234 r->handle = info.handle;
235 r->depth = info.depth;
236
237 return r;
238}
239
240
241/*
242 * Crtc functions
243 */
244
245drmModeCrtcPtr drmModeGetCrtc(int fd, uint32_t crtcId)
246{
247 struct drm_mode_crtc crtc;
248 drmModeCrtcPtr r;
249
250 crtc.crtc_id = crtcId;
251
252 if (drmIoctl(fd, DRM_IOCTL_MODE_GETCRTC, &crtc))
253 return 0;
254
255 /*
256 * return
257 */
258
259 if (!(r = drmMalloc(sizeof(*r))))
260 return 0;
261
262 r->crtc_id = crtc.crtc_id;
263 r->x = crtc.x;
264 r->y = crtc.y;
265 r->mode_valid = crtc.mode_valid;
266 if (r->mode_valid)
267 memcpy(&r->mode, &crtc.mode, sizeof(struct drm_mode_modeinfo));
268 r->buffer_id = crtc.fb_id;
269 r->gamma_size = crtc.gamma_size;
270 return r;
271}
272
273
274int drmModeSetCrtc(int fd, uint32_t crtcId, uint32_t bufferId,
275 uint32_t x, uint32_t y, uint32_t *connectors, int count,
276 struct drm_mode_modeinfo *mode)
277{
278 struct drm_mode_crtc crtc;
279
280 crtc.x = x;
281 crtc.y = y;
282 crtc.crtc_id = crtcId;
283 crtc.fb_id = bufferId;
284 crtc.set_connectors_ptr = VOID2U64(connectors);
285 crtc.count_connectors = count;
286 if (mode) {
287 memcpy(&crtc.mode, mode, sizeof(struct drm_mode_modeinfo));
288 crtc.mode_valid = 1;
289 } else
290 crtc.mode_valid = 0;
291
292 return drmIoctl(fd, DRM_IOCTL_MODE_SETCRTC, &crtc);
293}
294
295/*
296 * Cursor manipulation
297 */
298
299int drmModeSetCursor(int fd, uint32_t crtcId, uint32_t bo_handle, uint32_t width, uint32_t height)
300{
301 struct drm_mode_cursor arg;
302
303 arg.flags = DRM_MODE_CURSOR_BO;
304 arg.crtc_id = crtcId;
305 arg.width = width;
306 arg.height = height;
307 arg.handle = bo_handle;
308
309 return drmIoctl(fd, DRM_IOCTL_MODE_CURSOR, &arg);
310}
311
312int drmModeMoveCursor(int fd, uint32_t crtcId, int x, int y)
313{
314 struct drm_mode_cursor arg;
315
316 arg.flags = DRM_MODE_CURSOR_MOVE;
317 arg.crtc_id = crtcId;
318 arg.x = x;
319 arg.y = y;
320
321 return drmIoctl(fd, DRM_IOCTL_MODE_CURSOR, &arg);
322}
323
324/*
325 * Encoder get
326 */
327drmModeEncoderPtr drmModeGetEncoder(int fd, uint32_t encoder_id)
328{
329 struct drm_mode_get_encoder enc;
330 drmModeEncoderPtr r = NULL;
331
332 enc.encoder_id = encoder_id;
333 enc.encoder_type = 0;
334 enc.possible_crtcs = 0;
335 enc.possible_clones = 0;
336
337 if (drmIoctl(fd, DRM_IOCTL_MODE_GETENCODER, &enc))
338 return 0;
339
340 if (!(r = drmMalloc(sizeof(*r))))
341 return 0;
342
343 r->encoder_id = enc.encoder_id;
344 r->crtc_id = enc.crtc_id;
345 r->encoder_type = enc.encoder_type;
346 r->possible_crtcs = enc.possible_crtcs;
347 r->possible_clones = enc.possible_clones;
348
349 return r;
350}
351
352/*
353 * Connector manipulation
354 */
355
356drmModeConnectorPtr drmModeGetConnector(int fd, uint32_t connector_id)
357{
358 struct drm_mode_get_connector conn;
359 drmModeConnectorPtr r = NULL;
360
361 conn.connector_id = connector_id;
362 conn.connector_type_id = 0;
363 conn.connector_type = 0;
364 conn.count_modes = 0;
365 conn.modes_ptr = 0;
366 conn.count_props = 0;
367 conn.props_ptr = 0;
368 conn.prop_values_ptr = 0;
369 conn.count_encoders = 0;
370 conn.encoders_ptr = 0;
371
372 if (drmIoctl(fd, DRM_IOCTL_MODE_GETCONNECTOR, &conn))
373 return 0;
374
375 if (conn.count_props) {
376 conn.props_ptr = VOID2U64(drmMalloc(conn.count_props*sizeof(uint32_t)));
377 conn.prop_values_ptr = VOID2U64(drmMalloc(conn.count_props*sizeof(uint64_t)));
378 }
379
380 if (conn.count_modes)
381 conn.modes_ptr = VOID2U64(drmMalloc(conn.count_modes*sizeof(struct drm_mode_modeinfo)));
382
383 if (conn.count_encoders)
384 conn.encoders_ptr = VOID2U64(drmMalloc(conn.count_encoders*sizeof(uint32_t)));
385
386 if (drmIoctl(fd, DRM_IOCTL_MODE_GETCONNECTOR, &conn))
387 goto err_allocs;
388
389 if(!(r = drmMalloc(sizeof(*r)))) {
390 goto err_allocs;
391 }
392
393 r->connector_id = conn.connector_id;
394 r->encoder_id = conn.encoder_id;
395 r->connection = conn.connection;
396 r->mmWidth = conn.mm_width;
397 r->mmHeight = conn.mm_height;
398 r->subpixel = conn.subpixel;
399 r->count_modes = conn.count_modes;
400 /* TODO we should test if these alloc & cpy fails. */
401 r->count_props = conn.count_props;
402 r->props = drmAllocCpy(U642VOID(conn.props_ptr), conn.count_props, sizeof(uint32_t));
403 r->prop_values = drmAllocCpy(U642VOID(conn.prop_values_ptr), conn.count_props, sizeof(uint64_t));
404 r->modes = drmAllocCpy(U642VOID(conn.modes_ptr), conn.count_modes, sizeof(struct drm_mode_modeinfo));
405 r->count_encoders = conn.count_encoders;
406 r->encoders = drmAllocCpy(U642VOID(conn.encoders_ptr), conn.count_encoders, sizeof(uint32_t));
407 r->connector_type = conn.connector_type;
408 r->connector_type_id = conn.connector_type_id;
409
410 if (!r->props || !r->prop_values || !r->modes || !r->encoders)
411 goto err_allocs;
412
413err_allocs:
414 drmFree(U642VOID(conn.prop_values_ptr));
415 drmFree(U642VOID(conn.props_ptr));
416 drmFree(U642VOID(conn.modes_ptr));
417 drmFree(U642VOID(conn.encoders_ptr));
418
419 return r;
420}
421
422int drmModeAttachMode(int fd, uint32_t connector_id, struct drm_mode_modeinfo *mode_info)
423{
424 struct drm_mode_mode_cmd res;
425
426 memcpy(&res.mode, mode_info, sizeof(struct drm_mode_modeinfo));
427 res.connector_id = connector_id;
428
429 return drmIoctl(fd, DRM_IOCTL_MODE_ATTACHMODE, &res);
430}
431
432int drmModeDetachMode(int fd, uint32_t connector_id, struct drm_mode_modeinfo *mode_info)
433{
434 struct drm_mode_mode_cmd res;
435
436 memcpy(&res.mode, mode_info, sizeof(struct drm_mode_modeinfo));
437 res.connector_id = connector_id;
438
439 return drmIoctl(fd, DRM_IOCTL_MODE_DETACHMODE, &res);
440}
441
442
443drmModePropertyPtr drmModeGetProperty(int fd, uint32_t property_id)
444{
445 struct drm_mode_get_property prop;
446 drmModePropertyPtr r;
447
448 prop.prop_id = property_id;
449 prop.count_enum_blobs = 0;
450 prop.count_values = 0;
451 prop.flags = 0;
452 prop.enum_blob_ptr = 0;
453 prop.values_ptr = 0;
454
455 if (drmIoctl(fd, DRM_IOCTL_MODE_GETPROPERTY, &prop))
456 return 0;
457
458 if (prop.count_values)
459 prop.values_ptr = VOID2U64(drmMalloc(prop.count_values * sizeof(uint64_t)));
460
461 if (prop.count_enum_blobs && (prop.flags & DRM_MODE_PROP_ENUM))
462 prop.enum_blob_ptr = VOID2U64(drmMalloc(prop.count_enum_blobs * sizeof(struct drm_mode_property_enum)));
463
464 if (prop.count_enum_blobs && (prop.flags & DRM_MODE_PROP_BLOB)) {
465 prop.values_ptr = VOID2U64(drmMalloc(prop.count_enum_blobs * sizeof(uint32_t)));
466 prop.enum_blob_ptr = VOID2U64(drmMalloc(prop.count_enum_blobs * sizeof(uint32_t)));
467 }
468
469 if (drmIoctl(fd, DRM_IOCTL_MODE_GETPROPERTY, &prop)) {
470 r = NULL;
471 goto err_allocs;
472 }
473
474 if (!(r = drmMalloc(sizeof(*r))))
475 return NULL;
476
477 r->prop_id = prop.prop_id;
478 r->count_values = prop.count_values;
479
480 r->flags = prop.flags;
481 if (prop.count_values)
482 r->values = drmAllocCpy(U642VOID(prop.values_ptr), prop.count_values, sizeof(uint64_t));
483 if (prop.flags & DRM_MODE_PROP_ENUM) {
484 r->count_enums = prop.count_enum_blobs;
485 r->enums = drmAllocCpy(U642VOID(prop.enum_blob_ptr), prop.count_enum_blobs, sizeof(struct drm_mode_property_enum));
486 } else if (prop.flags & DRM_MODE_PROP_BLOB) {
487 r->values = drmAllocCpy(U642VOID(prop.values_ptr), prop.count_enum_blobs, sizeof(uint32_t));
488 r->blob_ids = drmAllocCpy(U642VOID(prop.enum_blob_ptr), prop.count_enum_blobs, sizeof(uint32_t));
489 r->count_blobs = prop.count_enum_blobs;
490 }
491 strncpy(r->name, prop.name, DRM_PROP_NAME_LEN);
492 r->name[DRM_PROP_NAME_LEN-1] = 0;
493
494err_allocs:
495 drmFree(U642VOID(prop.values_ptr));
496 drmFree(U642VOID(prop.enum_blob_ptr));
497
498 return r;
499}
500
501void drmModeFreeProperty(drmModePropertyPtr ptr)
502{
503 if (!ptr)
504 return;
505
506 drmFree(ptr->values);
507 drmFree(ptr->enums);
508 drmFree(ptr);
509}
510
511drmModePropertyBlobPtr drmModeGetPropertyBlob(int fd, uint32_t blob_id)
512{
513 struct drm_mode_get_blob blob;
514 drmModePropertyBlobPtr r;
515
516 blob.length = 0;
517 blob.data = 0;
518 blob.blob_id = blob_id;
519
520 if (drmIoctl(fd, DRM_IOCTL_MODE_GETPROPBLOB, &blob))
521 return NULL;
522
523 if (blob.length)
524 blob.data = VOID2U64(drmMalloc(blob.length));
525
526 if (drmIoctl(fd, DRM_IOCTL_MODE_GETPROPBLOB, &blob)) {
527 r = NULL;
528 goto err_allocs;
529 }
530
531 if (!(r = drmMalloc(sizeof(*r))))
532 return NULL;
533
534 r->id = blob.blob_id;
535 r->length = blob.length;
536 r->data = drmAllocCpy(U642VOID(blob.data), 1, blob.length);
537
538err_allocs:
539 drmFree(U642VOID(blob.data));
540 return r;
541}
542
543void drmModeFreePropertyBlob(drmModePropertyBlobPtr ptr)
544{
545 if (!ptr)
546 return;
547
548 drmFree(ptr->data);
549 drmFree(ptr);
550}
551
552int drmModeConnectorSetProperty(int fd, uint32_t connector_id, uint32_t property_id,
553 uint64_t value)
554{
555 struct drm_mode_connector_set_property osp;
556 int ret;
557
558 osp.connector_id = connector_id;
559 osp.prop_id = property_id;
560 osp.value = value;
561
562 if ((ret = drmIoctl(fd, DRM_IOCTL_MODE_SETPROPERTY, &osp)))
563 return ret;
564
565 return 0;
566}
567
568/*
569 * checks if a modesetting capable driver has attached to the pci id
570 * returns 0 if modesetting supported.
571 * -EINVAL or invalid bus id
572 * -ENOSYS if no modesetting support
573*/
574int drmCheckModesettingSupported(const char *busid)
575{
576#ifdef __linux__
577 char pci_dev_dir[1024];
578 int domain, bus, dev, func;
579 DIR *sysdir;
580 struct dirent *dent;
581 int found = 0, ret;
582
583 ret = sscanf(busid, "pci:%04x:%02x:%02x.%d", &domain, &bus, &dev, &func);
584 if (ret != 4)
585 return -EINVAL;
586
587 sprintf(pci_dev_dir, "/sys/bus/pci/devices/%04x:%02x:%02x.%d/drm",
588 domain, bus, dev, func);
589
590 sysdir = opendir(pci_dev_dir);
591 if (sysdir) {
592 dent = readdir(sysdir);
593 while (dent) {
594 if (!strncmp(dent->d_name, "controlD", 8)) {
595 found = 1;
596 break;
597 }
598
599 dent = readdir(sysdir);
600 }
601 closedir(sysdir);
602 if (found)
603 return 0;
604 }
605
606 sprintf(pci_dev_dir, "/sys/bus/pci/devices/%04x:%02x:%02x.%d/",
607 domain, bus, dev, func);
608
609 sysdir = opendir(pci_dev_dir);
610 if (!sysdir)
611 return -EINVAL;
612
613 dent = readdir(sysdir);
614 while (dent) {
615 if (!strncmp(dent->d_name, "drm:controlD", 12)) {
616 found = 1;
617 break;
618 }
619
620 dent = readdir(sysdir);
621 }
622
623 closedir(sysdir);
624 if (found)
625 return 0;
626#endif
627 return -ENOSYS;
628
629}
630
631int drmModeReplaceFB(int fd, uint32_t buffer_id,
632 uint32_t width, uint32_t height, uint8_t depth,
633 uint8_t bpp, uint32_t pitch, uint32_t bo_handle)
634{
635 struct drm_mode_fb_cmd f;
636 int ret;
637
638 f.width = width;
639 f.height = height;
640 f.pitch = pitch;
641 f.bpp = bpp;
642 f.depth = depth;
643 f.handle = bo_handle;
644 f.fb_id = buffer_id;
645
646 if ((ret = drmIoctl(fd, DRM_IOCTL_MODE_REPLACEFB, &f)))
647 return ret;
648
649 return 0;
650}
651
652int drmModeCrtcGetGamma(int fd, uint32_t crtc_id, uint32_t size,
653 uint16_t *red, uint16_t *green, uint16_t *blue)
654{
655 int ret;
656 struct drm_mode_crtc_lut l;
657
658 l.crtc_id = crtc_id;
659 l.gamma_size = size;
660 l.red = VOID2U64(red);
661 l.green = VOID2U64(green);
662 l.blue = VOID2U64(blue);
663
664 if ((ret = drmIoctl(fd, DRM_IOCTL_MODE_GETGAMMA, &l)))
665 return ret;
666
667 return 0;
668}
669
670int drmModeCrtcSetGamma(int fd, uint32_t crtc_id, uint32_t size,
671 uint16_t *red, uint16_t *green, uint16_t *blue)
672{
673 int ret;
674 struct drm_mode_crtc_lut l;
675
676 l.crtc_id = crtc_id;
677 l.gamma_size = size;
678 l.red = VOID2U64(red);
679 l.green = VOID2U64(green);
680 l.blue = VOID2U64(blue);
681
682 if ((ret = drmIoctl(fd, DRM_IOCTL_MODE_SETGAMMA, &l)))
683 return ret;
684
685 return 0;
686}
diff --git a/libdrm/xf86drmMode.h b/libdrm/xf86drmMode.h
new file mode 100644
index 00000000..965b7be9
--- /dev/null
+++ b/libdrm/xf86drmMode.h
@@ -0,0 +1,258 @@
1/*
2 * \file xf86drmMode.h
3 * Header for DRM modesetting interface.
4 *
5 * \author Jakob Bornecrantz <wallbraker@gmail.com>
6 *
7 * \par Acknowledgements:
8 * Feb 2007, Dave Airlie <airlied@linux.ie>
9 */
10
11/*
12 * Copyright (c) 2007-2008 Tungsten Graphics, Inc., Cedar Park, Texas.
13 * Copyright (c) 2007-2008 Dave Airlie <airlied@linux.ie>
14 * Copyright (c) 2007-2008 Jakob Bornecrantz <wallbraker@gmail.com>
15 *
16 * Permission is hereby granted, free of charge, to any person obtaining a
17 * copy of this software and associated documentation files (the "Software"),
18 * to deal in the Software without restriction, including without limitation
19 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
20 * and/or sell copies of the Software, and to permit persons to whom the
21 * Software is furnished to do so, subject to the following conditions:
22 *
23 * The above copyright notice and this permission notice shall be included in
24 * all copies or substantial portions of the Software.
25 *
26 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
27 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
28 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
29 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
30 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
31 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
32 * IN THE SOFTWARE.
33 *
34 */
35
36#include <drm.h>
37
38/*
39 * This is the interface for modesetting for drm.
40 *
41 * In order to use this interface you must include either <stdint.h> or another
42 * header defining uint32_t, int32_t and uint16_t.
43 *
44 * It aims to provide a randr1.2 compatible interface for modesettings in the
45 * kernel, the interface is also ment to be used by libraries like EGL.
46 *
47 * More information can be found in randrproto.txt which can be found here:
48 * http://gitweb.freedesktop.org/?p=xorg/proto/randrproto.git
49 *
50 * There are some major diffrences to be noted. Unlike the randr1.2 proto you
51 * need to create the memory object of the framebuffer yourself with the ttm
52 * buffer object interface. This object needs to be pinned.
53 */
54
55typedef struct _drmModeRes {
56
57 int count_fbs;
58 uint32_t *fbs;
59
60 int count_crtcs;
61 uint32_t *crtcs;
62
63 int count_connectors;
64 uint32_t *connectors;
65
66 int count_encoders;
67 uint32_t *encoders;
68
69 uint32_t min_width, max_width;
70 uint32_t min_height, max_height;
71} drmModeRes, *drmModeResPtr;
72
73typedef struct drm_mode_fb_cmd drmModeFB, *drmModeFBPtr;
74
75typedef struct _drmModePropertyBlob {
76 uint32_t id;
77 uint32_t length;
78 void *data;
79} drmModePropertyBlobRes, *drmModePropertyBlobPtr;
80
81typedef struct _drmModeProperty {
82 uint32_t prop_id;
83 uint32_t flags;
84 char name[DRM_PROP_NAME_LEN];
85 int count_values;
86 uint64_t *values; // store the blob lengths
87 int count_enums;
88 struct drm_mode_property_enum *enums;
89 int count_blobs;
90 uint32_t *blob_ids; // store the blob IDs
91} drmModePropertyRes, *drmModePropertyPtr;
92
93typedef struct _drmModeCrtc {
94 uint32_t crtc_id;
95 uint32_t buffer_id; /**< FB id to connect to 0 = disconnect */
96
97 uint32_t x, y; /**< Position on the framebuffer */
98 uint32_t width, height;
99 int mode_valid;
100 struct drm_mode_modeinfo mode;
101
102 int gamma_size; /**< Number of gamma stops */
103
104} drmModeCrtc, *drmModeCrtcPtr;
105
106typedef struct _drmModeEncoder {
107 uint32_t encoder_id;
108 uint32_t encoder_type;
109 uint32_t crtc_id;
110 uint32_t possible_crtcs;
111 uint32_t possible_clones;
112} drmModeEncoder, *drmModeEncoderPtr;
113
114typedef enum {
115 DRM_MODE_CONNECTED = 1,
116 DRM_MODE_DISCONNECTED = 2,
117 DRM_MODE_UNKNOWNCONNECTION = 3
118} drmModeConnection;
119
120typedef enum {
121 DRM_MODE_SUBPIXEL_UNKNOWN = 1,
122 DRM_MODE_SUBPIXEL_HORIZONTAL_RGB = 2,
123 DRM_MODE_SUBPIXEL_HORIZONTAL_BGR = 3,
124 DRM_MODE_SUBPIXEL_VERTICAL_RGB = 4,
125 DRM_MODE_SUBPIXEL_VERTICAL_BGR = 5,
126 DRM_MODE_SUBPIXEL_NONE = 6
127} drmModeSubPixel;
128
129typedef struct _drmModeConnector {
130 uint32_t connector_id;
131 uint32_t encoder_id; /**< Encoder currently connected to */
132 uint32_t connector_type;
133 uint32_t connector_type_id;
134 drmModeConnection connection;
135 uint32_t mmWidth, mmHeight; /**< HxW in millimeters */
136 drmModeSubPixel subpixel;
137
138 int count_modes;
139 struct drm_mode_modeinfo *modes;
140
141 int count_props;
142 uint32_t *props; /**< List of property ids */
143 uint64_t *prop_values; /**< List of property values */
144
145 int count_encoders;
146 uint32_t *encoders; /**< List of encoder ids */
147} drmModeConnector, *drmModeConnectorPtr;
148
149
150
151extern void drmModeFreeModeInfo( struct drm_mode_modeinfo *ptr );
152extern void drmModeFreeResources( drmModeResPtr ptr );
153extern void drmModeFreeFB( drmModeFBPtr ptr );
154extern void drmModeFreeCrtc( drmModeCrtcPtr ptr );
155extern void drmModeFreeConnector( drmModeConnectorPtr ptr );
156extern void drmModeFreeEncoder( drmModeEncoderPtr ptr );
157
158/**
159 * Retrives all of the resources associated with a card.
160 */
161extern drmModeResPtr drmModeGetResources(int fd);
162
163/*
164 * FrameBuffer manipulation.
165 */
166
167/**
168 * Retrive information about framebuffer bufferId
169 */
170extern drmModeFBPtr drmModeGetFB(int fd, uint32_t bufferId);
171
172/**
173 * Creates a new framebuffer with an buffer object as its scanout buffer.
174 */
175extern int drmModeAddFB(int fd, uint32_t width, uint32_t height, uint8_t depth,
176 uint8_t bpp, uint32_t pitch, uint32_t bo_handle,
177 uint32_t *buf_id);
178/**
179 * Destroies the given framebuffer.
180 */
181extern int drmModeRmFB(int fd, uint32_t bufferId);
182
183/**
184 * Replace a framebuffer object with a new one - for resizing the screen.
185 */
186extern int drmModeReplaceFB(int fd, uint32_t buffer_id,
187 uint32_t width, uint32_t height, uint8_t depth,
188 uint8_t bpp, uint32_t pitch, uint32_t bo_handle);
189
190/*
191 * Crtc functions
192 */
193
194/**
195 * Retrive information about the ctrt crtcId
196 */
197extern drmModeCrtcPtr drmModeGetCrtc(int fd, uint32_t crtcId);
198
199/**
200 * Set the mode on a crtc crtcId with the given mode modeId.
201 */
202int drmModeSetCrtc(int fd, uint32_t crtcId, uint32_t bufferId,
203 uint32_t x, uint32_t y, uint32_t *connectors, int count,
204 struct drm_mode_modeinfo *mode);
205
206/*
207 * Cursor functions
208 */
209
210/**
211 * Set the cursor on crtc
212 */
213int drmModeSetCursor(int fd, uint32_t crtcId, uint32_t bo_handle, uint32_t width, uint32_t height);
214
215/**
216 * Move the cursor on crtc
217 */
218int drmModeMoveCursor(int fd, uint32_t crtcId, int x, int y);
219
220/**
221 * Encoder functions
222 */
223drmModeEncoderPtr drmModeGetEncoder(int fd, uint32_t encoder_id);
224
225/*
226 * Connector manipulation
227 */
228
229/**
230 * Retrive information about the connector connectorId.
231 */
232extern drmModeConnectorPtr drmModeGetConnector(int fd,
233 uint32_t connectorId);
234
235/**
236 * Attaches the given mode to an connector.
237 */
238extern int drmModeAttachMode(int fd, uint32_t connectorId, struct drm_mode_modeinfo *mode_info);
239
240/**
241 * Detaches a mode from the connector
242 * must be unused, by the given mode.
243 */
244extern int drmModeDetachMode(int fd, uint32_t connectorId, struct drm_mode_modeinfo *mode_info);
245
246extern drmModePropertyPtr drmModeGetProperty(int fd, uint32_t propertyId);
247extern void drmModeFreeProperty(drmModePropertyPtr ptr);
248
249extern drmModePropertyBlobPtr drmModeGetPropertyBlob(int fd, uint32_t blob_id);
250extern void drmModeFreePropertyBlob(drmModePropertyBlobPtr ptr);
251extern int drmModeConnectorSetProperty(int fd, uint32_t connector_id, uint32_t property_id,
252 uint64_t value);
253extern int drmCheckModesettingSupported(const char *busid);
254
255extern int drmModeCrtcSetGamma(int fd, uint32_t crtc_id, uint32_t size,
256 uint16_t *red, uint16_t *green, uint16_t *blue);
257extern int drmModeCrtcGetGamma(int fd, uint32_t crtc_id, uint32_t size,
258 uint16_t *red, uint16_t *green, uint16_t *blue);
diff --git a/linux-core/drm_mode.h b/linux-core/drm_mode.h
new file mode 120000
index 00000000..a43f1385
--- /dev/null
+++ b/linux-core/drm_mode.h
@@ -0,0 +1 @@
../shared-core/drm_mode.h \ No newline at end of file
diff --git a/shared-core/Makefile.am b/shared-core/Makefile.am
index 7193e527..99e90d64 100644
--- a/shared-core/Makefile.am
+++ b/shared-core/Makefile.am
@@ -25,6 +25,7 @@
25klibdrmincludedir = ${includedir}/drm 25klibdrmincludedir = ${includedir}/drm
26klibdrminclude_HEADERS = \ 26klibdrminclude_HEADERS = \
27 drm.h \ 27 drm.h \
28 drm_mode.h \
28 drm_sarea.h \ 29 drm_sarea.h \
29 i915_drm.h \ 30 i915_drm.h \
30 mach64_drm.h \ 31 mach64_drm.h \
diff --git a/shared-core/drm.h b/shared-core/drm.h
index 507f0478..b97ba098 100644
--- a/shared-core/drm.h
+++ b/shared-core/drm.h
@@ -985,6 +985,8 @@ struct drm_gem_open {
985 uint64_t size; 985 uint64_t size;
986}; 986};
987 987
988#include "drm_mode.h"
989
988/** 990/**
989 * \name Ioctls Definitions 991 * \name Ioctls Definitions
990 */ 992 */
@@ -1027,6 +1029,9 @@ struct drm_gem_open {
1027#define DRM_IOCTL_SET_SAREA_CTX DRM_IOW( 0x1c, struct drm_ctx_priv_map) 1029#define DRM_IOCTL_SET_SAREA_CTX DRM_IOW( 0x1c, struct drm_ctx_priv_map)
1028#define DRM_IOCTL_GET_SAREA_CTX DRM_IOWR(0x1d, struct drm_ctx_priv_map) 1030#define DRM_IOCTL_GET_SAREA_CTX DRM_IOWR(0x1d, struct drm_ctx_priv_map)
1029 1031
1032#define DRM_IOCTL_SET_MASTER DRM_IO(0x1e)
1033#define DRM_IOCTL_DROP_MASTER DRM_IO(0x1f)
1034
1030#define DRM_IOCTL_ADD_CTX DRM_IOWR(0x20, struct drm_ctx) 1035#define DRM_IOCTL_ADD_CTX DRM_IOWR(0x20, struct drm_ctx)
1031#define DRM_IOCTL_RM_CTX DRM_IOWR(0x21, struct drm_ctx) 1036#define DRM_IOCTL_RM_CTX DRM_IOWR(0x21, struct drm_ctx)
1032#define DRM_IOCTL_MOD_CTX DRM_IOW( 0x22, struct drm_ctx) 1037#define DRM_IOCTL_MOD_CTX DRM_IOW( 0x22, struct drm_ctx)
@@ -1082,6 +1087,28 @@ struct drm_gem_open {
1082#define DRM_IOCTL_BO_VERSION DRM_IOR(0xd6, struct drm_bo_version_arg) 1087#define DRM_IOCTL_BO_VERSION DRM_IOR(0xd6, struct drm_bo_version_arg)
1083#define DRM_IOCTL_MM_INFO DRM_IOWR(0xd7, struct drm_mm_info_arg) 1088#define DRM_IOCTL_MM_INFO DRM_IOWR(0xd7, struct drm_mm_info_arg)
1084 1089
1090#define DRM_IOCTL_MODE_GETRESOURCES DRM_IOWR(0xA0, struct drm_mode_card_res)
1091
1092#define DRM_IOCTL_MODE_GETCRTC DRM_IOWR(0xA1, struct drm_mode_crtc)
1093#define DRM_IOCTL_MODE_SETCRTC DRM_IOWR(0xA2, struct drm_mode_crtc)
1094#define DRM_IOCTL_MODE_CURSOR DRM_IOWR(0xA3, struct drm_mode_cursor)
1095#define DRM_IOCTL_MODE_GETGAMMA DRM_IOWR(0xA4, struct drm_mode_crtc_lut)
1096#define DRM_IOCTL_MODE_SETGAMMA DRM_IOWR(0xA5, struct drm_mode_crtc_lut)
1097
1098#define DRM_IOCTL_MODE_GETENCODER DRM_IOWR(0xA6, struct drm_mode_get_encoder)
1099
1100#define DRM_IOCTL_MODE_GETCONNECTOR DRM_IOWR(0xA7, struct drm_mode_get_connector)
1101#define DRM_IOCTL_MODE_ATTACHMODE DRM_IOWR(0xA8, struct drm_mode_mode_cmd)
1102#define DRM_IOCTL_MODE_DETACHMODE DRM_IOWR(0xA9, struct drm_mode_mode_cmd)
1103#define DRM_IOCTL_MODE_GETPROPERTY DRM_IOWR(0xAA, struct drm_mode_get_property)
1104#define DRM_IOCTL_MODE_SETPROPERTY DRM_IOWR(0xAB, struct drm_mode_connector_set_property)
1105#define DRM_IOCTL_MODE_GETPROPBLOB DRM_IOWR(0xAC, struct drm_mode_get_blob)
1106
1107#define DRM_IOCTL_MODE_GETFB DRM_IOWR(0xAD, struct drm_mode_fb_cmd)
1108#define DRM_IOCTL_MODE_ADDFB DRM_IOWR(0xAE, struct drm_mode_fb_cmd)
1109#define DRM_IOCTL_MODE_RMFB DRM_IOWR(0xAF, uint32_t)
1110#define DRM_IOCTL_MODE_REPLACEFB DRM_IOWR(0xB0, struct drm_mode_fb_cmd)
1111
1085/*@}*/ 1112/*@}*/
1086 1113
1087/** 1114/**
diff --git a/shared-core/drm_mode.h b/shared-core/drm_mode.h
new file mode 100644
index 00000000..601d2bd8
--- /dev/null
+++ b/shared-core/drm_mode.h
@@ -0,0 +1,271 @@
1/*
2 * Copyright (c) 2007 Dave Airlie <airlied@linux.ie>
3 * Copyright (c) 2007 Jakob Bornecrantz <wallbraker@gmail.com>
4 * Copyright (c) 2008 Red Hat Inc.
5 * Copyright (c) 2007-2008 Tungsten Graphics, Inc., Cedar Park, TX., USA
6 * Copyright (c) 2007-2008 Intel Corporation
7 *
8 * Permission is hereby granted, free of charge, to any person obtaining a
9 * copy of this software and associated documentation files (the "Software"),
10 * to deal in the Software without restriction, including without limitation
11 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12 * and/or sell copies of the Software, and to permit persons to whom the
13 * Software is furnished to do so, subject to the following conditions:
14 *
15 * The above copyright notice and this permission notice shall be included in
16 * all copies or substantial portions of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
23 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
24 * IN THE SOFTWARE.
25 */
26
27#ifndef _DRM_MODE_H
28#define _DRM_MODE_H
29
30#if !defined(__KERNEL__) && !defined(_KERNEL)
31#include <stdint.h>
32#else
33#include <linux/kernel.h>
34#endif
35
36#define DRM_DISPLAY_INFO_LEN 32
37#define DRM_CONNECTOR_NAME_LEN 32
38#define DRM_DISPLAY_MODE_LEN 32
39#define DRM_PROP_NAME_LEN 32
40
41#define DRM_MODE_TYPE_BUILTIN (1<<0)
42#define DRM_MODE_TYPE_CLOCK_C ((1<<1) | DRM_MODE_TYPE_BUILTIN)
43#define DRM_MODE_TYPE_CRTC_C ((1<<2) | DRM_MODE_TYPE_BUILTIN)
44#define DRM_MODE_TYPE_PREFERRED (1<<3)
45#define DRM_MODE_TYPE_DEFAULT (1<<4)
46#define DRM_MODE_TYPE_USERDEF (1<<5)
47#define DRM_MODE_TYPE_DRIVER (1<<6)
48
49/* Video mode flags */
50/* bit compatible with the xorg definitions. */
51#define DRM_MODE_FLAG_PHSYNC (1<<0)
52#define DRM_MODE_FLAG_NHSYNC (1<<1)
53#define DRM_MODE_FLAG_PVSYNC (1<<2)
54#define DRM_MODE_FLAG_NVSYNC (1<<3)
55#define DRM_MODE_FLAG_INTERLACE (1<<4)
56#define DRM_MODE_FLAG_DBLSCAN (1<<5)
57#define DRM_MODE_FLAG_CSYNC (1<<6)
58#define DRM_MODE_FLAG_PCSYNC (1<<7)
59#define DRM_MODE_FLAG_NCSYNC (1<<8)
60#define DRM_MODE_FLAG_HSKEW (1<<9) /* hskew provided */
61#define DRM_MODE_FLAG_BCAST (1<<10)
62#define DRM_MODE_FLAG_PIXMUX (1<<11)
63#define DRM_MODE_FLAG_DBLCLK (1<<12)
64#define DRM_MODE_FLAG_CLKDIV2 (1<<13)
65
66/* DPMS flags */
67/* bit compatible with the xorg definitions. */
68#define DRM_MODE_DPMS_ON 0
69#define DRM_MODE_DPMS_STANDBY 1
70#define DRM_MODE_DPMS_SUSPEND 2
71#define DRM_MODE_DPMS_OFF 3
72
73/* Scaling mode options */
74#define DRM_MODE_SCALE_NON_GPU 0
75#define DRM_MODE_SCALE_FULLSCREEN 1
76#define DRM_MODE_SCALE_NO_SCALE 2
77#define DRM_MODE_SCALE_ASPECT 3
78
79/* Dithering mode options */
80#define DRM_MODE_DITHERING_OFF 0
81#define DRM_MODE_DITHERING_ON 1
82
83struct drm_mode_modeinfo {
84 uint32_t clock;
85 uint16_t hdisplay, hsync_start, hsync_end, htotal, hskew;
86 uint16_t vdisplay, vsync_start, vsync_end, vtotal, vscan;
87
88 uint32_t vrefresh; /* vertical refresh * 1000 */
89
90 uint32_t flags;
91 uint32_t type;
92 char name[DRM_DISPLAY_MODE_LEN];
93};
94
95struct drm_mode_card_res {
96 uint64_t fb_id_ptr;
97 uint64_t crtc_id_ptr;
98 uint64_t connector_id_ptr;
99 uint64_t encoder_id_ptr;
100 uint32_t count_fbs;
101 uint32_t count_crtcs;
102 uint32_t count_connectors;
103 uint32_t count_encoders;
104 uint32_t min_width, max_width;
105 uint32_t min_height, max_height;
106};
107
108struct drm_mode_crtc {
109 uint64_t set_connectors_ptr;
110 uint32_t count_connectors;
111
112 uint32_t crtc_id; /**< Id */
113 uint32_t fb_id; /**< Id of framebuffer */
114
115 uint32_t x, y; /**< Position on the frameuffer */
116
117 uint32_t gamma_size;
118 uint32_t mode_valid;
119 struct drm_mode_modeinfo mode;
120};
121
122#define DRM_MODE_ENCODER_NONE 0
123#define DRM_MODE_ENCODER_DAC 1
124#define DRM_MODE_ENCODER_TMDS 2
125#define DRM_MODE_ENCODER_LVDS 3
126#define DRM_MODE_ENCODER_TVDAC 4
127
128struct drm_mode_get_encoder {
129 uint32_t encoder_id;
130 uint32_t encoder_type;
131
132 uint32_t crtc_id; /**< Id of crtc */
133
134 uint32_t possible_crtcs;
135 uint32_t possible_clones;
136};
137
138/* This is for connectors with multiple signal types. */
139/* Try to match DRM_MODE_CONNECTOR_X as closely as possible. */
140#define DRM_MODE_SUBCONNECTOR_Automatic 0
141#define DRM_MODE_SUBCONNECTOR_Unknown 0
142#define DRM_MODE_SUBCONNECTOR_DVID 3
143#define DRM_MODE_SUBCONNECTOR_DVIA 4
144#define DRM_MODE_SUBCONNECTOR_Composite 5
145#define DRM_MODE_SUBCONNECTOR_SVIDEO 6
146#define DRM_MODE_SUBCONNECTOR_Component 8
147
148#define DRM_MODE_CONNECTOR_Unknown 0
149#define DRM_MODE_CONNECTOR_VGA 1
150#define DRM_MODE_CONNECTOR_DVII 2
151#define DRM_MODE_CONNECTOR_DVID 3
152#define DRM_MODE_CONNECTOR_DVIA 4
153#define DRM_MODE_CONNECTOR_Composite 5
154#define DRM_MODE_CONNECTOR_SVIDEO 6
155#define DRM_MODE_CONNECTOR_LVDS 7
156#define DRM_MODE_CONNECTOR_Component 8
157#define DRM_MODE_CONNECTOR_9PinDIN 9
158#define DRM_MODE_CONNECTOR_DisplayPort 10
159#define DRM_MODE_CONNECTOR_HDMIA 11
160#define DRM_MODE_CONNECTOR_HDMIB 12
161
162struct drm_mode_get_connector {
163
164 uint64_t encoders_ptr;
165 uint64_t modes_ptr;
166 uint64_t props_ptr;
167 uint64_t prop_values_ptr;
168
169 uint32_t count_modes;
170 uint32_t count_props;
171 uint32_t count_encoders;
172
173 uint32_t encoder_id; /**< Current Encoder */
174 uint32_t connector_id; /**< Id */
175 uint32_t connector_type;
176 uint32_t connector_type_id;
177
178 uint32_t connection;
179 uint32_t mm_width, mm_height; /**< HxW in millimeters */
180 uint32_t subpixel;
181};
182
183#define DRM_MODE_PROP_PENDING (1<<0)
184#define DRM_MODE_PROP_RANGE (1<<1)
185#define DRM_MODE_PROP_IMMUTABLE (1<<2)
186#define DRM_MODE_PROP_ENUM (1<<3) /* enumerated type with text strings */
187#define DRM_MODE_PROP_BLOB (1<<4)
188
189struct drm_mode_property_enum {
190 uint64_t value;
191 char name[DRM_PROP_NAME_LEN];
192};
193
194struct drm_mode_get_property {
195 uint64_t values_ptr; /* values and blob lengths */
196 uint64_t enum_blob_ptr; /* enum and blob id ptrs */
197
198 uint32_t prop_id;
199 uint32_t flags;
200 char name[DRM_PROP_NAME_LEN];
201
202 uint32_t count_values;
203 uint32_t count_enum_blobs;
204};
205
206struct drm_mode_connector_set_property {
207 uint64_t value;
208 uint32_t prop_id;
209 uint32_t connector_id;
210};
211
212struct drm_mode_get_blob {
213 uint32_t blob_id;
214 uint32_t length;
215 uint64_t data;
216};
217
218struct drm_mode_fb_cmd {
219 uint32_t fb_id;
220 uint32_t width, height;
221 uint32_t pitch;
222 uint32_t bpp;
223 uint32_t depth;
224 /* driver specific handle */
225 uint32_t handle;
226};
227
228struct drm_mode_mode_cmd {
229 uint32_t connector_id;
230 struct drm_mode_modeinfo mode;
231};
232
233#define DRM_MODE_CURSOR_BO (1<<0)
234#define DRM_MODE_CURSOR_MOVE (1<<1)
235
236/*
237 * depending on the value in flags diffrent members are used.
238 *
239 * CURSOR_BO uses
240 * crtc
241 * width
242 * height
243 * handle - if 0 turns the cursor of
244 *
245 * CURSOR_MOVE uses
246 * crtc
247 * x
248 * y
249 */
250struct drm_mode_cursor {
251 uint32_t flags;
252 uint32_t crtc_id;
253 int32_t x;
254 int32_t y;
255 uint32_t width;
256 uint32_t height;
257 /* driver specific handle */
258 uint32_t handle;
259};
260
261struct drm_mode_crtc_lut {
262 uint32_t crtc_id;
263 uint32_t gamma_size;
264
265 /* pointers to arrays */
266 uint64_t red;
267 uint64_t green;
268 uint64_t blue;
269};
270
271#endif
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 95f0f22e..02b2ef0a 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -15,6 +15,10 @@ libdrmtest_la_LIBADD = \
15 15
16LDADD = libdrmtest.la 16LDADD = libdrmtest.la
17 17
18noinst_SUBDIRS = \
19 modeprint \
20 modetest
21
18TESTS = auth \ 22TESTS = auth \
19 openclose \ 23 openclose \
20 getversion \ 24 getversion \
diff --git a/tests/dristat.c b/tests/dristat.c
index 89853164..48c3b51b 100644
--- a/tests/dristat.c
+++ b/tests/dristat.c
@@ -263,7 +263,7 @@ int main(int argc, char **argv)
263 263
264 for (i = 0; i < 16; i++) if (!minor || i == minor) { 264 for (i = 0; i < 16; i++) if (!minor || i == minor) {
265 sprintf(buf, DRM_DEV_NAME, DRM_DIR_NAME, i); 265 sprintf(buf, DRM_DEV_NAME, DRM_DIR_NAME, i);
266 fd = drmOpenMinor(i, 1); 266 fd = drmOpenMinor(i, 1, DRM_NODE_RENDER);
267 if (fd >= 0) { 267 if (fd >= 0) {
268 printf("%s\n", buf); 268 printf("%s\n", buf);
269 if (mask & DRM_BUSID) getbusid(fd); 269 if (mask & DRM_BUSID) getbusid(fd);
diff --git a/tests/modeprint/Makefile b/tests/modeprint/Makefile
new file mode 100644
index 00000000..70788dc9
--- /dev/null
+++ b/tests/modeprint/Makefile
@@ -0,0 +1,14 @@
1
2all: app
3
4#CFLAGS = -g -ansi -pedantic -DPOSIX_C_SOURCE=199309L \
5# -D_POSIX_SOURCE -D_XOPEN_SOURCE -D_BSD_SOURCE -D_SVID_SOURCE \
6
7app: modeprint.c
8 @gcc $(CFLAGS) -o app -Wall -I../../libdrm -I../../shared-core -L../../libdrm/.libs -ldrm modeprint.c
9
10clean:
11 @rm -f app
12
13run: app
14 @sudo ./test
diff --git a/tests/modeprint/app b/tests/modeprint/app
new file mode 100755
index 00000000..82085c85
--- /dev/null
+++ b/tests/modeprint/app
Binary files differ
diff --git a/tests/modeprint/modeprint.c b/tests/modeprint/modeprint.c
new file mode 100644
index 00000000..595d4447
--- /dev/null
+++ b/tests/modeprint/modeprint.c
@@ -0,0 +1,402 @@
1/*
2 * \file modedemo.c
3 * Test program to dump DRM kernel mode setting related information.
4 * Queries the kernel for all available information and dumps it to stdout.
5 *
6 * \author Jakob Bornecrantz <wallbraker@gmail.com>
7 */
8
9/*
10 * Copyright (c) 2007-2008 Tungsten Graphics, Inc., Cedar Park, Texas.
11 * Copyright (c) 2007-2008 Jakob Bornecrantz <wallbraker@gmail.com>
12 *
13 * Permission is hereby granted, free of charge, to any person obtaining a
14 * copy of this software and associated documentation files (the "Software"),
15 * to deal in the Software without restriction, including without limitation
16 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
17 * and/or sell copies of the Software, and to permit persons to whom the
18 * Software is furnished to do so, subject to the following conditions:
19 *
20 * The above copyright notice and this permission notice shall be included in
21 * all copies or substantial portions of the Software.
22 *
23 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
24 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
26 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
28 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
29 * IN THE SOFTWARE.
30 *
31 */
32
33#include <assert.h>
34#include <stdio.h>
35#include <stdlib.h>
36#include <stdint.h>
37#include <unistd.h>
38#include <string.h>
39
40#include "xf86drm.h"
41#include "xf86drmMode.h"
42
43int connectors;
44int full_props;
45int edid;
46int modes;
47int full_modes;
48int encoders;
49int crtcs;
50int fbs;
51char *module_name;
52
53const char* getConnectionText(drmModeConnection conn)
54{
55 switch (conn) {
56 case DRM_MODE_CONNECTED:
57 return "connected";
58 case DRM_MODE_DISCONNECTED:
59 return "disconnected";
60 default:
61 return "unknown";
62 }
63
64}
65
66int printMode(struct drm_mode_modeinfo *mode)
67{
68 if (full_modes) {
69 printf("Mode: %s\n", mode->name);
70 printf("\tclock : %i\n", mode->clock);
71 printf("\thdisplay : %i\n", mode->hdisplay);
72 printf("\thsync_start : %i\n", mode->hsync_start);
73 printf("\thsync_end : %i\n", mode->hsync_end);
74 printf("\thtotal : %i\n", mode->htotal);
75 printf("\thskew : %i\n", mode->hskew);
76 printf("\tvdisplay : %i\n", mode->vdisplay);
77 printf("\tvsync_start : %i\n", mode->vsync_start);
78 printf("\tvsync_end : %i\n", mode->vsync_end);
79 printf("\tvtotal : %i\n", mode->vtotal);
80 printf("\tvscan : %i\n", mode->vscan);
81 printf("\tvrefresh : %i\n", mode->vrefresh);
82 printf("\tflags : %i\n", mode->flags);
83 } else {
84 printf("Mode: \"%s\" %ix%i %.0f\n", mode->name,
85 mode->hdisplay, mode->vdisplay, mode->vrefresh / 1000.0);
86 }
87 return 0;
88}
89
90int printProperty(int fd, drmModeResPtr res, drmModePropertyPtr props, uint64_t value)
91{
92 const unsigned char *name = NULL;
93 int j;
94
95 printf("Property: %s\n", props->name);
96 printf("\tid : %i\n", props->prop_id);
97 printf("\tflags : %i\n", props->flags);
98 printf("\tcount_values : %d\n", props->count_values);
99
100
101 if (props->count_values) {
102 printf("\tvalues :");
103 for (j = 0; j < props->count_values; j++)
104 printf(" %lld", props->values[j]);
105 printf("\n");
106 }
107
108
109 printf("\tcount_enums : %d\n", props->count_enums);
110
111 if (props->flags & DRM_MODE_PROP_BLOB) {
112 drmModePropertyBlobPtr blob;
113
114 blob = drmModeGetPropertyBlob(fd, value);
115 if (blob) {
116 printf("blob is %d length, %08X\n", blob->length, *(uint32_t *)blob->data);
117 drmModeFreePropertyBlob(blob);
118 } else {
119 printf("error getting blob %lld\n", value);
120 }
121
122 } else {
123 if (!strncmp(props->name, "DPMS", 4))
124 ;
125
126 for (j = 0; j < props->count_enums; j++) {
127 printf("\t\t%lld = %s\n", props->enums[j].value, props->enums[j].name);
128 if (props->enums[j].value == value)
129 name = props->enums[j].name;
130 }
131
132 if (props->count_enums && name) {
133 printf("\tcon_value : %s\n", name);
134 } else {
135 printf("\tcon_value : %lld\n", value);
136 }
137 }
138
139 return 0;
140}
141
142int printConnector(int fd, drmModeResPtr res, drmModeConnectorPtr connector, uint32_t id)
143{
144 int i = 0;
145 struct drm_mode_modeinfo *mode = NULL;
146 drmModePropertyPtr props;
147
148 printf("Connector: %d-%d\n", connector->connector_type, connector->connector_type_id);
149 printf("\tid : %i\n", id);
150 printf("\tencoder id : %i\n", connector->encoder_id);
151 printf("\tconn : %s\n", getConnectionText(connector->connection));
152 printf("\tsize : %ix%i (mm)\n", connector->mmWidth, connector->mmHeight);
153 printf("\tcount_modes : %i\n", connector->count_modes);
154 printf("\tcount_props : %i\n", connector->count_props);
155 if (connector->count_props) {
156 printf("\tprops :");
157 for (i = 0; i < connector->count_props; i++)
158 printf(" %i", connector->props[i]);
159 printf("\n");
160 }
161
162 printf("\tcount_encoders : %i\n", connector->count_encoders);
163 if (connector->count_encoders) {
164 printf("\tencoders :");
165 for (i = 0; i < connector->count_encoders; i++)
166 printf(" %i", connector->encoders[i]);
167 printf("\n");
168 }
169
170 if (modes) {
171 for (i = 0; i < connector->count_modes; i++) {
172 mode = &connector->modes[i];
173 printMode(mode);
174 }
175 }
176
177 if (full_props) {
178 for (i = 0; i < connector->count_props; i++) {
179 props = drmModeGetProperty(fd, connector->props[i]);
180 if (props) {
181 printProperty(fd, res, props, connector->prop_values[i]);
182 drmModeFreeProperty(props);
183 }
184 }
185 }
186
187 return 0;
188}
189
190int printEncoder(int fd, drmModeResPtr res, drmModeEncoderPtr encoder, uint32_t id)
191{
192 printf("Encoder\n");
193 printf("\tid :%i\n", id);
194 printf("\tcrtc_id :%d\n", encoder->crtc_id);
195 printf("\ttype :%d\n", encoder->encoder_type);
196 printf("\tpossible_crtcs :%d\n", encoder->possible_crtcs);
197 printf("\tpossible_clones :%d\n", encoder->possible_clones);
198 return 0;
199}
200
201int printCrtc(int fd, drmModeResPtr res, drmModeCrtcPtr crtc, uint32_t id)
202{
203 printf("Crtc\n");
204 printf("\tid : %i\n", id);
205 printf("\tx : %i\n", crtc->x);
206 printf("\ty : %i\n", crtc->y);
207 printf("\twidth : %i\n", crtc->width);
208 printf("\theight : %i\n", crtc->height);
209 printf("\tmode : %p\n", &crtc->mode);
210 printf("\tgamma size : %d\n", crtc->gamma_size);
211
212 return 0;
213}
214
215int printFrameBuffer(int fd, drmModeResPtr res, drmModeFBPtr fb)
216{
217 printf("Framebuffer\n");
218 printf("\thandle : %i\n", fb->handle);
219 printf("\twidth : %i\n", fb->width);
220 printf("\theight : %i\n", fb->height);
221 printf("\tpitch : %i\n", fb->pitch);;
222 printf("\tbpp : %i\n", fb->bpp);
223 printf("\tdepth : %i\n", fb->depth);
224 printf("\tbuffer_id : %i\n", fb->handle);
225
226 return 0;
227}
228
229int printRes(int fd, drmModeResPtr res)
230{
231 int i;
232 drmModeFBPtr fb;
233 drmModeCrtcPtr crtc;
234 drmModeEncoderPtr encoder;
235 drmModeConnectorPtr connector;
236
237 printf("Resources\n\n");
238
239 printf("count_connectors : %i\n", res->count_connectors);
240 printf("count_encoders : %i\n", res->count_encoders);
241 printf("count_crtcs : %i\n", res->count_crtcs);
242 printf("count_fbs : %i\n", res->count_fbs);
243
244 printf("\n");
245
246 if (connectors) {
247 for (i = 0; i < res->count_connectors; i++) {
248 connector = drmModeGetConnector(fd, res->connectors[i]);
249
250 if (!connector)
251 printf("Could not get connector %i\n", res->connectors[i]);
252 else {
253 printConnector(fd, res, connector, res->connectors[i]);
254 drmModeFreeConnector(connector);
255 }
256 }
257 printf("\n");
258 }
259
260
261 if (encoders) {
262 for (i = 0; i < res->count_encoders; i++) {
263 encoder = drmModeGetEncoder(fd, res->encoders[i]);
264
265 if (!encoder)
266 printf("Could not get encoder %i\n", res->encoders[i]);
267 else {
268 printEncoder(fd, res, encoder, res->encoders[i]);
269 drmModeFreeEncoder(encoder);
270 }
271 }
272 printf("\n");
273 }
274
275 if (crtcs) {
276 for (i = 0; i < res->count_crtcs; i++) {
277 crtc = drmModeGetCrtc(fd, res->crtcs[i]);
278
279 if (!crtc)
280 printf("Could not get crtc %i\n", res->crtcs[i]);
281 else {
282 printCrtc(fd, res, crtc, res->crtcs[i]);
283 drmModeFreeCrtc(crtc);
284 }
285 }
286 printf("\n");
287 }
288
289 if (fbs) {
290 for (i = 0; i < res->count_fbs; i++) {
291 fb = drmModeGetFB(fd, res->fbs[i]);
292
293 if (!fb)
294 printf("Could not get fb %i\n", res->fbs[i]);
295 else {
296 printFrameBuffer(fd, res, fb);
297 drmModeFreeFB(fb);
298 }
299 }
300 }
301
302 return 0;
303}
304
305void args(int argc, char **argv)
306{
307 int i;
308
309 fbs = 0;
310 edid = 0;
311 crtcs = 0;
312 modes = 0;
313 encoders = 0;
314 full_modes = 0;
315 full_props = 0;
316 connectors = 0;
317
318 module_name = argv[1];
319
320 for (i = 2; i < argc; i++) {
321 if (strcmp(argv[i], "-fb") == 0) {
322 fbs = 1;
323 } else if (strcmp(argv[i], "-crtcs") == 0) {
324 crtcs = 1;
325 } else if (strcmp(argv[i], "-cons") == 0) {
326 connectors = 1;
327 modes = 1;
328 } else if (strcmp(argv[i], "-modes") == 0) {
329 connectors = 1;
330 modes = 1;
331 } else if (strcmp(argv[i], "-full") == 0) {
332 connectors = 1;
333 modes = 1;
334 full_modes = 1;
335 } else if (strcmp(argv[i], "-props") == 0) {
336 connectors = 1;
337 full_props = 1;
338 } else if (strcmp(argv[i], "-edids") == 0) {
339 connectors = 1;
340 edid = 1;
341 } else if (strcmp(argv[i], "-encoders") == 0) {
342 encoders = 1;
343 } else if (strcmp(argv[i], "-v") == 0) {
344 fbs = 1;
345 edid = 1;
346 crtcs = 1;
347 modes = 1;
348 encoders = 1;
349 full_modes = 1;
350 full_props = 1;
351 connectors = 1;
352 }
353 }
354
355 if (argc == 2) {
356 fbs = 1;
357 edid = 1;
358 crtcs = 1;
359 modes = 1;
360 encoders = 1;
361 full_modes = 0;
362 full_props = 0;
363 connectors = 1;
364 }
365}
366
367int main(int argc, char **argv)
368{
369 int fd;
370 drmModeResPtr res;
371
372 if (argc == 1) {
373 printf("Please add modulename as first argument\n");
374 return 1;
375 }
376
377 args(argc, argv);
378
379 printf("Starting test\n");
380
381 fd = drmOpen(module_name, NULL);
382
383 if (fd < 0) {
384 printf("Failed to open the card fd (%d)\n",fd);
385 return 1;
386 }
387
388 res = drmModeGetResources(fd);
389 if (res == 0) {
390 printf("Failed to get resources from card\n");
391 drmClose(fd);
392 return 1;
393 }
394
395 printRes(fd, res);
396
397 drmModeFreeResources(res);
398
399 printf("Ok\n");
400
401 return 0;
402}
diff --git a/tests/modeprint/test b/tests/modeprint/test
new file mode 100644
index 00000000..bd1952cc
--- /dev/null
+++ b/tests/modeprint/test
@@ -0,0 +1 @@
LD_PRELOAD=../../libdrm/.libs/libdrm.so ./app $@
diff --git a/tests/modetest/Makefile b/tests/modetest/Makefile
new file mode 100644
index 00000000..8583ae82
--- /dev/null
+++ b/tests/modetest/Makefile
@@ -0,0 +1,14 @@
1
2all: app
3
4#CFLAGS = -g -ansi -pedantic -DPOSIX_C_SOURCE=199309L \
5# -D_POSIX_SOURCE -D_XOPEN_SOURCE -D_BSD_SOURCE -D_SVID_SOURCE \
6
7app: modetest.c
8 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
9
10clean:
11 @rm -f app
12
13run: app
14 sudo ./test
diff --git a/tests/modetest/modetest.c b/tests/modetest/modetest.c
new file mode 100644
index 00000000..e5a16e1a
--- /dev/null
+++ b/tests/modetest/modetest.c
@@ -0,0 +1,449 @@
1/*
2 * DRM based mode setting test program
3 * Copyright 2008 Tungsten Graphics
4 * Jakob Bornecrantz <jakob@tungstengraphics.com>
5 * Copyright 2008 Intel Corporation
6 * Jesse Barnes <jesse.barnes@intel.com>
7 *
8 * Permission is hereby granted, free of charge, to any person obtaining a
9 * copy of this software and associated documentation files (the "Software"),
10 * to deal in the Software without restriction, including without limitation
11 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12 * and/or sell copies of the Software, and to permit persons to whom the
13 * Software is furnished to do so, subject to the following conditions:
14 *
15 * The above copyright notice and this permission notice shall be included in
16 * all copies or substantial portions of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
23 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
24 * IN THE SOFTWARE.
25 */
26
27/*
28 * This fairly simple test program dumps output in a similar format to the
29 * "xrandr" tool everyone knows & loves. It's necessarily slightly different
30 * since the kernel separates outputs into encoder and connector structures,
31 * each with their own unique ID. The program also allows test testing of the
32 * memory management and mode setting APIs by allowing the user to specify a
33 * connector and mode to use for mode setting. If all works as expected, a
34 * blue background should be painted on the monitor attached to the specified
35 * connector after the selected mode is set.
36 *
37 * TODO: use cairo to write the mode info on the selected output once
38 * the mode has been programmed, along with possible test patterns.
39 */
40#include <assert.h>
41#include <stdio.h>
42#include <stdlib.h>
43#include <stdint.h>
44#include <unistd.h>
45#include <string.h>
46#include <errno.h>
47
48#include "xf86drm.h"
49#include "xf86drmMode.h"
50#include "intel_bufmgr.h"
51
52drmModeRes *resources;
53int fd, modes;
54
55#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
56
57struct type_name {
58 int type;
59 char *name;
60};
61
62#define type_name_fn(res) \
63char * res##_str(int type) { \
64 int i; \
65 for (i = 0; i < ARRAY_SIZE(res##_names); i++) { \
66 if (res##_names[i].type == type) \
67 return res##_names[i].name; \
68 } \
69 return "(invalid)"; \
70}
71
72struct type_name encoder_type_names[] = {
73 { DRM_MODE_ENCODER_NONE, "none" },
74 { DRM_MODE_ENCODER_DAC, "DAC" },
75 { DRM_MODE_ENCODER_TMDS, "TMDS" },
76 { DRM_MODE_ENCODER_LVDS, "LVDS" },
77 { DRM_MODE_ENCODER_TVDAC, "TVDAC" },
78};
79
80type_name_fn(encoder_type)
81
82struct type_name connector_status_names[] = {
83 { DRM_MODE_CONNECTED, "connected" },
84 { DRM_MODE_DISCONNECTED, "disconnected" },
85 { DRM_MODE_UNKNOWNCONNECTION, "unknown" },
86};
87
88type_name_fn(connector_status)
89
90struct type_name connector_type_names[] = {
91 { DRM_MODE_CONNECTOR_Unknown, "unknown" },
92 { DRM_MODE_CONNECTOR_VGA, "VGA" },
93 { DRM_MODE_CONNECTOR_DVII, "DVI-I" },
94 { DRM_MODE_CONNECTOR_DVID, "DVI-D" },
95 { DRM_MODE_CONNECTOR_DVIA, "DVI-A" },
96 { DRM_MODE_CONNECTOR_Composite, "composite" },
97 { DRM_MODE_CONNECTOR_SVIDEO, "s-video" },
98 { DRM_MODE_CONNECTOR_LVDS, "LVDS" },
99 { DRM_MODE_CONNECTOR_Component, "component" },
100 { DRM_MODE_CONNECTOR_9PinDIN, "9-pin DIN" },
101 { DRM_MODE_CONNECTOR_DisplayPort, "displayport" },
102 { DRM_MODE_CONNECTOR_HDMIA, "HDMI-A" },
103 { DRM_MODE_CONNECTOR_HDMIB, "HDMI-B" },
104};
105
106type_name_fn(connector_type)
107
108void dump_encoders(void)
109{
110 drmModeEncoder *encoder;
111 int i;
112
113 printf("Encoders:\n");
114 printf("id\tcrtc\ttype\tpossible crtcs\tpossible clones\t\n");
115 for (i = 0; i < resources->count_encoders; i++) {
116 encoder = drmModeGetEncoder(fd, resources->encoders[i]);
117
118 if (!encoder) {
119 fprintf(stderr, "could not get encoder %i: %s\n",
120 resources->encoders[i], strerror(errno));
121 continue;
122 }
123 printf("%d\t%d\t%s\t0x%08x\t0x%08x\n",
124 encoder->encoder_id,
125 encoder->crtc_id,
126 encoder_type_str(encoder->encoder_type),
127 encoder->possible_crtcs,
128 encoder->possible_clones);
129 drmModeFreeEncoder(encoder);
130 }
131}
132
133void dump_connectors(void)
134{
135 drmModeConnector *connector;
136 int i, j;
137
138 printf("Connectors:\n");
139 printf("id\tencoder\tstatus\t\ttype\tsize (mm)\tmodes\n");
140 for (i = 0; i < resources->count_connectors; i++) {
141 connector = drmModeGetConnector(fd, resources->connectors[i]);
142
143 if (!connector) {
144 fprintf(stderr, "could not get connector %i: %s\n",
145 resources->connectors[i], strerror(errno));
146 continue;
147 }
148
149 printf("%d\t%d\t%s\t%s\t%dx%d\t\t%d\n",
150 connector->connector_id,
151 connector->encoder_id,
152 connector_status_str(connector->connection),
153 connector_type_str(connector->connector_type),
154 connector->mmWidth, connector->mmHeight,
155 connector->count_modes);
156
157 if (!connector->count_modes)
158 continue;
159
160 printf(" modes:\n");
161 printf(" name refresh (Hz) hdisp hss hse htot vdisp "
162 "vss vse vtot)\n");
163 for (j = 0; j < connector->count_modes; j++) {
164 struct drm_mode_modeinfo *mode;
165
166 mode = &connector->modes[j];
167 printf(" %s %.02f %d %d %d %d %d %d %d %d\n",
168 mode->name,
169 (float)mode->vrefresh / 1000,
170 mode->hdisplay,
171 mode->hsync_start,
172 mode->hsync_end,
173 mode->htotal,
174 mode->vdisplay,
175 mode->vsync_start,
176 mode->vsync_end,
177 mode->vtotal);
178 }
179 drmModeFreeConnector(connector);
180 }
181}
182
183void dump_crtcs(void)
184{
185 drmModeCrtc *crtc;
186 int i;
187
188 for (i = 0; i < resources->count_crtcs; i++) {
189 crtc = drmModeGetCrtc(fd, resources->crtcs[i]);
190
191 if (!crtc) {
192 fprintf(stderr, "could not get crtc %i: %s\n",
193 resources->crtcs[i], strerror(errno));
194 continue;
195 }
196 drmModeFreeCrtc(crtc);
197 }
198}
199
200void dump_framebuffers(void)
201{
202 drmModeFB *fb;
203 int i;
204
205 for (i = 0; i < resources->count_fbs; i++) {
206 fb = drmModeGetFB(fd, resources->fbs[i]);
207
208 if (!fb) {
209 fprintf(stderr, "could not get fb %i: %s\n",
210 resources->fbs[i], strerror(errno));
211 continue;
212 }
213 drmModeFreeFB(fb);
214 }
215}
216
217/*
218 * Mode setting with the kernel interfaces is a bit of a chore.
219 * First you have to find the connector in question and make sure the
220 * requested mode is available.
221 * Then you need to find the encoder attached to that connector so you
222 * can bind it with a free crtc.
223 */
224void set_mode(int connector_id, char *mode_str)
225{
226 drmModeConnector *connector;
227 drmModeEncoder *encoder = NULL;
228 struct drm_mode_modeinfo *mode = NULL;
229 drm_intel_bufmgr *bufmgr;
230 drm_intel_bo *bo;
231 unsigned int fb_id, *fb_ptr;
232 int i, j, size, ret, width, height;
233
234 /* First, find the connector & mode */
235 for (i = 0; i < resources->count_connectors; i++) {
236 connector = drmModeGetConnector(fd, resources->connectors[i]);
237
238 if (!connector) {
239 fprintf(stderr, "could not get connector %i: %s\n",
240 resources->connectors[i], strerror(errno));
241 drmModeFreeConnector(connector);
242 continue;
243 }
244
245 if (!connector->count_modes) {
246 drmModeFreeConnector(connector);
247 continue;
248 }
249
250 if (connector->connector_id != connector_id) {
251 drmModeFreeConnector(connector);
252 continue;
253 }
254
255 for (j = 0; j < connector->count_modes; j++) {
256 mode = &connector->modes[j];
257 if (!strcmp(mode->name, mode_str))
258 break;
259 }
260
261 /* Found it, break out */
262 if (mode)
263 break;
264
265 drmModeFreeConnector(connector);
266 }
267
268 if (!mode) {
269 fprintf(stderr, "failed to find mode \"%s\"\n", mode_str);
270 return;
271 }
272
273 width = mode->hdisplay;
274 height = mode->vdisplay;
275
276 /* Now get the encoder */
277 for (i = 0; i < resources->count_encoders; i++) {
278 encoder = drmModeGetEncoder(fd, resources->encoders[i]);
279
280 if (!encoder) {
281 fprintf(stderr, "could not get encoder %i: %s\n",
282 resources->encoders[i], strerror(errno));
283 drmModeFreeEncoder(encoder);
284 continue;
285 }
286
287 if (encoder->encoder_id == connector->encoder_id)
288 break;
289
290 drmModeFreeEncoder(encoder);
291 }
292
293 bufmgr = drm_intel_bufmgr_gem_init(fd, 2<<20);
294 if (!bufmgr) {
295 fprintf(stderr, "failed to init bufmgr: %s\n", strerror(errno));
296 return;
297 }
298
299 /* Mode size at 32 bpp */
300 size = width * height * 4;
301
302 bo = drm_intel_bo_alloc(bufmgr, "frontbuffer", size, 4096);
303 if (!bo) {
304 fprintf(stderr, "failed to alloc buffer: %s\n",
305 strerror(errno));
306 return;
307 }
308
309 ret = drm_intel_bo_pin(bo, 4096);
310 if (ret) {
311 fprintf(stderr, "failed to pin buffer: %s\n", strerror(errno));
312 return;
313 }
314
315 ret = drm_intel_gem_bo_map_gtt(bo);
316 if (ret) {
317 fprintf(stderr, "failed to GTT map buffer: %s\n",
318 strerror(errno));
319 return;
320 }
321
322 fb_ptr = bo->virtual;
323
324 /* paint the buffer blue */
325 for (i = 0; i < width * height; i++)
326 fb_ptr[i] = 0xff;
327
328 ret = drmModeAddFB(fd, width, height, 32, 32, width * 4, bo->handle,
329 &fb_id);
330 if (ret) {
331 fprintf(stderr, "failed to add fb: %s\n", strerror(errno));
332 return;
333 }
334
335 ret = drmModeSetCrtc(fd, encoder->crtc_id, fb_id, 0, 0,
336 &connector->connector_id, 1, mode);
337 if (ret) {
338 fprintf(stderr, "failed to set mode: %s\n", strerror(errno));
339 return;
340 }
341}
342
343extern char *optarg;
344extern int optind, opterr, optopt;
345static char optstr[] = "ecpmfs:";
346
347void usage(char *name)
348{
349 fprintf(stderr, "usage: %s [-ecpmf]\n", name);
350 fprintf(stderr, "\t-e\tlist encoders\n");
351 fprintf(stderr, "\t-c\tlist connectors\n");
352 fprintf(stderr, "\t-p\tlist CRTCs (pipes)\n");
353 fprintf(stderr, "\t-m\tlist modes\n");
354 fprintf(stderr, "\t-f\tlist framebuffers\n");
355 fprintf(stderr, "\t-s <connector_id>:<mode>\tset a mode\n");
356 fprintf(stderr, "\n\tDefault is to dump all info.\n");
357 exit(0);
358}
359
360#define dump_resource(res) if (res) dump_##res()
361
362int main(int argc, char **argv)
363{
364 int c;
365 int encoders = 0, connectors = 0, crtcs = 0, framebuffers = 0;
366 char *modules[] = { "i915", "radeon" };
367 char *modeset = NULL, *mode, *connector;
368 int i, connector_id;
369
370 opterr = 0;
371 while ((c = getopt(argc, argv, optstr)) != -1) {
372 switch (c) {
373 case 'e':
374 encoders = 1;
375 break;
376 case 'c':
377 connectors = 1;
378 break;
379 case 'p':
380 crtcs = 1;
381 break;
382 case 'm':
383 modes = 1;
384 break;
385 case 'f':
386 framebuffers = 1;
387 break;
388 case 's':
389 modeset = strdup(optarg);
390 break;
391 default:
392 usage(argv[0]);
393 break;
394 }
395 }
396
397 if (argc == 1)
398 encoders = connectors = crtcs = modes = framebuffers = 1;
399
400 for (i = 0; i < ARRAY_SIZE(modules); i++) {
401 printf("trying to load module %s...", modules[i]);
402 fd = drmOpen(modules[i], NULL);
403 if (fd < 0) {
404 printf("failed.\n");
405 } else {
406 printf("success.\n");
407 break;
408 }
409 }
410
411 if (i == ARRAY_SIZE(modules)) {
412 fprintf(stderr, "failed to load any modules, aborting.\n");
413 return -1;
414 }
415
416 resources = drmModeGetResources(fd);
417 if (!resources) {
418 fprintf(stderr, "drmModeGetResources failed: %s\n",
419 strerror(errno));
420 drmClose(fd);
421 return 1;
422 }
423
424 dump_resource(encoders);
425 dump_resource(connectors);
426 dump_resource(crtcs);
427 dump_resource(framebuffers);
428
429 if (modeset) {
430 connector = strtok(modeset, ":");
431 if (!connector)
432 usage(argv[0]);
433 connector_id = atoi(connector);
434
435 mode = strtok(NULL, ":");
436 if (!mode)
437 usage(argv[0]);
438 printf("setting connector %d to mode %s\n", connector_id,
439 mode);
440 set_mode(connector_id, mode);
441 sleep(3);
442 }
443
444 sleep(3);
445
446 drmModeFreeResources(resources);
447
448 return 0;
449}
diff --git a/tests/modetest/test b/tests/modetest/test
new file mode 100644
index 00000000..5bb552ef
--- /dev/null
+++ b/tests/modetest/test
@@ -0,0 +1,2 @@
1export LD_LIBRARY_PATH=../../libdrm/.libs:../../libdrm/intel/.libs
2LD_PRELOAD=../../libdrm/.libs/libdrm.so ./app $@