aboutsummaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
authorJesse Barnes2008-12-17 12:09:49 -0600
committerJesse Barnes2008-12-17 12:11:37 -0600
commit731cd5526e5c732d51307b26e784f454a724a699 (patch)
tree215249e4aa86a3d8418b7f5cad95551d49ecce2d /tests
parentc86d431fe6174b1c2de531929213ea7dbd92326d (diff)
downloadexternal-libdrm-731cd5526e5c732d51307b26e784f454a724a699.tar.gz
external-libdrm-731cd5526e5c732d51307b26e784f454a724a699.tar.xz
external-libdrm-731cd5526e5c732d51307b26e784f454a724a699.zip
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.
Diffstat (limited to 'tests')
-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
9 files changed, 887 insertions, 1 deletions
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 $@