diff options
Diffstat (limited to 'tests/kms/libkms-test-device.c')
-rw-r--r-- | tests/kms/libkms-test-device.c | 218 |
1 files changed, 218 insertions, 0 deletions
diff --git a/tests/kms/libkms-test-device.c b/tests/kms/libkms-test-device.c new file mode 100644 index 00000000..53c7349b --- /dev/null +++ b/tests/kms/libkms-test-device.c | |||
@@ -0,0 +1,218 @@ | |||
1 | /* | ||
2 | * Copyright © 2014 NVIDIA Corporation | ||
3 | * | ||
4 | * Permission is hereby granted, free of charge, to any person obtaining a | ||
5 | * copy of this software and associated documentation files (the "Software"), | ||
6 | * to deal in the Software without restriction, including without limitation | ||
7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||
8 | * and/or sell copies of the Software, and to permit persons to whom the | ||
9 | * Software is furnished to do so, subject to the following conditions: | ||
10 | * | ||
11 | * The above copyright notice and this permission notice (including the next | ||
12 | * paragraph) shall be included in all copies or substantial portions of the | ||
13 | * Software. | ||
14 | * | ||
15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | ||
18 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | ||
20 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS | ||
21 | * IN THE SOFTWARE. | ||
22 | */ | ||
23 | |||
24 | #ifdef HAVE_CONFIG_H | ||
25 | #include "config.h" | ||
26 | #endif | ||
27 | |||
28 | #include <stdio.h> | ||
29 | #include <string.h> | ||
30 | #include <unistd.h> | ||
31 | |||
32 | #include "util/common.h" | ||
33 | #include "libkms-test.h" | ||
34 | |||
35 | static const char *const connector_names[] = { | ||
36 | "Unknown", | ||
37 | "VGA", | ||
38 | "DVI-I", | ||
39 | "DVI-D", | ||
40 | "DVI-A", | ||
41 | "Composite", | ||
42 | "SVIDEO", | ||
43 | "LVDS", | ||
44 | "Component", | ||
45 | "9PinDIN", | ||
46 | "DisplayPort", | ||
47 | "HDMI-A", | ||
48 | "HDMI-B", | ||
49 | "TV", | ||
50 | "eDP", | ||
51 | "Virtual", | ||
52 | "DSI", | ||
53 | }; | ||
54 | |||
55 | static void kms_device_probe_screens(struct kms_device *device) | ||
56 | { | ||
57 | unsigned int counts[ARRAY_SIZE(connector_names)]; | ||
58 | struct kms_screen *screen; | ||
59 | drmModeRes *res; | ||
60 | int i; | ||
61 | |||
62 | memset(counts, 0, sizeof(counts)); | ||
63 | |||
64 | res = drmModeGetResources(device->fd); | ||
65 | if (!res) | ||
66 | return; | ||
67 | |||
68 | device->screens = calloc(res->count_connectors, sizeof(screen)); | ||
69 | if (!device->screens) | ||
70 | return; | ||
71 | |||
72 | for (i = 0; i < res->count_connectors; i++) { | ||
73 | unsigned int *count; | ||
74 | const char *type; | ||
75 | int len; | ||
76 | |||
77 | screen = kms_screen_create(device, res->connectors[i]); | ||
78 | if (!screen) | ||
79 | continue; | ||
80 | |||
81 | /* assign a unique name to this screen */ | ||
82 | type = connector_names[screen->type]; | ||
83 | count = &counts[screen->type]; | ||
84 | |||
85 | len = snprintf(NULL, 0, "%s-%u", type, *count); | ||
86 | |||
87 | screen->name = malloc(len + 1); | ||
88 | if (!screen->name) { | ||
89 | free(screen); | ||
90 | continue; | ||
91 | } | ||
92 | |||
93 | snprintf(screen->name, len + 1, "%s-%u", type, *count); | ||
94 | (*count)++; | ||
95 | |||
96 | device->screens[i] = screen; | ||
97 | device->num_screens++; | ||
98 | } | ||
99 | |||
100 | drmModeFreeResources(res); | ||
101 | } | ||
102 | |||
103 | static void kms_device_probe_crtcs(struct kms_device *device) | ||
104 | { | ||
105 | struct kms_crtc *crtc; | ||
106 | drmModeRes *res; | ||
107 | int i; | ||
108 | |||
109 | res = drmModeGetResources(device->fd); | ||
110 | if (!res) | ||
111 | return; | ||
112 | |||
113 | device->crtcs = calloc(res->count_crtcs, sizeof(crtc)); | ||
114 | if (!device->crtcs) | ||
115 | return; | ||
116 | |||
117 | for (i = 0; i < res->count_crtcs; i++) { | ||
118 | crtc = kms_crtc_create(device, res->crtcs[i]); | ||
119 | if (!crtc) | ||
120 | continue; | ||
121 | |||
122 | device->crtcs[i] = crtc; | ||
123 | device->num_crtcs++; | ||
124 | } | ||
125 | |||
126 | drmModeFreeResources(res); | ||
127 | } | ||
128 | |||
129 | static void kms_device_probe_planes(struct kms_device *device) | ||
130 | { | ||
131 | struct kms_plane *plane; | ||
132 | drmModePlaneRes *res; | ||
133 | unsigned int i; | ||
134 | |||
135 | res = drmModeGetPlaneResources(device->fd); | ||
136 | if (!res) | ||
137 | return; | ||
138 | |||
139 | device->planes = calloc(res->count_planes, sizeof(plane)); | ||
140 | if (!device->planes) | ||
141 | return; | ||
142 | |||
143 | for (i = 0; i < res->count_planes; i++) { | ||
144 | plane = kms_plane_create(device, res->planes[i]); | ||
145 | if (!plane) | ||
146 | continue; | ||
147 | |||
148 | device->planes[i] = plane; | ||
149 | device->num_planes++; | ||
150 | } | ||
151 | |||
152 | drmModeFreePlaneResources(res); | ||
153 | } | ||
154 | |||
155 | static void kms_device_probe(struct kms_device *device) | ||
156 | { | ||
157 | kms_device_probe_screens(device); | ||
158 | kms_device_probe_crtcs(device); | ||
159 | kms_device_probe_planes(device); | ||
160 | } | ||
161 | |||
162 | struct kms_device *kms_device_open(int fd) | ||
163 | { | ||
164 | struct kms_device *device; | ||
165 | |||
166 | device = calloc(1, sizeof(*device)); | ||
167 | if (!device) | ||
168 | return NULL; | ||
169 | |||
170 | device->fd = fd; | ||
171 | |||
172 | kms_device_probe(device); | ||
173 | |||
174 | return device; | ||
175 | } | ||
176 | |||
177 | void kms_device_close(struct kms_device *device) | ||
178 | { | ||
179 | unsigned int i; | ||
180 | |||
181 | for (i = 0; i < device->num_planes; i++) | ||
182 | kms_plane_free(device->planes[i]); | ||
183 | |||
184 | free(device->planes); | ||
185 | |||
186 | for (i = 0; i < device->num_crtcs; i++) | ||
187 | kms_crtc_free(device->crtcs[i]); | ||
188 | |||
189 | free(device->crtcs); | ||
190 | |||
191 | for (i = 0; i < device->num_screens; i++) | ||
192 | kms_screen_free(device->screens[i]); | ||
193 | |||
194 | free(device->screens); | ||
195 | |||
196 | if (device->fd >= 0) | ||
197 | close(device->fd); | ||
198 | |||
199 | free(device); | ||
200 | } | ||
201 | |||
202 | struct kms_plane *kms_device_find_plane_by_type(struct kms_device *device, | ||
203 | uint32_t type, | ||
204 | unsigned int index) | ||
205 | { | ||
206 | unsigned int i; | ||
207 | |||
208 | for (i = 0; i < device->num_planes; i++) { | ||
209 | if (device->planes[i]->type == type) { | ||
210 | if (index == 0) | ||
211 | return device->planes[i]; | ||
212 | |||
213 | index--; | ||
214 | } | ||
215 | } | ||
216 | |||
217 | return NULL; | ||
218 | } | ||