• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
kms_device_probe_screens(struct kms_device * device)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 
kms_device_probe_crtcs(struct kms_device * device)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 
kms_device_probe_planes(struct kms_device * device)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 
kms_device_probe(struct kms_device * device)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 
kms_device_open(int fd)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 
kms_device_close(struct kms_device * device)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 
kms_device_find_plane_by_type(struct kms_device * device,uint32_t type,unsigned int index)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 }
219