| Jesse Barnes | 731cd55 | 2008-12-17 10:09:49 -0800 | [diff] [blame] | 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 | /* | 
| Eric Engestrom | ce97507 | 2016-04-03 19:48:12 +0100 | [diff] [blame] | 37 |  * TODO the types we are after are defined in different headers on different | 
| Jesse Barnes | 731cd55 | 2008-12-17 10:09:49 -0800 | [diff] [blame] | 38 |  * platforms find which headers to include to get uint32_t | 
 | 39 |  */ | 
| Emil Velikov | 5f76273 | 2015-06-29 17:32:21 +0100 | [diff] [blame] | 40 |  | 
| Ville Syrjälä | ed44e0b | 2015-06-22 17:26:02 +0100 | [diff] [blame] | 41 | #include <limits.h> | 
| Jesse Barnes | 731cd55 | 2008-12-17 10:09:49 -0800 | [diff] [blame] | 42 | #include <stdint.h> | 
| Ville Syrjälä | ed44e0b | 2015-06-22 17:26:02 +0100 | [diff] [blame] | 43 | #include <stdlib.h> | 
| Jesse Barnes | 731cd55 | 2008-12-17 10:09:49 -0800 | [diff] [blame] | 44 | #include <sys/ioctl.h> | 
| Julien Cristau | fc8c3e2 | 2015-07-06 12:45:31 +0100 | [diff] [blame] | 45 | #ifdef HAVE_SYS_SYSCTL_H | 
 | 46 | #include <sys/sysctl.h> | 
 | 47 | #endif | 
| Jesse Barnes | 731cd55 | 2008-12-17 10:09:49 -0800 | [diff] [blame] | 48 | #include <stdio.h> | 
| Ville Syrjälä | ed44e0b | 2015-06-22 17:26:02 +0100 | [diff] [blame] | 49 | #include <stdbool.h> | 
| Jesse Barnes | 731cd55 | 2008-12-17 10:09:49 -0800 | [diff] [blame] | 50 |  | 
| Lucas De Marchi | 26f9ce5 | 2018-09-13 15:42:26 -0700 | [diff] [blame] | 51 | #include "libdrm_macros.h" | 
| Jesse Barnes | 731cd55 | 2008-12-17 10:09:49 -0800 | [diff] [blame] | 52 | #include "xf86drmMode.h" | 
 | 53 | #include "xf86drm.h" | 
 | 54 | #include <drm.h> | 
 | 55 | #include <string.h> | 
 | 56 | #include <dirent.h> | 
| Kristian Høgsberg | b0b9663 | 2009-09-11 13:27:35 -0400 | [diff] [blame] | 57 | #include <unistd.h> | 
| Jesse Barnes | 731cd55 | 2008-12-17 10:09:49 -0800 | [diff] [blame] | 58 | #include <errno.h> | 
 | 59 |  | 
| Daniel Vetter | 7e0460c | 2015-02-11 12:03:12 +0100 | [diff] [blame] | 60 | #define memclear(s) memset(&s, 0, sizeof(s)) | 
| Eric Anholt | 734de70 | 2013-12-28 22:06:51 -0800 | [diff] [blame] | 61 |  | 
| Jesse Barnes | 731cd55 | 2008-12-17 10:09:49 -0800 | [diff] [blame] | 62 | #define U642VOID(x) ((void *)(unsigned long)(x)) | 
 | 63 | #define VOID2U64(x) ((uint64_t)(unsigned long)(x)) | 
 | 64 |  | 
| Marcin Slusarz | 763b618 | 2011-06-05 18:53:16 +0200 | [diff] [blame] | 65 | static inline int DRM_IOCTL(int fd, unsigned long cmd, void *arg) | 
| Chris Wilson | b803918 | 2010-07-01 22:38:54 +0100 | [diff] [blame] | 66 | { | 
 | 67 | 	int ret = drmIoctl(fd, cmd, arg); | 
 | 68 | 	return ret < 0 ? -errno : ret; | 
 | 69 | } | 
 | 70 |  | 
| Jesse Barnes | 731cd55 | 2008-12-17 10:09:49 -0800 | [diff] [blame] | 71 | /* | 
 | 72 |  * Util functions | 
 | 73 |  */ | 
 | 74 |  | 
| Jan Vesely | 65041c4 | 2015-02-27 11:51:05 -0500 | [diff] [blame] | 75 | static void* drmAllocCpy(char *array, int count, int entry_size) | 
| Jesse Barnes | 731cd55 | 2008-12-17 10:09:49 -0800 | [diff] [blame] | 76 | { | 
 | 77 | 	char *r; | 
 | 78 | 	int i; | 
 | 79 |  | 
 | 80 | 	if (!count || !array || !entry_size) | 
 | 81 | 		return 0; | 
 | 82 |  | 
 | 83 | 	if (!(r = drmMalloc(count*entry_size))) | 
 | 84 | 		return 0; | 
 | 85 |  | 
 | 86 | 	for (i = 0; i < count; i++) | 
 | 87 | 		memcpy(r+(entry_size*i), array+(entry_size*i), entry_size); | 
 | 88 |  | 
 | 89 | 	return r; | 
 | 90 | } | 
 | 91 |  | 
 | 92 | /* | 
 | 93 |  * A couple of free functions. | 
 | 94 |  */ | 
 | 95 |  | 
| Lucas De Marchi | 26f9ce5 | 2018-09-13 15:42:26 -0700 | [diff] [blame] | 96 | drm_public void drmModeFreeModeInfo(drmModeModeInfoPtr ptr) | 
| Jesse Barnes | 731cd55 | 2008-12-17 10:09:49 -0800 | [diff] [blame] | 97 | { | 
 | 98 | 	if (!ptr) | 
 | 99 | 		return; | 
 | 100 |  | 
 | 101 | 	drmFree(ptr); | 
 | 102 | } | 
 | 103 |  | 
| Lucas De Marchi | 26f9ce5 | 2018-09-13 15:42:26 -0700 | [diff] [blame] | 104 | drm_public void drmModeFreeResources(drmModeResPtr ptr) | 
| Jesse Barnes | 731cd55 | 2008-12-17 10:09:49 -0800 | [diff] [blame] | 105 | { | 
 | 106 | 	if (!ptr) | 
 | 107 | 		return; | 
 | 108 |  | 
| Ville Syrjälä | df497e9 | 2012-02-02 14:53:39 -0500 | [diff] [blame] | 109 | 	drmFree(ptr->fbs); | 
 | 110 | 	drmFree(ptr->crtcs); | 
 | 111 | 	drmFree(ptr->connectors); | 
 | 112 | 	drmFree(ptr->encoders); | 
| Jesse Barnes | 731cd55 | 2008-12-17 10:09:49 -0800 | [diff] [blame] | 113 | 	drmFree(ptr); | 
| Jesse Barnes | 731cd55 | 2008-12-17 10:09:49 -0800 | [diff] [blame] | 114 | } | 
 | 115 |  | 
| Lucas De Marchi | 26f9ce5 | 2018-09-13 15:42:26 -0700 | [diff] [blame] | 116 | drm_public void drmModeFreeFB(drmModeFBPtr ptr) | 
| Jesse Barnes | 731cd55 | 2008-12-17 10:09:49 -0800 | [diff] [blame] | 117 | { | 
 | 118 | 	if (!ptr) | 
 | 119 | 		return; | 
 | 120 |  | 
 | 121 | 	/* we might add more frees later. */ | 
 | 122 | 	drmFree(ptr); | 
 | 123 | } | 
 | 124 |  | 
| Lucas De Marchi | 26f9ce5 | 2018-09-13 15:42:26 -0700 | [diff] [blame] | 125 | drm_public void drmModeFreeCrtc(drmModeCrtcPtr ptr) | 
| Jesse Barnes | 731cd55 | 2008-12-17 10:09:49 -0800 | [diff] [blame] | 126 | { | 
 | 127 | 	if (!ptr) | 
 | 128 | 		return; | 
 | 129 |  | 
 | 130 | 	drmFree(ptr); | 
| Jesse Barnes | 731cd55 | 2008-12-17 10:09:49 -0800 | [diff] [blame] | 131 | } | 
 | 132 |  | 
| Lucas De Marchi | 26f9ce5 | 2018-09-13 15:42:26 -0700 | [diff] [blame] | 133 | drm_public void drmModeFreeConnector(drmModeConnectorPtr ptr) | 
| Jesse Barnes | 731cd55 | 2008-12-17 10:09:49 -0800 | [diff] [blame] | 134 | { | 
 | 135 | 	if (!ptr) | 
 | 136 | 		return; | 
 | 137 |  | 
| Keith Packard | 0a24654 | 2009-09-17 17:28:08 -0700 | [diff] [blame] | 138 | 	drmFree(ptr->encoders); | 
 | 139 | 	drmFree(ptr->prop_values); | 
 | 140 | 	drmFree(ptr->props); | 
| Jesse Barnes | 731cd55 | 2008-12-17 10:09:49 -0800 | [diff] [blame] | 141 | 	drmFree(ptr->modes); | 
 | 142 | 	drmFree(ptr); | 
| Jesse Barnes | 731cd55 | 2008-12-17 10:09:49 -0800 | [diff] [blame] | 143 | } | 
 | 144 |  | 
| Lucas De Marchi | 26f9ce5 | 2018-09-13 15:42:26 -0700 | [diff] [blame] | 145 | drm_public void drmModeFreeEncoder(drmModeEncoderPtr ptr) | 
| Jesse Barnes | 731cd55 | 2008-12-17 10:09:49 -0800 | [diff] [blame] | 146 | { | 
 | 147 | 	drmFree(ptr); | 
 | 148 | } | 
 | 149 |  | 
 | 150 | /* | 
 | 151 |  * ModeSetting functions. | 
 | 152 |  */ | 
 | 153 |  | 
| Lucas De Marchi | 26f9ce5 | 2018-09-13 15:42:26 -0700 | [diff] [blame] | 154 | drm_public drmModeResPtr drmModeGetResources(int fd) | 
| Jesse Barnes | 731cd55 | 2008-12-17 10:09:49 -0800 | [diff] [blame] | 155 | { | 
| Chris Wilson | d1308f4 | 2010-01-06 15:19:25 +0000 | [diff] [blame] | 156 | 	struct drm_mode_card_res res, counts; | 
| Jesse Barnes | 731cd55 | 2008-12-17 10:09:49 -0800 | [diff] [blame] | 157 | 	drmModeResPtr r = 0; | 
 | 158 |  | 
| Chris Wilson | d1308f4 | 2010-01-06 15:19:25 +0000 | [diff] [blame] | 159 | retry: | 
| Daniel Vetter | 7e0460c | 2015-02-11 12:03:12 +0100 | [diff] [blame] | 160 | 	memclear(res); | 
| Jesse Barnes | 731cd55 | 2008-12-17 10:09:49 -0800 | [diff] [blame] | 161 | 	if (drmIoctl(fd, DRM_IOCTL_MODE_GETRESOURCES, &res)) | 
 | 162 | 		return 0; | 
 | 163 |  | 
| Chris Wilson | d1308f4 | 2010-01-06 15:19:25 +0000 | [diff] [blame] | 164 | 	counts = res; | 
 | 165 |  | 
| Chris Wilson | 85fb3e5 | 2010-01-06 15:39:49 +0000 | [diff] [blame] | 166 | 	if (res.count_fbs) { | 
| Jesse Barnes | 731cd55 | 2008-12-17 10:09:49 -0800 | [diff] [blame] | 167 | 		res.fb_id_ptr = VOID2U64(drmMalloc(res.count_fbs*sizeof(uint32_t))); | 
| Chris Wilson | 85fb3e5 | 2010-01-06 15:39:49 +0000 | [diff] [blame] | 168 | 		if (!res.fb_id_ptr) | 
 | 169 | 			goto err_allocs; | 
 | 170 | 	} | 
 | 171 | 	if (res.count_crtcs) { | 
| Jesse Barnes | 731cd55 | 2008-12-17 10:09:49 -0800 | [diff] [blame] | 172 | 		res.crtc_id_ptr = VOID2U64(drmMalloc(res.count_crtcs*sizeof(uint32_t))); | 
| Chris Wilson | 85fb3e5 | 2010-01-06 15:39:49 +0000 | [diff] [blame] | 173 | 		if (!res.crtc_id_ptr) | 
 | 174 | 			goto err_allocs; | 
 | 175 | 	} | 
 | 176 | 	if (res.count_connectors) { | 
| Jesse Barnes | 731cd55 | 2008-12-17 10:09:49 -0800 | [diff] [blame] | 177 | 		res.connector_id_ptr = VOID2U64(drmMalloc(res.count_connectors*sizeof(uint32_t))); | 
| Chris Wilson | 85fb3e5 | 2010-01-06 15:39:49 +0000 | [diff] [blame] | 178 | 		if (!res.connector_id_ptr) | 
 | 179 | 			goto err_allocs; | 
 | 180 | 	} | 
 | 181 | 	if (res.count_encoders) { | 
| Jesse Barnes | 731cd55 | 2008-12-17 10:09:49 -0800 | [diff] [blame] | 182 | 		res.encoder_id_ptr = VOID2U64(drmMalloc(res.count_encoders*sizeof(uint32_t))); | 
| Chris Wilson | 85fb3e5 | 2010-01-06 15:39:49 +0000 | [diff] [blame] | 183 | 		if (!res.encoder_id_ptr) | 
 | 184 | 			goto err_allocs; | 
 | 185 | 	} | 
| Jesse Barnes | 731cd55 | 2008-12-17 10:09:49 -0800 | [diff] [blame] | 186 |  | 
| Chris Wilson | d1308f4 | 2010-01-06 15:19:25 +0000 | [diff] [blame] | 187 | 	if (drmIoctl(fd, DRM_IOCTL_MODE_GETRESOURCES, &res)) | 
| Jesse Barnes | 731cd55 | 2008-12-17 10:09:49 -0800 | [diff] [blame] | 188 | 		goto err_allocs; | 
| Chris Wilson | d1308f4 | 2010-01-06 15:19:25 +0000 | [diff] [blame] | 189 |  | 
 | 190 | 	/* The number of available connectors and etc may have changed with a | 
 | 191 | 	 * hotplug event in between the ioctls, in which case the field is | 
 | 192 | 	 * silently ignored by the kernel. | 
 | 193 | 	 */ | 
 | 194 | 	if (counts.count_fbs < res.count_fbs || | 
 | 195 | 	    counts.count_crtcs < res.count_crtcs || | 
 | 196 | 	    counts.count_connectors < res.count_connectors || | 
 | 197 | 	    counts.count_encoders < res.count_encoders) | 
 | 198 | 	{ | 
 | 199 | 		drmFree(U642VOID(res.fb_id_ptr)); | 
 | 200 | 		drmFree(U642VOID(res.crtc_id_ptr)); | 
 | 201 | 		drmFree(U642VOID(res.connector_id_ptr)); | 
 | 202 | 		drmFree(U642VOID(res.encoder_id_ptr)); | 
 | 203 |  | 
 | 204 | 		goto retry; | 
| Jesse Barnes | 731cd55 | 2008-12-17 10:09:49 -0800 | [diff] [blame] | 205 | 	} | 
 | 206 |  | 
 | 207 | 	/* | 
 | 208 | 	 * return | 
 | 209 | 	 */ | 
| Jesse Barnes | 731cd55 | 2008-12-17 10:09:49 -0800 | [diff] [blame] | 210 | 	if (!(r = drmMalloc(sizeof(*r)))) | 
| Chris Wilson | d1308f4 | 2010-01-06 15:19:25 +0000 | [diff] [blame] | 211 | 		goto err_allocs; | 
| Jesse Barnes | 731cd55 | 2008-12-17 10:09:49 -0800 | [diff] [blame] | 212 |  | 
 | 213 | 	r->min_width     = res.min_width; | 
 | 214 | 	r->max_width     = res.max_width; | 
 | 215 | 	r->min_height    = res.min_height; | 
 | 216 | 	r->max_height    = res.max_height; | 
 | 217 | 	r->count_fbs     = res.count_fbs; | 
 | 218 | 	r->count_crtcs   = res.count_crtcs; | 
 | 219 | 	r->count_connectors = res.count_connectors; | 
 | 220 | 	r->count_encoders = res.count_encoders; | 
| Chris Wilson | 85fb3e5 | 2010-01-06 15:39:49 +0000 | [diff] [blame] | 221 |  | 
 | 222 | 	r->fbs        = drmAllocCpy(U642VOID(res.fb_id_ptr), res.count_fbs, sizeof(uint32_t)); | 
 | 223 | 	r->crtcs      = drmAllocCpy(U642VOID(res.crtc_id_ptr), res.count_crtcs, sizeof(uint32_t)); | 
 | 224 | 	r->connectors = drmAllocCpy(U642VOID(res.connector_id_ptr), res.count_connectors, sizeof(uint32_t)); | 
 | 225 | 	r->encoders   = drmAllocCpy(U642VOID(res.encoder_id_ptr), res.count_encoders, sizeof(uint32_t)); | 
| Chris Wilson | e6c136c | 2010-01-06 16:53:33 +0000 | [diff] [blame] | 226 | 	if ((res.count_fbs && !r->fbs) || | 
 | 227 | 	    (res.count_crtcs && !r->crtcs) || | 
 | 228 | 	    (res.count_connectors && !r->connectors) || | 
 | 229 | 	    (res.count_encoders && !r->encoders)) | 
 | 230 | 	{ | 
| Chris Wilson | 85fb3e5 | 2010-01-06 15:39:49 +0000 | [diff] [blame] | 231 | 		drmFree(r->fbs); | 
 | 232 | 		drmFree(r->crtcs); | 
 | 233 | 		drmFree(r->connectors); | 
 | 234 | 		drmFree(r->encoders); | 
 | 235 | 		drmFree(r); | 
 | 236 | 		r = 0; | 
 | 237 | 	} | 
| Jesse Barnes | 731cd55 | 2008-12-17 10:09:49 -0800 | [diff] [blame] | 238 |  | 
 | 239 | err_allocs: | 
 | 240 | 	drmFree(U642VOID(res.fb_id_ptr)); | 
 | 241 | 	drmFree(U642VOID(res.crtc_id_ptr)); | 
 | 242 | 	drmFree(U642VOID(res.connector_id_ptr)); | 
 | 243 | 	drmFree(U642VOID(res.encoder_id_ptr)); | 
 | 244 |  | 
 | 245 | 	return r; | 
 | 246 | } | 
 | 247 |  | 
| Lucas De Marchi | 26f9ce5 | 2018-09-13 15:42:26 -0700 | [diff] [blame] | 248 |  | 
 | 249 | drm_public int drmModeAddFB(int fd, uint32_t width, uint32_t height, uint8_t depth, | 
 | 250 |                             uint8_t bpp, uint32_t pitch, uint32_t bo_handle, | 
 | 251 |                             uint32_t *buf_id) | 
| Jesse Barnes | 731cd55 | 2008-12-17 10:09:49 -0800 | [diff] [blame] | 252 | { | 
 | 253 | 	struct drm_mode_fb_cmd f; | 
 | 254 | 	int ret; | 
 | 255 |  | 
| Daniel Vetter | 7e0460c | 2015-02-11 12:03:12 +0100 | [diff] [blame] | 256 | 	memclear(f); | 
| Jesse Barnes | 731cd55 | 2008-12-17 10:09:49 -0800 | [diff] [blame] | 257 | 	f.width  = width; | 
 | 258 | 	f.height = height; | 
 | 259 | 	f.pitch  = pitch; | 
 | 260 | 	f.bpp    = bpp; | 
 | 261 | 	f.depth  = depth; | 
 | 262 | 	f.handle = bo_handle; | 
 | 263 |  | 
| Chris Wilson | b803918 | 2010-07-01 22:38:54 +0100 | [diff] [blame] | 264 | 	if ((ret = DRM_IOCTL(fd, DRM_IOCTL_MODE_ADDFB, &f))) | 
| Jesse Barnes | 731cd55 | 2008-12-17 10:09:49 -0800 | [diff] [blame] | 265 | 		return ret; | 
 | 266 |  | 
 | 267 | 	*buf_id = f.fb_id; | 
 | 268 | 	return 0; | 
 | 269 | } | 
 | 270 |  | 
| Lucas De Marchi | 26f9ce5 | 2018-09-13 15:42:26 -0700 | [diff] [blame] | 271 | drm_public int drmModeAddFB2WithModifiers(int fd, uint32_t width, | 
 | 272 | 		uint32_t height, uint32_t pixel_format, const uint32_t bo_handles[4], | 
 | 273 | 		const uint32_t pitches[4], const uint32_t offsets[4], | 
 | 274 | 		const uint64_t modifier[4], uint32_t *buf_id, uint32_t flags) | 
| Jesse Barnes | ac168bf | 2011-04-29 08:53:53 -0700 | [diff] [blame] | 275 | { | 
 | 276 | 	struct drm_mode_fb_cmd2 f; | 
 | 277 | 	int ret; | 
 | 278 |  | 
| Daniel Vetter | 7e0460c | 2015-02-11 12:03:12 +0100 | [diff] [blame] | 279 | 	memclear(f); | 
| Jesse Barnes | ac168bf | 2011-04-29 08:53:53 -0700 | [diff] [blame] | 280 | 	f.width  = width; | 
 | 281 | 	f.height = height; | 
 | 282 | 	f.pixel_format = pixel_format; | 
 | 283 | 	f.flags = flags; | 
| Ville Syrjälä | 76b4a69 | 2012-02-02 14:53:43 -0500 | [diff] [blame] | 284 | 	memcpy(f.handles, bo_handles, 4 * sizeof(bo_handles[0])); | 
 | 285 | 	memcpy(f.pitches, pitches, 4 * sizeof(pitches[0])); | 
 | 286 | 	memcpy(f.offsets, offsets, 4 * sizeof(offsets[0])); | 
| Kristian H. Kristensen | abfa680 | 2016-09-08 13:08:59 -0700 | [diff] [blame] | 287 | 	if (modifier) | 
 | 288 | 		memcpy(f.modifier, modifier, 4 * sizeof(modifier[0])); | 
| Jesse Barnes | ac168bf | 2011-04-29 08:53:53 -0700 | [diff] [blame] | 289 |  | 
 | 290 | 	if ((ret = DRM_IOCTL(fd, DRM_IOCTL_MODE_ADDFB2, &f))) | 
 | 291 | 		return ret; | 
 | 292 |  | 
 | 293 | 	*buf_id = f.fb_id; | 
 | 294 | 	return 0; | 
 | 295 | } | 
 | 296 |  | 
| Lucas De Marchi | 26f9ce5 | 2018-09-13 15:42:26 -0700 | [diff] [blame] | 297 | drm_public int drmModeAddFB2(int fd, uint32_t width, uint32_t height, | 
 | 298 | 		uint32_t pixel_format, const uint32_t bo_handles[4], | 
 | 299 | 		const uint32_t pitches[4], const uint32_t offsets[4], | 
 | 300 | 		uint32_t *buf_id, uint32_t flags) | 
| Kristian H. Kristensen | abfa680 | 2016-09-08 13:08:59 -0700 | [diff] [blame] | 301 | { | 
 | 302 | 	return drmModeAddFB2WithModifiers(fd, width, height, | 
 | 303 | 					  pixel_format, bo_handles, | 
 | 304 | 					  pitches, offsets, NULL, | 
 | 305 | 					  buf_id, flags); | 
 | 306 | } | 
 | 307 |  | 
| Lucas De Marchi | 26f9ce5 | 2018-09-13 15:42:26 -0700 | [diff] [blame] | 308 | drm_public int drmModeRmFB(int fd, uint32_t bufferId) | 
| Jesse Barnes | 731cd55 | 2008-12-17 10:09:49 -0800 | [diff] [blame] | 309 | { | 
| Chris Wilson | b803918 | 2010-07-01 22:38:54 +0100 | [diff] [blame] | 310 | 	return DRM_IOCTL(fd, DRM_IOCTL_MODE_RMFB, &bufferId); | 
| Jesse Barnes | 731cd55 | 2008-12-17 10:09:49 -0800 | [diff] [blame] | 311 | } | 
 | 312 |  | 
| Lucas De Marchi | 26f9ce5 | 2018-09-13 15:42:26 -0700 | [diff] [blame] | 313 | drm_public drmModeFBPtr drmModeGetFB(int fd, uint32_t buf) | 
| Jesse Barnes | 731cd55 | 2008-12-17 10:09:49 -0800 | [diff] [blame] | 314 | { | 
 | 315 | 	struct drm_mode_fb_cmd info; | 
 | 316 | 	drmModeFBPtr r; | 
 | 317 |  | 
| Daniel Vetter | 7e0460c | 2015-02-11 12:03:12 +0100 | [diff] [blame] | 318 | 	memclear(info); | 
| Jesse Barnes | 731cd55 | 2008-12-17 10:09:49 -0800 | [diff] [blame] | 319 | 	info.fb_id = buf; | 
 | 320 |  | 
 | 321 | 	if (drmIoctl(fd, DRM_IOCTL_MODE_GETFB, &info)) | 
 | 322 | 		return NULL; | 
 | 323 |  | 
 | 324 | 	if (!(r = drmMalloc(sizeof(*r)))) | 
 | 325 | 		return NULL; | 
 | 326 |  | 
 | 327 | 	r->fb_id = info.fb_id; | 
 | 328 | 	r->width = info.width; | 
 | 329 | 	r->height = info.height; | 
 | 330 | 	r->pitch = info.pitch; | 
 | 331 | 	r->bpp = info.bpp; | 
 | 332 | 	r->handle = info.handle; | 
 | 333 | 	r->depth = info.depth; | 
 | 334 |  | 
 | 335 | 	return r; | 
 | 336 | } | 
 | 337 |  | 
| Lucas De Marchi | 26f9ce5 | 2018-09-13 15:42:26 -0700 | [diff] [blame] | 338 | drm_public int drmModeDirtyFB(int fd, uint32_t bufferId, | 
| Jakob Bornecrantz | 3e48613 | 2009-11-24 18:00:12 +0100 | [diff] [blame] | 339 | 		   drmModeClipPtr clips, uint32_t num_clips) | 
 | 340 | { | 
| Daniel Vetter | 7e0460c | 2015-02-11 12:03:12 +0100 | [diff] [blame] | 341 | 	struct drm_mode_fb_dirty_cmd dirty; | 
| Jakob Bornecrantz | 3e48613 | 2009-11-24 18:00:12 +0100 | [diff] [blame] | 342 |  | 
| Daniel Vetter | 7e0460c | 2015-02-11 12:03:12 +0100 | [diff] [blame] | 343 | 	memclear(dirty); | 
| Jakob Bornecrantz | 3e48613 | 2009-11-24 18:00:12 +0100 | [diff] [blame] | 344 | 	dirty.fb_id = bufferId; | 
 | 345 | 	dirty.clips_ptr = VOID2U64(clips); | 
 | 346 | 	dirty.num_clips = num_clips; | 
 | 347 |  | 
| Chris Wilson | b803918 | 2010-07-01 22:38:54 +0100 | [diff] [blame] | 348 | 	return DRM_IOCTL(fd, DRM_IOCTL_MODE_DIRTYFB, &dirty); | 
| Jakob Bornecrantz | 3e48613 | 2009-11-24 18:00:12 +0100 | [diff] [blame] | 349 | } | 
 | 350 |  | 
| Jesse Barnes | 731cd55 | 2008-12-17 10:09:49 -0800 | [diff] [blame] | 351 | /* | 
 | 352 |  * Crtc functions | 
 | 353 |  */ | 
 | 354 |  | 
| Lucas De Marchi | 26f9ce5 | 2018-09-13 15:42:26 -0700 | [diff] [blame] | 355 | drm_public drmModeCrtcPtr drmModeGetCrtc(int fd, uint32_t crtcId) | 
| Jesse Barnes | 731cd55 | 2008-12-17 10:09:49 -0800 | [diff] [blame] | 356 | { | 
 | 357 | 	struct drm_mode_crtc crtc; | 
 | 358 | 	drmModeCrtcPtr r; | 
 | 359 |  | 
| Daniel Vetter | 7e0460c | 2015-02-11 12:03:12 +0100 | [diff] [blame] | 360 | 	memclear(crtc); | 
| Jesse Barnes | 731cd55 | 2008-12-17 10:09:49 -0800 | [diff] [blame] | 361 | 	crtc.crtc_id = crtcId; | 
 | 362 |  | 
 | 363 | 	if (drmIoctl(fd, DRM_IOCTL_MODE_GETCRTC, &crtc)) | 
 | 364 | 		return 0; | 
 | 365 |  | 
 | 366 | 	/* | 
 | 367 | 	 * return | 
 | 368 | 	 */ | 
 | 369 |  | 
 | 370 | 	if (!(r = drmMalloc(sizeof(*r)))) | 
 | 371 | 		return 0; | 
 | 372 |  | 
 | 373 | 	r->crtc_id         = crtc.crtc_id; | 
 | 374 | 	r->x               = crtc.x; | 
 | 375 | 	r->y               = crtc.y; | 
 | 376 | 	r->mode_valid      = crtc.mode_valid; | 
| Rob Clark | e81acf5 | 2012-10-14 16:55:32 -0500 | [diff] [blame] | 377 | 	if (r->mode_valid) { | 
| Jesse Barnes | 731cd55 | 2008-12-17 10:09:49 -0800 | [diff] [blame] | 378 | 		memcpy(&r->mode, &crtc.mode, sizeof(struct drm_mode_modeinfo)); | 
| Rob Clark | e81acf5 | 2012-10-14 16:55:32 -0500 | [diff] [blame] | 379 | 		r->width = crtc.mode.hdisplay; | 
 | 380 | 		r->height = crtc.mode.vdisplay; | 
 | 381 | 	} | 
| Jesse Barnes | 731cd55 | 2008-12-17 10:09:49 -0800 | [diff] [blame] | 382 | 	r->buffer_id       = crtc.fb_id; | 
 | 383 | 	r->gamma_size      = crtc.gamma_size; | 
 | 384 | 	return r; | 
 | 385 | } | 
 | 386 |  | 
| Lucas De Marchi | 26f9ce5 | 2018-09-13 15:42:26 -0700 | [diff] [blame] | 387 | drm_public int drmModeSetCrtc(int fd, uint32_t crtcId, uint32_t bufferId, | 
| Thierry Reding | 5e5a3c4 | 2014-04-09 09:00:49 +0200 | [diff] [blame] | 388 | 		   uint32_t x, uint32_t y, uint32_t *connectors, int count, | 
| Jakob Bornecrantz | eb78c53 | 2009-02-11 16:43:20 +0100 | [diff] [blame] | 389 | 		   drmModeModeInfoPtr mode) | 
| Jesse Barnes | 731cd55 | 2008-12-17 10:09:49 -0800 | [diff] [blame] | 390 | { | 
 | 391 | 	struct drm_mode_crtc crtc; | 
 | 392 |  | 
| Daniel Vetter | 7e0460c | 2015-02-11 12:03:12 +0100 | [diff] [blame] | 393 | 	memclear(crtc); | 
| Jesse Barnes | 731cd55 | 2008-12-17 10:09:49 -0800 | [diff] [blame] | 394 | 	crtc.x             = x; | 
 | 395 | 	crtc.y             = y; | 
 | 396 | 	crtc.crtc_id       = crtcId; | 
 | 397 | 	crtc.fb_id         = bufferId; | 
 | 398 | 	crtc.set_connectors_ptr = VOID2U64(connectors); | 
 | 399 | 	crtc.count_connectors = count; | 
 | 400 | 	if (mode) { | 
 | 401 | 	  memcpy(&crtc.mode, mode, sizeof(struct drm_mode_modeinfo)); | 
 | 402 | 	  crtc.mode_valid = 1; | 
| Daniel Vetter | 7e0460c | 2015-02-11 12:03:12 +0100 | [diff] [blame] | 403 | 	} | 
| Jesse Barnes | 731cd55 | 2008-12-17 10:09:49 -0800 | [diff] [blame] | 404 |  | 
| Chris Wilson | b803918 | 2010-07-01 22:38:54 +0100 | [diff] [blame] | 405 | 	return DRM_IOCTL(fd, DRM_IOCTL_MODE_SETCRTC, &crtc); | 
| Jesse Barnes | 731cd55 | 2008-12-17 10:09:49 -0800 | [diff] [blame] | 406 | } | 
 | 407 |  | 
 | 408 | /* | 
 | 409 |  * Cursor manipulation | 
 | 410 |  */ | 
 | 411 |  | 
| Lucas De Marchi | 26f9ce5 | 2018-09-13 15:42:26 -0700 | [diff] [blame] | 412 | drm_public int drmModeSetCursor(int fd, uint32_t crtcId, uint32_t bo_handle, | 
 | 413 | 								uint32_t width, uint32_t height) | 
| Jesse Barnes | 731cd55 | 2008-12-17 10:09:49 -0800 | [diff] [blame] | 414 | { | 
 | 415 | 	struct drm_mode_cursor arg; | 
 | 416 |  | 
| Daniel Vetter | 7e0460c | 2015-02-11 12:03:12 +0100 | [diff] [blame] | 417 | 	memclear(arg); | 
| Jesse Barnes | 731cd55 | 2008-12-17 10:09:49 -0800 | [diff] [blame] | 418 | 	arg.flags = DRM_MODE_CURSOR_BO; | 
 | 419 | 	arg.crtc_id = crtcId; | 
 | 420 | 	arg.width = width; | 
 | 421 | 	arg.height = height; | 
 | 422 | 	arg.handle = bo_handle; | 
 | 423 |  | 
| Chris Wilson | b803918 | 2010-07-01 22:38:54 +0100 | [diff] [blame] | 424 | 	return DRM_IOCTL(fd, DRM_IOCTL_MODE_CURSOR, &arg); | 
| Jesse Barnes | 731cd55 | 2008-12-17 10:09:49 -0800 | [diff] [blame] | 425 | } | 
 | 426 |  | 
| Lucas De Marchi | 26f9ce5 | 2018-09-13 15:42:26 -0700 | [diff] [blame] | 427 | drm_public int drmModeSetCursor2(int fd, uint32_t crtcId, uint32_t bo_handle, | 
 | 428 | 								 uint32_t width, uint32_t height, int32_t hot_x, | 
 | 429 | 								 int32_t hot_y) | 
| Dave Airlie | 2e0ab62 | 2013-07-02 09:21:06 +0100 | [diff] [blame] | 430 | { | 
 | 431 | 	struct drm_mode_cursor2 arg; | 
 | 432 |  | 
| Daniel Vetter | 7e0460c | 2015-02-11 12:03:12 +0100 | [diff] [blame] | 433 | 	memclear(arg); | 
| Dave Airlie | 2e0ab62 | 2013-07-02 09:21:06 +0100 | [diff] [blame] | 434 | 	arg.flags = DRM_MODE_CURSOR_BO; | 
 | 435 | 	arg.crtc_id = crtcId; | 
 | 436 | 	arg.width = width; | 
 | 437 | 	arg.height = height; | 
 | 438 | 	arg.handle = bo_handle; | 
 | 439 | 	arg.hot_x = hot_x; | 
 | 440 | 	arg.hot_y = hot_y; | 
 | 441 |  | 
 | 442 | 	return DRM_IOCTL(fd, DRM_IOCTL_MODE_CURSOR2, &arg); | 
 | 443 | } | 
 | 444 |  | 
| Lucas De Marchi | 26f9ce5 | 2018-09-13 15:42:26 -0700 | [diff] [blame] | 445 | drm_public int drmModeMoveCursor(int fd, uint32_t crtcId, int x, int y) | 
| Jesse Barnes | 731cd55 | 2008-12-17 10:09:49 -0800 | [diff] [blame] | 446 | { | 
 | 447 | 	struct drm_mode_cursor arg; | 
 | 448 |  | 
| Daniel Vetter | 7e0460c | 2015-02-11 12:03:12 +0100 | [diff] [blame] | 449 | 	memclear(arg); | 
| Jesse Barnes | 731cd55 | 2008-12-17 10:09:49 -0800 | [diff] [blame] | 450 | 	arg.flags = DRM_MODE_CURSOR_MOVE; | 
 | 451 | 	arg.crtc_id = crtcId; | 
 | 452 | 	arg.x = x; | 
 | 453 | 	arg.y = y; | 
 | 454 |  | 
| Chris Wilson | b803918 | 2010-07-01 22:38:54 +0100 | [diff] [blame] | 455 | 	return DRM_IOCTL(fd, DRM_IOCTL_MODE_CURSOR, &arg); | 
| Jesse Barnes | 731cd55 | 2008-12-17 10:09:49 -0800 | [diff] [blame] | 456 | } | 
 | 457 |  | 
 | 458 | /* | 
 | 459 |  * Encoder get | 
 | 460 |  */ | 
| Lucas De Marchi | 26f9ce5 | 2018-09-13 15:42:26 -0700 | [diff] [blame] | 461 | drm_public drmModeEncoderPtr drmModeGetEncoder(int fd, uint32_t encoder_id) | 
| Jesse Barnes | 731cd55 | 2008-12-17 10:09:49 -0800 | [diff] [blame] | 462 | { | 
 | 463 | 	struct drm_mode_get_encoder enc; | 
 | 464 | 	drmModeEncoderPtr r = NULL; | 
 | 465 |  | 
| Daniel Vetter | 7e0460c | 2015-02-11 12:03:12 +0100 | [diff] [blame] | 466 | 	memclear(enc); | 
| Jesse Barnes | 731cd55 | 2008-12-17 10:09:49 -0800 | [diff] [blame] | 467 | 	enc.encoder_id = encoder_id; | 
| Jesse Barnes | 731cd55 | 2008-12-17 10:09:49 -0800 | [diff] [blame] | 468 |  | 
 | 469 | 	if (drmIoctl(fd, DRM_IOCTL_MODE_GETENCODER, &enc)) | 
 | 470 | 		return 0; | 
 | 471 |  | 
 | 472 | 	if (!(r = drmMalloc(sizeof(*r)))) | 
 | 473 | 		return 0; | 
 | 474 |  | 
 | 475 | 	r->encoder_id = enc.encoder_id; | 
 | 476 | 	r->crtc_id = enc.crtc_id; | 
 | 477 | 	r->encoder_type = enc.encoder_type; | 
 | 478 | 	r->possible_crtcs = enc.possible_crtcs; | 
 | 479 | 	r->possible_clones = enc.possible_clones; | 
 | 480 |  | 
 | 481 | 	return r; | 
 | 482 | } | 
 | 483 |  | 
 | 484 | /* | 
 | 485 |  * Connector manipulation | 
 | 486 |  */ | 
| Chris Wilson | 5ed5fa1 | 2015-03-04 10:07:19 +0000 | [diff] [blame] | 487 | static drmModeConnectorPtr | 
 | 488 | _drmModeGetConnector(int fd, uint32_t connector_id, int probe) | 
| Jesse Barnes | 731cd55 | 2008-12-17 10:09:49 -0800 | [diff] [blame] | 489 | { | 
| Peter Clifton | 04f90a4 | 2010-01-06 20:44:11 +0000 | [diff] [blame] | 490 | 	struct drm_mode_get_connector conn, counts; | 
| Jesse Barnes | 731cd55 | 2008-12-17 10:09:49 -0800 | [diff] [blame] | 491 | 	drmModeConnectorPtr r = NULL; | 
| Ville Syrjälä | e342c0f | 2015-12-15 14:18:32 +0200 | [diff] [blame] | 492 | 	struct drm_mode_modeinfo stack_mode; | 
| Jesse Barnes | 731cd55 | 2008-12-17 10:09:49 -0800 | [diff] [blame] | 493 |  | 
| Daniel Vetter | 7e0460c | 2015-02-11 12:03:12 +0100 | [diff] [blame] | 494 | 	memclear(conn); | 
| Jesse Barnes | 731cd55 | 2008-12-17 10:09:49 -0800 | [diff] [blame] | 495 | 	conn.connector_id = connector_id; | 
| Chris Wilson | 5ed5fa1 | 2015-03-04 10:07:19 +0000 | [diff] [blame] | 496 | 	if (!probe) { | 
 | 497 | 		conn.count_modes = 1; | 
| Ville Syrjälä | e342c0f | 2015-12-15 14:18:32 +0200 | [diff] [blame] | 498 | 		conn.modes_ptr = VOID2U64(&stack_mode); | 
| Chris Wilson | 5ed5fa1 | 2015-03-04 10:07:19 +0000 | [diff] [blame] | 499 | 	} | 
| Jesse Barnes | 731cd55 | 2008-12-17 10:09:49 -0800 | [diff] [blame] | 500 |  | 
 | 501 | 	if (drmIoctl(fd, DRM_IOCTL_MODE_GETCONNECTOR, &conn)) | 
 | 502 | 		return 0; | 
 | 503 |  | 
| Chris Wilson | 5ed5fa1 | 2015-03-04 10:07:19 +0000 | [diff] [blame] | 504 | retry: | 
| Peter Clifton | 04f90a4 | 2010-01-06 20:44:11 +0000 | [diff] [blame] | 505 | 	counts = conn; | 
 | 506 |  | 
| Jesse Barnes | 731cd55 | 2008-12-17 10:09:49 -0800 | [diff] [blame] | 507 | 	if (conn.count_props) { | 
 | 508 | 		conn.props_ptr = VOID2U64(drmMalloc(conn.count_props*sizeof(uint32_t))); | 
| Peter Clifton | 04f90a4 | 2010-01-06 20:44:11 +0000 | [diff] [blame] | 509 | 		if (!conn.props_ptr) | 
 | 510 | 			goto err_allocs; | 
| Jesse Barnes | 731cd55 | 2008-12-17 10:09:49 -0800 | [diff] [blame] | 511 | 		conn.prop_values_ptr = VOID2U64(drmMalloc(conn.count_props*sizeof(uint64_t))); | 
| Peter Clifton | 04f90a4 | 2010-01-06 20:44:11 +0000 | [diff] [blame] | 512 | 		if (!conn.prop_values_ptr) | 
 | 513 | 			goto err_allocs; | 
| Jesse Barnes | 731cd55 | 2008-12-17 10:09:49 -0800 | [diff] [blame] | 514 | 	} | 
 | 515 |  | 
| Peter Clifton | 04f90a4 | 2010-01-06 20:44:11 +0000 | [diff] [blame] | 516 | 	if (conn.count_modes) { | 
| Jesse Barnes | 731cd55 | 2008-12-17 10:09:49 -0800 | [diff] [blame] | 517 | 		conn.modes_ptr = VOID2U64(drmMalloc(conn.count_modes*sizeof(struct drm_mode_modeinfo))); | 
| Peter Clifton | 04f90a4 | 2010-01-06 20:44:11 +0000 | [diff] [blame] | 518 | 		if (!conn.modes_ptr) | 
 | 519 | 			goto err_allocs; | 
| Chris Wilson | 5ed5fa1 | 2015-03-04 10:07:19 +0000 | [diff] [blame] | 520 | 	} else { | 
 | 521 | 		conn.count_modes = 1; | 
| Ville Syrjälä | e342c0f | 2015-12-15 14:18:32 +0200 | [diff] [blame] | 522 | 		conn.modes_ptr = VOID2U64(&stack_mode); | 
| Peter Clifton | 04f90a4 | 2010-01-06 20:44:11 +0000 | [diff] [blame] | 523 | 	} | 
| Jesse Barnes | 731cd55 | 2008-12-17 10:09:49 -0800 | [diff] [blame] | 524 |  | 
| Peter Clifton | 04f90a4 | 2010-01-06 20:44:11 +0000 | [diff] [blame] | 525 | 	if (conn.count_encoders) { | 
| Jesse Barnes | 731cd55 | 2008-12-17 10:09:49 -0800 | [diff] [blame] | 526 | 		conn.encoders_ptr = VOID2U64(drmMalloc(conn.count_encoders*sizeof(uint32_t))); | 
| Peter Clifton | 04f90a4 | 2010-01-06 20:44:11 +0000 | [diff] [blame] | 527 | 		if (!conn.encoders_ptr) | 
 | 528 | 			goto err_allocs; | 
 | 529 | 	} | 
| Jesse Barnes | 731cd55 | 2008-12-17 10:09:49 -0800 | [diff] [blame] | 530 |  | 
 | 531 | 	if (drmIoctl(fd, DRM_IOCTL_MODE_GETCONNECTOR, &conn)) | 
 | 532 | 		goto err_allocs; | 
 | 533 |  | 
| Peter Clifton | 04f90a4 | 2010-01-06 20:44:11 +0000 | [diff] [blame] | 534 | 	/* The number of available connectors and etc may have changed with a | 
 | 535 | 	 * hotplug event in between the ioctls, in which case the field is | 
 | 536 | 	 * silently ignored by the kernel. | 
 | 537 | 	 */ | 
 | 538 | 	if (counts.count_props < conn.count_props || | 
 | 539 | 	    counts.count_modes < conn.count_modes || | 
 | 540 | 	    counts.count_encoders < conn.count_encoders) { | 
 | 541 | 		drmFree(U642VOID(conn.props_ptr)); | 
 | 542 | 		drmFree(U642VOID(conn.prop_values_ptr)); | 
| Ville Syrjälä | e342c0f | 2015-12-15 14:18:32 +0200 | [diff] [blame] | 543 | 		if (U642VOID(conn.modes_ptr) != &stack_mode) | 
 | 544 | 			drmFree(U642VOID(conn.modes_ptr)); | 
| Peter Clifton | 04f90a4 | 2010-01-06 20:44:11 +0000 | [diff] [blame] | 545 | 		drmFree(U642VOID(conn.encoders_ptr)); | 
 | 546 |  | 
 | 547 | 		goto retry; | 
 | 548 | 	} | 
 | 549 |  | 
| Jesse Barnes | 731cd55 | 2008-12-17 10:09:49 -0800 | [diff] [blame] | 550 | 	if(!(r = drmMalloc(sizeof(*r)))) { | 
 | 551 | 		goto err_allocs; | 
 | 552 | 	} | 
 | 553 |  | 
 | 554 | 	r->connector_id = conn.connector_id; | 
 | 555 | 	r->encoder_id = conn.encoder_id; | 
 | 556 | 	r->connection   = conn.connection; | 
 | 557 | 	r->mmWidth      = conn.mm_width; | 
 | 558 | 	r->mmHeight     = conn.mm_height; | 
| Dave Airlie | 412d370 | 2009-04-22 20:25:40 +1000 | [diff] [blame] | 559 | 	/* convert subpixel from kernel to userspace */ | 
 | 560 | 	r->subpixel     = conn.subpixel + 1; | 
| Jesse Barnes | 731cd55 | 2008-12-17 10:09:49 -0800 | [diff] [blame] | 561 | 	r->count_modes  = conn.count_modes; | 
| Jesse Barnes | 731cd55 | 2008-12-17 10:09:49 -0800 | [diff] [blame] | 562 | 	r->count_props  = conn.count_props; | 
 | 563 | 	r->props        = drmAllocCpy(U642VOID(conn.props_ptr), conn.count_props, sizeof(uint32_t)); | 
 | 564 | 	r->prop_values  = drmAllocCpy(U642VOID(conn.prop_values_ptr), conn.count_props, sizeof(uint64_t)); | 
 | 565 | 	r->modes        = drmAllocCpy(U642VOID(conn.modes_ptr), conn.count_modes, sizeof(struct drm_mode_modeinfo)); | 
 | 566 | 	r->count_encoders = conn.count_encoders; | 
 | 567 | 	r->encoders     = drmAllocCpy(U642VOID(conn.encoders_ptr), conn.count_encoders, sizeof(uint32_t)); | 
 | 568 | 	r->connector_type  = conn.connector_type; | 
 | 569 | 	r->connector_type_id = conn.connector_type_id; | 
 | 570 |  | 
| Peter Clifton | 04f90a4 | 2010-01-06 20:44:11 +0000 | [diff] [blame] | 571 | 	if ((r->count_props && !r->props) || | 
 | 572 | 	    (r->count_props && !r->prop_values) || | 
 | 573 | 	    (r->count_modes && !r->modes) || | 
 | 574 | 	    (r->count_encoders && !r->encoders)) { | 
 | 575 | 		drmFree(r->props); | 
 | 576 | 		drmFree(r->prop_values); | 
 | 577 | 		drmFree(r->modes); | 
 | 578 | 		drmFree(r->encoders); | 
 | 579 | 		drmFree(r); | 
 | 580 | 		r = 0; | 
 | 581 | 	} | 
| Jesse Barnes | 731cd55 | 2008-12-17 10:09:49 -0800 | [diff] [blame] | 582 |  | 
 | 583 | err_allocs: | 
 | 584 | 	drmFree(U642VOID(conn.prop_values_ptr)); | 
 | 585 | 	drmFree(U642VOID(conn.props_ptr)); | 
| Ville Syrjälä | e342c0f | 2015-12-15 14:18:32 +0200 | [diff] [blame] | 586 | 	if (U642VOID(conn.modes_ptr) != &stack_mode) | 
 | 587 | 		drmFree(U642VOID(conn.modes_ptr)); | 
| Jesse Barnes | 731cd55 | 2008-12-17 10:09:49 -0800 | [diff] [blame] | 588 | 	drmFree(U642VOID(conn.encoders_ptr)); | 
 | 589 |  | 
 | 590 | 	return r; | 
 | 591 | } | 
 | 592 |  | 
| Lucas De Marchi | 26f9ce5 | 2018-09-13 15:42:26 -0700 | [diff] [blame] | 593 | drm_public drmModeConnectorPtr drmModeGetConnector(int fd, uint32_t connector_id) | 
| Chris Wilson | 5ed5fa1 | 2015-03-04 10:07:19 +0000 | [diff] [blame] | 594 | { | 
 | 595 | 	return _drmModeGetConnector(fd, connector_id, 1); | 
 | 596 | } | 
 | 597 |  | 
| Lucas De Marchi | 26f9ce5 | 2018-09-13 15:42:26 -0700 | [diff] [blame] | 598 | drm_public drmModeConnectorPtr drmModeGetConnectorCurrent(int fd, uint32_t connector_id) | 
| Chris Wilson | 5ed5fa1 | 2015-03-04 10:07:19 +0000 | [diff] [blame] | 599 | { | 
 | 600 | 	return _drmModeGetConnector(fd, connector_id, 0); | 
 | 601 | } | 
 | 602 |  | 
| Lucas De Marchi | 26f9ce5 | 2018-09-13 15:42:26 -0700 | [diff] [blame] | 603 | drm_public int drmModeAttachMode(int fd, uint32_t connector_id, drmModeModeInfoPtr mode_info) | 
| Jesse Barnes | 731cd55 | 2008-12-17 10:09:49 -0800 | [diff] [blame] | 604 | { | 
 | 605 | 	struct drm_mode_mode_cmd res; | 
 | 606 |  | 
| Daniel Vetter | 7e0460c | 2015-02-11 12:03:12 +0100 | [diff] [blame] | 607 | 	memclear(res); | 
| Jesse Barnes | 731cd55 | 2008-12-17 10:09:49 -0800 | [diff] [blame] | 608 | 	memcpy(&res.mode, mode_info, sizeof(struct drm_mode_modeinfo)); | 
 | 609 | 	res.connector_id = connector_id; | 
 | 610 |  | 
| Chris Wilson | b803918 | 2010-07-01 22:38:54 +0100 | [diff] [blame] | 611 | 	return DRM_IOCTL(fd, DRM_IOCTL_MODE_ATTACHMODE, &res); | 
| Jesse Barnes | 731cd55 | 2008-12-17 10:09:49 -0800 | [diff] [blame] | 612 | } | 
 | 613 |  | 
| Lucas De Marchi | 26f9ce5 | 2018-09-13 15:42:26 -0700 | [diff] [blame] | 614 | drm_public int drmModeDetachMode(int fd, uint32_t connector_id, drmModeModeInfoPtr mode_info) | 
| Jesse Barnes | 731cd55 | 2008-12-17 10:09:49 -0800 | [diff] [blame] | 615 | { | 
 | 616 | 	struct drm_mode_mode_cmd res; | 
 | 617 |  | 
| Daniel Vetter | 7e0460c | 2015-02-11 12:03:12 +0100 | [diff] [blame] | 618 | 	memclear(res); | 
| Jesse Barnes | 731cd55 | 2008-12-17 10:09:49 -0800 | [diff] [blame] | 619 | 	memcpy(&res.mode, mode_info, sizeof(struct drm_mode_modeinfo)); | 
 | 620 | 	res.connector_id = connector_id; | 
 | 621 |  | 
| Chris Wilson | b803918 | 2010-07-01 22:38:54 +0100 | [diff] [blame] | 622 | 	return DRM_IOCTL(fd, DRM_IOCTL_MODE_DETACHMODE, &res); | 
| Jesse Barnes | 731cd55 | 2008-12-17 10:09:49 -0800 | [diff] [blame] | 623 | } | 
 | 624 |  | 
| Lucas De Marchi | 26f9ce5 | 2018-09-13 15:42:26 -0700 | [diff] [blame] | 625 | drm_public drmModePropertyPtr drmModeGetProperty(int fd, uint32_t property_id) | 
| Jesse Barnes | 731cd55 | 2008-12-17 10:09:49 -0800 | [diff] [blame] | 626 | { | 
 | 627 | 	struct drm_mode_get_property prop; | 
 | 628 | 	drmModePropertyPtr r; | 
 | 629 |  | 
| Daniel Vetter | 7e0460c | 2015-02-11 12:03:12 +0100 | [diff] [blame] | 630 | 	memclear(prop); | 
| Jesse Barnes | 731cd55 | 2008-12-17 10:09:49 -0800 | [diff] [blame] | 631 | 	prop.prop_id = property_id; | 
| Jesse Barnes | 731cd55 | 2008-12-17 10:09:49 -0800 | [diff] [blame] | 632 |  | 
 | 633 | 	if (drmIoctl(fd, DRM_IOCTL_MODE_GETPROPERTY, &prop)) | 
 | 634 | 		return 0; | 
 | 635 |  | 
 | 636 | 	if (prop.count_values) | 
 | 637 | 		prop.values_ptr = VOID2U64(drmMalloc(prop.count_values * sizeof(uint64_t))); | 
 | 638 |  | 
| Rob Clark | 7b228e9 | 2012-06-05 12:28:22 -0500 | [diff] [blame] | 639 | 	if (prop.count_enum_blobs && (prop.flags & (DRM_MODE_PROP_ENUM | DRM_MODE_PROP_BITMASK))) | 
| Jesse Barnes | 731cd55 | 2008-12-17 10:09:49 -0800 | [diff] [blame] | 640 | 		prop.enum_blob_ptr = VOID2U64(drmMalloc(prop.count_enum_blobs * sizeof(struct drm_mode_property_enum))); | 
 | 641 |  | 
 | 642 | 	if (prop.count_enum_blobs && (prop.flags & DRM_MODE_PROP_BLOB)) { | 
 | 643 | 		prop.values_ptr = VOID2U64(drmMalloc(prop.count_enum_blobs * sizeof(uint32_t))); | 
 | 644 | 		prop.enum_blob_ptr = VOID2U64(drmMalloc(prop.count_enum_blobs * sizeof(uint32_t))); | 
 | 645 | 	} | 
 | 646 |  | 
 | 647 | 	if (drmIoctl(fd, DRM_IOCTL_MODE_GETPROPERTY, &prop)) { | 
 | 648 | 		r = NULL; | 
 | 649 | 		goto err_allocs; | 
 | 650 | 	} | 
 | 651 |  | 
 | 652 | 	if (!(r = drmMalloc(sizeof(*r)))) | 
| Seung-Woo Kim | b39377d | 2019-04-29 18:10:52 +0900 | [diff] [blame] | 653 | 		goto err_allocs; | 
| Jesse Barnes | 731cd55 | 2008-12-17 10:09:49 -0800 | [diff] [blame] | 654 |  | 
 | 655 | 	r->prop_id = prop.prop_id; | 
 | 656 | 	r->count_values = prop.count_values; | 
 | 657 |  | 
 | 658 | 	r->flags = prop.flags; | 
 | 659 | 	if (prop.count_values) | 
 | 660 | 		r->values = drmAllocCpy(U642VOID(prop.values_ptr), prop.count_values, sizeof(uint64_t)); | 
| Rob Clark | 7b228e9 | 2012-06-05 12:28:22 -0500 | [diff] [blame] | 661 | 	if (prop.flags & (DRM_MODE_PROP_ENUM | DRM_MODE_PROP_BITMASK)) { | 
| Jesse Barnes | 731cd55 | 2008-12-17 10:09:49 -0800 | [diff] [blame] | 662 | 		r->count_enums = prop.count_enum_blobs; | 
 | 663 | 		r->enums = drmAllocCpy(U642VOID(prop.enum_blob_ptr), prop.count_enum_blobs, sizeof(struct drm_mode_property_enum)); | 
 | 664 | 	} else if (prop.flags & DRM_MODE_PROP_BLOB) { | 
 | 665 | 		r->values = drmAllocCpy(U642VOID(prop.values_ptr), prop.count_enum_blobs, sizeof(uint32_t)); | 
 | 666 | 		r->blob_ids = drmAllocCpy(U642VOID(prop.enum_blob_ptr), prop.count_enum_blobs, sizeof(uint32_t)); | 
 | 667 | 		r->count_blobs = prop.count_enum_blobs; | 
 | 668 | 	} | 
 | 669 | 	strncpy(r->name, prop.name, DRM_PROP_NAME_LEN); | 
 | 670 | 	r->name[DRM_PROP_NAME_LEN-1] = 0; | 
 | 671 |  | 
 | 672 | err_allocs: | 
 | 673 | 	drmFree(U642VOID(prop.values_ptr)); | 
 | 674 | 	drmFree(U642VOID(prop.enum_blob_ptr)); | 
 | 675 |  | 
 | 676 | 	return r; | 
 | 677 | } | 
 | 678 |  | 
| Lucas De Marchi | 26f9ce5 | 2018-09-13 15:42:26 -0700 | [diff] [blame] | 679 | drm_public void drmModeFreeProperty(drmModePropertyPtr ptr) | 
| Jesse Barnes | 731cd55 | 2008-12-17 10:09:49 -0800 | [diff] [blame] | 680 | { | 
 | 681 | 	if (!ptr) | 
 | 682 | 		return; | 
 | 683 |  | 
 | 684 | 	drmFree(ptr->values); | 
 | 685 | 	drmFree(ptr->enums); | 
 | 686 | 	drmFree(ptr); | 
 | 687 | } | 
 | 688 |  | 
| Lucas De Marchi | 26f9ce5 | 2018-09-13 15:42:26 -0700 | [diff] [blame] | 689 | drm_public drmModePropertyBlobPtr drmModeGetPropertyBlob(int fd, | 
 | 690 | 														 uint32_t blob_id) | 
| Jesse Barnes | 731cd55 | 2008-12-17 10:09:49 -0800 | [diff] [blame] | 691 | { | 
 | 692 | 	struct drm_mode_get_blob blob; | 
 | 693 | 	drmModePropertyBlobPtr r; | 
 | 694 |  | 
| Daniel Vetter | 7e0460c | 2015-02-11 12:03:12 +0100 | [diff] [blame] | 695 | 	memclear(blob); | 
| Jesse Barnes | 731cd55 | 2008-12-17 10:09:49 -0800 | [diff] [blame] | 696 | 	blob.blob_id = blob_id; | 
 | 697 |  | 
 | 698 | 	if (drmIoctl(fd, DRM_IOCTL_MODE_GETPROPBLOB, &blob)) | 
 | 699 | 		return NULL; | 
 | 700 |  | 
 | 701 | 	if (blob.length) | 
 | 702 | 		blob.data = VOID2U64(drmMalloc(blob.length)); | 
 | 703 |  | 
 | 704 | 	if (drmIoctl(fd, DRM_IOCTL_MODE_GETPROPBLOB, &blob)) { | 
 | 705 | 		r = NULL; | 
 | 706 | 		goto err_allocs; | 
 | 707 | 	} | 
 | 708 |  | 
 | 709 | 	if (!(r = drmMalloc(sizeof(*r)))) | 
| Chris Wilson | 8a76244 | 2010-08-24 21:29:31 +0100 | [diff] [blame] | 710 | 		goto err_allocs; | 
| Jesse Barnes | 731cd55 | 2008-12-17 10:09:49 -0800 | [diff] [blame] | 711 |  | 
 | 712 | 	r->id = blob.blob_id; | 
 | 713 | 	r->length = blob.length; | 
 | 714 | 	r->data = drmAllocCpy(U642VOID(blob.data), 1, blob.length); | 
 | 715 |  | 
 | 716 | err_allocs: | 
 | 717 | 	drmFree(U642VOID(blob.data)); | 
 | 718 | 	return r; | 
 | 719 | } | 
 | 720 |  | 
| Lucas De Marchi | 26f9ce5 | 2018-09-13 15:42:26 -0700 | [diff] [blame] | 721 | drm_public void drmModeFreePropertyBlob(drmModePropertyBlobPtr ptr) | 
| Jesse Barnes | 731cd55 | 2008-12-17 10:09:49 -0800 | [diff] [blame] | 722 | { | 
 | 723 | 	if (!ptr) | 
 | 724 | 		return; | 
 | 725 |  | 
 | 726 | 	drmFree(ptr->data); | 
 | 727 | 	drmFree(ptr); | 
 | 728 | } | 
 | 729 |  | 
| Lucas De Marchi | 26f9ce5 | 2018-09-13 15:42:26 -0700 | [diff] [blame] | 730 | drm_public int drmModeConnectorSetProperty(int fd, uint32_t connector_id, | 
 | 731 | 										   uint32_t property_id, | 
 | 732 | 										   uint64_t value) | 
| Jesse Barnes | 731cd55 | 2008-12-17 10:09:49 -0800 | [diff] [blame] | 733 | { | 
 | 734 | 	struct drm_mode_connector_set_property osp; | 
| Jesse Barnes | 731cd55 | 2008-12-17 10:09:49 -0800 | [diff] [blame] | 735 |  | 
| Daniel Vetter | 7e0460c | 2015-02-11 12:03:12 +0100 | [diff] [blame] | 736 | 	memclear(osp); | 
| Jesse Barnes | 731cd55 | 2008-12-17 10:09:49 -0800 | [diff] [blame] | 737 | 	osp.connector_id = connector_id; | 
 | 738 | 	osp.prop_id = property_id; | 
 | 739 | 	osp.value = value; | 
 | 740 |  | 
| Chris Wilson | b803918 | 2010-07-01 22:38:54 +0100 | [diff] [blame] | 741 | 	return DRM_IOCTL(fd, DRM_IOCTL_MODE_SETPROPERTY, &osp); | 
| Jesse Barnes | 731cd55 | 2008-12-17 10:09:49 -0800 | [diff] [blame] | 742 | } | 
 | 743 |  | 
 | 744 | /* | 
 | 745 |  * checks if a modesetting capable driver has attached to the pci id | 
 | 746 |  * returns 0 if modesetting supported. | 
 | 747 |  *  -EINVAL or invalid bus id | 
 | 748 |  *  -ENOSYS if no modesetting support | 
 | 749 | */ | 
| Lucas De Marchi | 26f9ce5 | 2018-09-13 15:42:26 -0700 | [diff] [blame] | 750 | drm_public int drmCheckModesettingSupported(const char *busid) | 
| Jesse Barnes | 731cd55 | 2008-12-17 10:09:49 -0800 | [diff] [blame] | 751 | { | 
| Robert Millan | cbb31f2 | 2014-01-23 14:46:05 +0000 | [diff] [blame] | 752 | #if defined (__linux__) | 
| Jesse Barnes | 731cd55 | 2008-12-17 10:09:49 -0800 | [diff] [blame] | 753 | 	char pci_dev_dir[1024]; | 
 | 754 | 	int domain, bus, dev, func; | 
 | 755 | 	DIR *sysdir; | 
 | 756 | 	struct dirent *dent; | 
 | 757 | 	int found = 0, ret; | 
 | 758 |  | 
 | 759 | 	ret = sscanf(busid, "pci:%04x:%02x:%02x.%d", &domain, &bus, &dev, &func); | 
 | 760 | 	if (ret != 4) | 
 | 761 | 		return -EINVAL; | 
 | 762 |  | 
 | 763 | 	sprintf(pci_dev_dir, "/sys/bus/pci/devices/%04x:%02x:%02x.%d/drm", | 
 | 764 | 		domain, bus, dev, func); | 
 | 765 |  | 
 | 766 | 	sysdir = opendir(pci_dev_dir); | 
 | 767 | 	if (sysdir) { | 
 | 768 | 		dent = readdir(sysdir); | 
 | 769 | 		while (dent) { | 
 | 770 | 			if (!strncmp(dent->d_name, "controlD", 8)) { | 
 | 771 | 				found = 1; | 
 | 772 | 				break; | 
 | 773 | 			} | 
 | 774 |  | 
 | 775 | 			dent = readdir(sysdir); | 
 | 776 | 		} | 
 | 777 | 		closedir(sysdir); | 
 | 778 | 		if (found) | 
 | 779 | 			return 0; | 
 | 780 | 	} | 
 | 781 |  | 
 | 782 | 	sprintf(pci_dev_dir, "/sys/bus/pci/devices/%04x:%02x:%02x.%d/", | 
 | 783 | 		domain, bus, dev, func); | 
 | 784 |  | 
 | 785 | 	sysdir = opendir(pci_dev_dir); | 
 | 786 | 	if (!sysdir) | 
 | 787 | 		return -EINVAL; | 
 | 788 |  | 
 | 789 | 	dent = readdir(sysdir); | 
 | 790 | 	while (dent) { | 
 | 791 | 		if (!strncmp(dent->d_name, "drm:controlD", 12)) { | 
 | 792 | 			found = 1; | 
 | 793 | 			break; | 
 | 794 | 		} | 
 | 795 |  | 
 | 796 | 		dent = readdir(sysdir); | 
 | 797 | 	} | 
 | 798 |  | 
 | 799 | 	closedir(sysdir); | 
 | 800 | 	if (found) | 
 | 801 | 		return 0; | 
| Robert Millan | cbb31f2 | 2014-01-23 14:46:05 +0000 | [diff] [blame] | 802 | #elif defined (__FreeBSD__) || defined (__FreeBSD_kernel__) | 
 | 803 | 	char kbusid[1024], sbusid[1024]; | 
 | 804 | 	char oid[128]; | 
 | 805 | 	int domain, bus, dev, func; | 
 | 806 | 	int i, modesetting, ret; | 
 | 807 | 	size_t len; | 
 | 808 |  | 
 | 809 | 	ret = sscanf(busid, "pci:%04x:%02x:%02x.%d", &domain, &bus, &dev, | 
 | 810 | 	    &func); | 
 | 811 | 	if (ret != 4) | 
 | 812 | 		return -EINVAL; | 
 | 813 | 	snprintf(kbusid, sizeof(kbusid), "pci:%04x:%02x:%02x.%d", domain, bus, | 
 | 814 | 	    dev, func); | 
 | 815 |  | 
 | 816 | 	/* How many GPUs do we expect in the machine ? */ | 
 | 817 | 	for (i = 0; i < 16; i++) { | 
 | 818 | 		snprintf(oid, sizeof(oid), "hw.dri.%d.busid", i); | 
 | 819 | 		len = sizeof(sbusid); | 
 | 820 | 		ret = sysctlbyname(oid, sbusid, &len, NULL, 0); | 
 | 821 | 		if (ret == -1) { | 
 | 822 | 			if (errno == ENOENT) | 
 | 823 | 				continue; | 
 | 824 | 			return -EINVAL; | 
 | 825 | 		} | 
 | 826 | 		if (strcmp(sbusid, kbusid) != 0) | 
 | 827 | 			continue; | 
 | 828 | 		snprintf(oid, sizeof(oid), "hw.dri.%d.modesetting", i); | 
 | 829 | 		len = sizeof(modesetting); | 
 | 830 | 		ret = sysctlbyname(oid, &modesetting, &len, NULL, 0); | 
 | 831 | 		if (ret == -1 || len != sizeof(modesetting)) | 
 | 832 | 			return -EINVAL; | 
 | 833 | 		return (modesetting ? 0 : -ENOSYS); | 
 | 834 | 	} | 
| François Tigeot | edbb4e5 | 2014-07-26 13:39:58 +0200 | [diff] [blame] | 835 | #elif defined(__DragonFly__) | 
 | 836 | 	return 0; | 
| Eric Engestrom | 00aa374 | 2018-03-22 17:08:37 +0000 | [diff] [blame] | 837 | #elif defined(__OpenBSD__) | 
| Jonathan Gray | 1d3b823 | 2015-07-19 07:20:37 +1000 | [diff] [blame] | 838 | 	int	fd; | 
 | 839 | 	struct drm_mode_card_res res; | 
 | 840 | 	drmModeResPtr r = 0; | 
| Jesse Barnes | 731cd55 | 2008-12-17 10:09:49 -0800 | [diff] [blame] | 841 |  | 
| Jonathan Gray | 1d3b823 | 2015-07-19 07:20:37 +1000 | [diff] [blame] | 842 | 	if ((fd = drmOpen(NULL, busid)) < 0) | 
 | 843 | 		return -EINVAL; | 
 | 844 |  | 
 | 845 | 	memset(&res, 0, sizeof(struct drm_mode_card_res)); | 
 | 846 |  | 
 | 847 | 	if (drmIoctl(fd, DRM_IOCTL_MODE_GETRESOURCES, &res)) { | 
 | 848 | 		drmClose(fd); | 
 | 849 | 		return -errno; | 
 | 850 | 	} | 
 | 851 |  | 
 | 852 | 	drmClose(fd); | 
 | 853 | 	return 0; | 
 | 854 | #endif | 
 | 855 | 	return -ENOSYS; | 
| Jesse Barnes | 731cd55 | 2008-12-17 10:09:49 -0800 | [diff] [blame] | 856 | } | 
 | 857 |  | 
| Lucas De Marchi | 26f9ce5 | 2018-09-13 15:42:26 -0700 | [diff] [blame] | 858 | drm_public int drmModeCrtcGetGamma(int fd, uint32_t crtc_id, uint32_t size, | 
 | 859 | 								   uint16_t *red, uint16_t *green, | 
 | 860 | 								   uint16_t *blue) | 
| Jesse Barnes | 731cd55 | 2008-12-17 10:09:49 -0800 | [diff] [blame] | 861 | { | 
| Jesse Barnes | 731cd55 | 2008-12-17 10:09:49 -0800 | [diff] [blame] | 862 | 	struct drm_mode_crtc_lut l; | 
 | 863 |  | 
| Daniel Vetter | 7e0460c | 2015-02-11 12:03:12 +0100 | [diff] [blame] | 864 | 	memclear(l); | 
| Jesse Barnes | 731cd55 | 2008-12-17 10:09:49 -0800 | [diff] [blame] | 865 | 	l.crtc_id = crtc_id; | 
 | 866 | 	l.gamma_size = size; | 
 | 867 | 	l.red = VOID2U64(red); | 
 | 868 | 	l.green = VOID2U64(green); | 
 | 869 | 	l.blue = VOID2U64(blue); | 
 | 870 |  | 
| Chris Wilson | b803918 | 2010-07-01 22:38:54 +0100 | [diff] [blame] | 871 | 	return DRM_IOCTL(fd, DRM_IOCTL_MODE_GETGAMMA, &l); | 
| Jesse Barnes | 731cd55 | 2008-12-17 10:09:49 -0800 | [diff] [blame] | 872 | } | 
 | 873 |  | 
| Lucas De Marchi | 26f9ce5 | 2018-09-13 15:42:26 -0700 | [diff] [blame] | 874 | drm_public int drmModeCrtcSetGamma(int fd, uint32_t crtc_id, uint32_t size, | 
 | 875 | 								   uint16_t *red, uint16_t *green, | 
 | 876 | 								   uint16_t *blue) | 
| Jesse Barnes | 731cd55 | 2008-12-17 10:09:49 -0800 | [diff] [blame] | 877 | { | 
| Jesse Barnes | 731cd55 | 2008-12-17 10:09:49 -0800 | [diff] [blame] | 878 | 	struct drm_mode_crtc_lut l; | 
 | 879 |  | 
| Daniel Vetter | 7e0460c | 2015-02-11 12:03:12 +0100 | [diff] [blame] | 880 | 	memclear(l); | 
| Jesse Barnes | 731cd55 | 2008-12-17 10:09:49 -0800 | [diff] [blame] | 881 | 	l.crtc_id = crtc_id; | 
 | 882 | 	l.gamma_size = size; | 
 | 883 | 	l.red = VOID2U64(red); | 
 | 884 | 	l.green = VOID2U64(green); | 
 | 885 | 	l.blue = VOID2U64(blue); | 
 | 886 |  | 
| Chris Wilson | b803918 | 2010-07-01 22:38:54 +0100 | [diff] [blame] | 887 | 	return DRM_IOCTL(fd, DRM_IOCTL_MODE_SETGAMMA, &l); | 
| Jesse Barnes | 731cd55 | 2008-12-17 10:09:49 -0800 | [diff] [blame] | 888 | } | 
| Kristian Høgsberg | b0b9663 | 2009-09-11 13:27:35 -0400 | [diff] [blame] | 889 |  | 
| Lucas De Marchi | 26f9ce5 | 2018-09-13 15:42:26 -0700 | [diff] [blame] | 890 | drm_public int drmHandleEvent(int fd, drmEventContextPtr evctx) | 
| Kristian Høgsberg | b0b9663 | 2009-09-11 13:27:35 -0400 | [diff] [blame] | 891 | { | 
 | 892 | 	char buffer[1024]; | 
 | 893 | 	int len, i; | 
 | 894 | 	struct drm_event *e; | 
 | 895 | 	struct drm_event_vblank *vblank; | 
| Keith Packard | d4331dd | 2017-07-01 00:43:15 -0700 | [diff] [blame] | 896 | 	struct drm_event_crtc_sequence *seq; | 
| Ander Conselvan de Oliveira | 890d43a | 2015-08-17 16:21:24 +0300 | [diff] [blame] | 897 | 	void *user_data; | 
| Hyungwon Hwang | 4bac035 | 2015-08-19 09:58:39 +0900 | [diff] [blame] | 898 |  | 
| Kristian Høgsberg | b0b9663 | 2009-09-11 13:27:35 -0400 | [diff] [blame] | 899 | 	/* The DRM read semantics guarantees that we always get only | 
 | 900 | 	 * complete events. */ | 
 | 901 |  | 
 | 902 | 	len = read(fd, buffer, sizeof buffer); | 
 | 903 | 	if (len == 0) | 
 | 904 | 		return 0; | 
| Jan Vesely | de8532d | 2014-11-30 12:53:18 -0500 | [diff] [blame] | 905 | 	if (len < (int)sizeof *e) | 
| Kristian Høgsberg | b0b9663 | 2009-09-11 13:27:35 -0400 | [diff] [blame] | 906 | 		return -1; | 
 | 907 |  | 
 | 908 | 	i = 0; | 
 | 909 | 	while (i < len) { | 
| Thierry Reding | ecc2a09 | 2015-04-13 11:36:59 +0200 | [diff] [blame] | 910 | 		e = (struct drm_event *)(buffer + i); | 
| Kristian Høgsberg | b0b9663 | 2009-09-11 13:27:35 -0400 | [diff] [blame] | 911 | 		switch (e->type) { | 
 | 912 | 		case DRM_EVENT_VBLANK: | 
 | 913 | 			if (evctx->version < 1 || | 
 | 914 | 			    evctx->vblank_handler == NULL) | 
 | 915 | 				break; | 
 | 916 | 			vblank = (struct drm_event_vblank *) e; | 
 | 917 | 			evctx->vblank_handler(fd, | 
| Hyungwon Hwang | 4bac035 | 2015-08-19 09:58:39 +0900 | [diff] [blame] | 918 | 					      vblank->sequence, | 
| Kristian Høgsberg | b0b9663 | 2009-09-11 13:27:35 -0400 | [diff] [blame] | 919 | 					      vblank->tv_sec, | 
 | 920 | 					      vblank->tv_usec, | 
 | 921 | 					      U642VOID (vblank->user_data)); | 
 | 922 | 			break; | 
| Kristian Høgsberg | b80bcff | 2009-11-12 14:06:45 -0500 | [diff] [blame] | 923 | 		case DRM_EVENT_FLIP_COMPLETE: | 
| Kristian Høgsberg | b80bcff | 2009-11-12 14:06:45 -0500 | [diff] [blame] | 924 | 			vblank = (struct drm_event_vblank *) e; | 
| Ander Conselvan de Oliveira | 890d43a | 2015-08-17 16:21:24 +0300 | [diff] [blame] | 925 | 			user_data = U642VOID (vblank->user_data); | 
 | 926 |  | 
 | 927 | 			if (evctx->version >= 3 && evctx->page_flip_handler2) | 
 | 928 | 				evctx->page_flip_handler2(fd, | 
 | 929 | 							 vblank->sequence, | 
 | 930 | 							 vblank->tv_sec, | 
 | 931 | 							 vblank->tv_usec, | 
 | 932 | 							 vblank->crtc_id, | 
 | 933 | 							 user_data); | 
 | 934 | 			else if (evctx->version >= 2 && evctx->page_flip_handler) | 
 | 935 | 				evctx->page_flip_handler(fd, | 
 | 936 | 							 vblank->sequence, | 
 | 937 | 							 vblank->tv_sec, | 
 | 938 | 							 vblank->tv_usec, | 
 | 939 | 							 user_data); | 
| Kristian Høgsberg | b80bcff | 2009-11-12 14:06:45 -0500 | [diff] [blame] | 940 | 			break; | 
| Keith Packard | d4331dd | 2017-07-01 00:43:15 -0700 | [diff] [blame] | 941 | 		case DRM_EVENT_CRTC_SEQUENCE: | 
 | 942 | 			seq = (struct drm_event_crtc_sequence *) e; | 
 | 943 | 			if (evctx->version >= 4 && evctx->sequence_handler) | 
 | 944 | 				evctx->sequence_handler(fd, | 
 | 945 | 							seq->sequence, | 
 | 946 | 							seq->time_ns, | 
 | 947 | 							seq->user_data); | 
 | 948 | 			break; | 
| Kristian Høgsberg | b0b9663 | 2009-09-11 13:27:35 -0400 | [diff] [blame] | 949 | 		default: | 
 | 950 | 			break; | 
 | 951 | 		} | 
 | 952 | 		i += e->length; | 
 | 953 | 	} | 
 | 954 |  | 
 | 955 | 	return 0; | 
 | 956 | } | 
 | 957 |  | 
| Lucas De Marchi | 26f9ce5 | 2018-09-13 15:42:26 -0700 | [diff] [blame] | 958 | drm_public int drmModePageFlip(int fd, uint32_t crtc_id, uint32_t fb_id, | 
| Kristian Høgsberg | b80bcff | 2009-11-12 14:06:45 -0500 | [diff] [blame] | 959 | 		    uint32_t flags, void *user_data) | 
 | 960 | { | 
 | 961 | 	struct drm_mode_crtc_page_flip flip; | 
 | 962 |  | 
| Daniel Vetter | 7e0460c | 2015-02-11 12:03:12 +0100 | [diff] [blame] | 963 | 	memclear(flip); | 
| Kristian Høgsberg | b80bcff | 2009-11-12 14:06:45 -0500 | [diff] [blame] | 964 | 	flip.fb_id = fb_id; | 
 | 965 | 	flip.crtc_id = crtc_id; | 
 | 966 | 	flip.user_data = VOID2U64(user_data); | 
 | 967 | 	flip.flags = flags; | 
| Kristian Høgsberg | b80bcff | 2009-11-12 14:06:45 -0500 | [diff] [blame] | 968 |  | 
| Chris Wilson | b803918 | 2010-07-01 22:38:54 +0100 | [diff] [blame] | 969 | 	return DRM_IOCTL(fd, DRM_IOCTL_MODE_PAGE_FLIP, &flip); | 
| Kristian Høgsberg | b80bcff | 2009-11-12 14:06:45 -0500 | [diff] [blame] | 970 | } | 
| Jesse Barnes | ac168bf | 2011-04-29 08:53:53 -0700 | [diff] [blame] | 971 |  | 
| Lucas De Marchi | 26f9ce5 | 2018-09-13 15:42:26 -0700 | [diff] [blame] | 972 | drm_public int drmModePageFlipTarget(int fd, uint32_t crtc_id, uint32_t fb_id, | 
| Michel Dänzer | 7dd2847 | 2016-06-29 18:07:25 +0900 | [diff] [blame] | 973 | 			  uint32_t flags, void *user_data, | 
 | 974 | 			  uint32_t target_vblank) | 
 | 975 | { | 
 | 976 | 	struct drm_mode_crtc_page_flip_target flip_target; | 
 | 977 |  | 
 | 978 | 	memclear(flip_target); | 
 | 979 | 	flip_target.fb_id = fb_id; | 
 | 980 | 	flip_target.crtc_id = crtc_id; | 
 | 981 | 	flip_target.user_data = VOID2U64(user_data); | 
 | 982 | 	flip_target.flags = flags; | 
 | 983 | 	flip_target.sequence = target_vblank; | 
 | 984 |  | 
 | 985 | 	return DRM_IOCTL(fd, DRM_IOCTL_MODE_PAGE_FLIP, &flip_target); | 
 | 986 | } | 
 | 987 |  | 
| Lucas De Marchi | 26f9ce5 | 2018-09-13 15:42:26 -0700 | [diff] [blame] | 988 | drm_public int drmModeSetPlane(int fd, uint32_t plane_id, uint32_t crtc_id, | 
| Jesse Barnes | ac168bf | 2011-04-29 08:53:53 -0700 | [diff] [blame] | 989 | 		    uint32_t fb_id, uint32_t flags, | 
| Daniel Kurtz | 828c3e8 | 2014-05-01 19:56:43 +0800 | [diff] [blame] | 990 | 		    int32_t crtc_x, int32_t crtc_y, | 
| Jesse Barnes | ac168bf | 2011-04-29 08:53:53 -0700 | [diff] [blame] | 991 | 		    uint32_t crtc_w, uint32_t crtc_h, | 
 | 992 | 		    uint32_t src_x, uint32_t src_y, | 
 | 993 | 		    uint32_t src_w, uint32_t src_h) | 
| Jesse Barnes | ac168bf | 2011-04-29 08:53:53 -0700 | [diff] [blame] | 994 | { | 
 | 995 | 	struct drm_mode_set_plane s; | 
 | 996 |  | 
| Daniel Vetter | 7e0460c | 2015-02-11 12:03:12 +0100 | [diff] [blame] | 997 | 	memclear(s); | 
| Jesse Barnes | ac168bf | 2011-04-29 08:53:53 -0700 | [diff] [blame] | 998 | 	s.plane_id = plane_id; | 
 | 999 | 	s.crtc_id = crtc_id; | 
 | 1000 | 	s.fb_id = fb_id; | 
 | 1001 | 	s.flags = flags; | 
 | 1002 | 	s.crtc_x = crtc_x; | 
 | 1003 | 	s.crtc_y = crtc_y; | 
 | 1004 | 	s.crtc_w = crtc_w; | 
 | 1005 | 	s.crtc_h = crtc_h; | 
 | 1006 | 	s.src_x = src_x; | 
 | 1007 | 	s.src_y = src_y; | 
 | 1008 | 	s.src_w = src_w; | 
 | 1009 | 	s.src_h = src_h; | 
 | 1010 |  | 
 | 1011 | 	return DRM_IOCTL(fd, DRM_IOCTL_MODE_SETPLANE, &s); | 
 | 1012 | } | 
 | 1013 |  | 
| Lucas De Marchi | 26f9ce5 | 2018-09-13 15:42:26 -0700 | [diff] [blame] | 1014 | drm_public drmModePlanePtr drmModeGetPlane(int fd, uint32_t plane_id) | 
| Jesse Barnes | ac168bf | 2011-04-29 08:53:53 -0700 | [diff] [blame] | 1015 | { | 
 | 1016 | 	struct drm_mode_get_plane ovr, counts; | 
 | 1017 | 	drmModePlanePtr r = 0; | 
 | 1018 |  | 
 | 1019 | retry: | 
| Daniel Vetter | 7e0460c | 2015-02-11 12:03:12 +0100 | [diff] [blame] | 1020 | 	memclear(ovr); | 
| Jesse Barnes | ac168bf | 2011-04-29 08:53:53 -0700 | [diff] [blame] | 1021 | 	ovr.plane_id = plane_id; | 
 | 1022 | 	if (drmIoctl(fd, DRM_IOCTL_MODE_GETPLANE, &ovr)) | 
 | 1023 | 		return 0; | 
 | 1024 |  | 
 | 1025 | 	counts = ovr; | 
 | 1026 |  | 
 | 1027 | 	if (ovr.count_format_types) { | 
 | 1028 | 		ovr.format_type_ptr = VOID2U64(drmMalloc(ovr.count_format_types * | 
 | 1029 | 							 sizeof(uint32_t))); | 
 | 1030 | 		if (!ovr.format_type_ptr) | 
 | 1031 | 			goto err_allocs; | 
 | 1032 | 	} | 
 | 1033 |  | 
 | 1034 | 	if (drmIoctl(fd, DRM_IOCTL_MODE_GETPLANE, &ovr)) | 
 | 1035 | 		goto err_allocs; | 
 | 1036 |  | 
 | 1037 | 	if (counts.count_format_types < ovr.count_format_types) { | 
 | 1038 | 		drmFree(U642VOID(ovr.format_type_ptr)); | 
 | 1039 | 		goto retry; | 
 | 1040 | 	} | 
 | 1041 |  | 
 | 1042 | 	if (!(r = drmMalloc(sizeof(*r)))) | 
 | 1043 | 		goto err_allocs; | 
 | 1044 |  | 
 | 1045 | 	r->count_formats = ovr.count_format_types; | 
 | 1046 | 	r->plane_id = ovr.plane_id; | 
 | 1047 | 	r->crtc_id = ovr.crtc_id; | 
 | 1048 | 	r->fb_id = ovr.fb_id; | 
 | 1049 | 	r->possible_crtcs = ovr.possible_crtcs; | 
 | 1050 | 	r->gamma_size = ovr.gamma_size; | 
 | 1051 | 	r->formats = drmAllocCpy(U642VOID(ovr.format_type_ptr), | 
 | 1052 | 				 ovr.count_format_types, sizeof(uint32_t)); | 
 | 1053 | 	if (ovr.count_format_types && !r->formats) { | 
 | 1054 | 		drmFree(r->formats); | 
| Ville Syrjälä | df497e9 | 2012-02-02 14:53:39 -0500 | [diff] [blame] | 1055 | 		drmFree(r); | 
| Jesse Barnes | ac168bf | 2011-04-29 08:53:53 -0700 | [diff] [blame] | 1056 | 		r = 0; | 
 | 1057 | 	} | 
 | 1058 |  | 
 | 1059 | err_allocs: | 
 | 1060 | 	drmFree(U642VOID(ovr.format_type_ptr)); | 
 | 1061 |  | 
 | 1062 | 	return r; | 
 | 1063 | } | 
 | 1064 |  | 
| Lucas De Marchi | 26f9ce5 | 2018-09-13 15:42:26 -0700 | [diff] [blame] | 1065 | drm_public void drmModeFreePlane(drmModePlanePtr ptr) | 
| Jesse Barnes | ac168bf | 2011-04-29 08:53:53 -0700 | [diff] [blame] | 1066 | { | 
 | 1067 | 	if (!ptr) | 
 | 1068 | 		return; | 
 | 1069 |  | 
 | 1070 | 	drmFree(ptr->formats); | 
 | 1071 | 	drmFree(ptr); | 
 | 1072 | } | 
 | 1073 |  | 
| Lucas De Marchi | 26f9ce5 | 2018-09-13 15:42:26 -0700 | [diff] [blame] | 1074 | drm_public drmModePlaneResPtr drmModeGetPlaneResources(int fd) | 
| Jesse Barnes | ac168bf | 2011-04-29 08:53:53 -0700 | [diff] [blame] | 1075 | { | 
 | 1076 | 	struct drm_mode_get_plane_res res, counts; | 
 | 1077 | 	drmModePlaneResPtr r = 0; | 
 | 1078 |  | 
 | 1079 | retry: | 
| Daniel Vetter | 7e0460c | 2015-02-11 12:03:12 +0100 | [diff] [blame] | 1080 | 	memclear(res); | 
| Jesse Barnes | ac168bf | 2011-04-29 08:53:53 -0700 | [diff] [blame] | 1081 | 	if (drmIoctl(fd, DRM_IOCTL_MODE_GETPLANERESOURCES, &res)) | 
 | 1082 | 		return 0; | 
 | 1083 |  | 
 | 1084 | 	counts = res; | 
 | 1085 |  | 
 | 1086 | 	if (res.count_planes) { | 
 | 1087 | 		res.plane_id_ptr = VOID2U64(drmMalloc(res.count_planes * | 
 | 1088 | 							sizeof(uint32_t))); | 
 | 1089 | 		if (!res.plane_id_ptr) | 
 | 1090 | 			goto err_allocs; | 
 | 1091 | 	} | 
 | 1092 |  | 
 | 1093 | 	if (drmIoctl(fd, DRM_IOCTL_MODE_GETPLANERESOURCES, &res)) | 
 | 1094 | 		goto err_allocs; | 
 | 1095 |  | 
 | 1096 | 	if (counts.count_planes < res.count_planes) { | 
 | 1097 | 		drmFree(U642VOID(res.plane_id_ptr)); | 
 | 1098 | 		goto retry; | 
 | 1099 | 	} | 
 | 1100 |  | 
 | 1101 | 	if (!(r = drmMalloc(sizeof(*r)))) | 
 | 1102 | 		goto err_allocs; | 
 | 1103 |  | 
 | 1104 | 	r->count_planes = res.count_planes; | 
 | 1105 | 	r->planes = drmAllocCpy(U642VOID(res.plane_id_ptr), | 
 | 1106 | 				  res.count_planes, sizeof(uint32_t)); | 
 | 1107 | 	if (res.count_planes && !r->planes) { | 
 | 1108 | 		drmFree(r->planes); | 
| Ville Syrjälä | df497e9 | 2012-02-02 14:53:39 -0500 | [diff] [blame] | 1109 | 		drmFree(r); | 
| Jesse Barnes | ac168bf | 2011-04-29 08:53:53 -0700 | [diff] [blame] | 1110 | 		r = 0; | 
 | 1111 | 	} | 
 | 1112 |  | 
 | 1113 | err_allocs: | 
 | 1114 | 	drmFree(U642VOID(res.plane_id_ptr)); | 
 | 1115 |  | 
 | 1116 | 	return r; | 
 | 1117 | } | 
| Ville Syrjälä | a14c3dd | 2012-02-02 14:53:41 -0500 | [diff] [blame] | 1118 |  | 
| Lucas De Marchi | 26f9ce5 | 2018-09-13 15:42:26 -0700 | [diff] [blame] | 1119 | drm_public void drmModeFreePlaneResources(drmModePlaneResPtr ptr) | 
| Ville Syrjälä | a14c3dd | 2012-02-02 14:53:41 -0500 | [diff] [blame] | 1120 | { | 
 | 1121 | 	if (!ptr) | 
 | 1122 | 		return; | 
 | 1123 |  | 
 | 1124 | 	drmFree(ptr->planes); | 
 | 1125 | 	drmFree(ptr); | 
 | 1126 | } | 
| Paulo Zanoni | 8c75703 | 2012-05-15 18:38:28 -0300 | [diff] [blame] | 1127 |  | 
| Lucas De Marchi | 26f9ce5 | 2018-09-13 15:42:26 -0700 | [diff] [blame] | 1128 | drm_public drmModeObjectPropertiesPtr drmModeObjectGetProperties(int fd, | 
| Paulo Zanoni | 8c75703 | 2012-05-15 18:38:28 -0300 | [diff] [blame] | 1129 | 						      uint32_t object_id, | 
 | 1130 | 						      uint32_t object_type) | 
 | 1131 | { | 
 | 1132 | 	struct drm_mode_obj_get_properties properties; | 
 | 1133 | 	drmModeObjectPropertiesPtr ret = NULL; | 
 | 1134 | 	uint32_t count; | 
 | 1135 |  | 
 | 1136 | retry: | 
| Daniel Vetter | 7e0460c | 2015-02-11 12:03:12 +0100 | [diff] [blame] | 1137 | 	memclear(properties); | 
| Paulo Zanoni | 8c75703 | 2012-05-15 18:38:28 -0300 | [diff] [blame] | 1138 | 	properties.obj_id = object_id; | 
 | 1139 | 	properties.obj_type = object_type; | 
 | 1140 |  | 
 | 1141 | 	if (drmIoctl(fd, DRM_IOCTL_MODE_OBJ_GETPROPERTIES, &properties)) | 
 | 1142 | 		return 0; | 
 | 1143 |  | 
 | 1144 | 	count = properties.count_props; | 
 | 1145 |  | 
 | 1146 | 	if (count) { | 
 | 1147 | 		properties.props_ptr = VOID2U64(drmMalloc(count * | 
 | 1148 | 							  sizeof(uint32_t))); | 
 | 1149 | 		if (!properties.props_ptr) | 
 | 1150 | 			goto err_allocs; | 
 | 1151 | 		properties.prop_values_ptr = VOID2U64(drmMalloc(count * | 
 | 1152 | 						      sizeof(uint64_t))); | 
 | 1153 | 		if (!properties.prop_values_ptr) | 
 | 1154 | 			goto err_allocs; | 
 | 1155 | 	} | 
 | 1156 |  | 
 | 1157 | 	if (drmIoctl(fd, DRM_IOCTL_MODE_OBJ_GETPROPERTIES, &properties)) | 
 | 1158 | 		goto err_allocs; | 
 | 1159 |  | 
 | 1160 | 	if (count < properties.count_props) { | 
 | 1161 | 		drmFree(U642VOID(properties.props_ptr)); | 
 | 1162 | 		drmFree(U642VOID(properties.prop_values_ptr)); | 
 | 1163 | 		goto retry; | 
 | 1164 | 	} | 
 | 1165 | 	count = properties.count_props; | 
 | 1166 |  | 
 | 1167 | 	ret = drmMalloc(sizeof(*ret)); | 
 | 1168 | 	if (!ret) | 
 | 1169 | 		goto err_allocs; | 
 | 1170 |  | 
 | 1171 | 	ret->count_props = count; | 
 | 1172 | 	ret->props = drmAllocCpy(U642VOID(properties.props_ptr), | 
 | 1173 | 				 count, sizeof(uint32_t)); | 
 | 1174 | 	ret->prop_values = drmAllocCpy(U642VOID(properties.prop_values_ptr), | 
 | 1175 | 				       count, sizeof(uint64_t)); | 
 | 1176 | 	if (ret->count_props && (!ret->props || !ret->prop_values)) { | 
 | 1177 | 		drmFree(ret->props); | 
 | 1178 | 		drmFree(ret->prop_values); | 
 | 1179 | 		drmFree(ret); | 
 | 1180 | 		ret = NULL; | 
 | 1181 | 	} | 
 | 1182 |  | 
 | 1183 | err_allocs: | 
 | 1184 | 	drmFree(U642VOID(properties.props_ptr)); | 
 | 1185 | 	drmFree(U642VOID(properties.prop_values_ptr)); | 
 | 1186 | 	return ret; | 
 | 1187 | } | 
 | 1188 |  | 
| Lucas De Marchi | 26f9ce5 | 2018-09-13 15:42:26 -0700 | [diff] [blame] | 1189 | drm_public void drmModeFreeObjectProperties(drmModeObjectPropertiesPtr ptr) | 
| Paulo Zanoni | 8c75703 | 2012-05-15 18:38:28 -0300 | [diff] [blame] | 1190 | { | 
 | 1191 | 	if (!ptr) | 
 | 1192 | 		return; | 
 | 1193 | 	drmFree(ptr->props); | 
 | 1194 | 	drmFree(ptr->prop_values); | 
 | 1195 | 	drmFree(ptr); | 
 | 1196 | } | 
 | 1197 |  | 
| Lucas De Marchi | 26f9ce5 | 2018-09-13 15:42:26 -0700 | [diff] [blame] | 1198 | drm_public int drmModeObjectSetProperty(int fd, uint32_t object_id, uint32_t object_type, | 
| Paulo Zanoni | 8c75703 | 2012-05-15 18:38:28 -0300 | [diff] [blame] | 1199 | 			     uint32_t property_id, uint64_t value) | 
 | 1200 | { | 
 | 1201 | 	struct drm_mode_obj_set_property prop; | 
 | 1202 |  | 
| Daniel Vetter | 7e0460c | 2015-02-11 12:03:12 +0100 | [diff] [blame] | 1203 | 	memclear(prop); | 
| Paulo Zanoni | 8c75703 | 2012-05-15 18:38:28 -0300 | [diff] [blame] | 1204 | 	prop.value = value; | 
 | 1205 | 	prop.prop_id = property_id; | 
 | 1206 | 	prop.obj_id = object_id; | 
 | 1207 | 	prop.obj_type = object_type; | 
 | 1208 |  | 
 | 1209 | 	return DRM_IOCTL(fd, DRM_IOCTL_MODE_OBJ_SETPROPERTY, &prop); | 
 | 1210 | } | 
| Ville Syrjälä | ed44e0b | 2015-06-22 17:26:02 +0100 | [diff] [blame] | 1211 |  | 
 | 1212 | typedef struct _drmModeAtomicReqItem drmModeAtomicReqItem, *drmModeAtomicReqItemPtr; | 
 | 1213 |  | 
 | 1214 | struct _drmModeAtomicReqItem { | 
 | 1215 | 	uint32_t object_id; | 
 | 1216 | 	uint32_t property_id; | 
 | 1217 | 	uint64_t value; | 
 | 1218 | }; | 
 | 1219 |  | 
 | 1220 | struct _drmModeAtomicReq { | 
 | 1221 | 	uint32_t cursor; | 
 | 1222 | 	uint32_t size_items; | 
 | 1223 | 	drmModeAtomicReqItemPtr items; | 
 | 1224 | }; | 
 | 1225 |  | 
| Lucas De Marchi | 26f9ce5 | 2018-09-13 15:42:26 -0700 | [diff] [blame] | 1226 | drm_public drmModeAtomicReqPtr drmModeAtomicAlloc(void) | 
| Ville Syrjälä | ed44e0b | 2015-06-22 17:26:02 +0100 | [diff] [blame] | 1227 | { | 
 | 1228 | 	drmModeAtomicReqPtr req; | 
 | 1229 |  | 
 | 1230 | 	req = drmMalloc(sizeof *req); | 
 | 1231 | 	if (!req) | 
 | 1232 | 		return NULL; | 
 | 1233 |  | 
 | 1234 | 	req->items = NULL; | 
 | 1235 | 	req->cursor = 0; | 
 | 1236 | 	req->size_items = 0; | 
 | 1237 |  | 
 | 1238 | 	return req; | 
 | 1239 | } | 
 | 1240 |  | 
| Lucas De Marchi | 26f9ce5 | 2018-09-13 15:42:26 -0700 | [diff] [blame] | 1241 | drm_public drmModeAtomicReqPtr drmModeAtomicDuplicate(drmModeAtomicReqPtr old) | 
| Ville Syrjälä | ed44e0b | 2015-06-22 17:26:02 +0100 | [diff] [blame] | 1242 | { | 
 | 1243 | 	drmModeAtomicReqPtr new; | 
 | 1244 |  | 
| Emil Velikov | ed3c665 | 2015-09-05 17:20:53 +0100 | [diff] [blame] | 1245 | 	if (!old) | 
 | 1246 | 		return NULL; | 
 | 1247 |  | 
| Ville Syrjälä | ed44e0b | 2015-06-22 17:26:02 +0100 | [diff] [blame] | 1248 | 	new = drmMalloc(sizeof *new); | 
 | 1249 | 	if (!new) | 
 | 1250 | 		return NULL; | 
 | 1251 |  | 
 | 1252 | 	new->cursor = old->cursor; | 
 | 1253 | 	new->size_items = old->size_items; | 
 | 1254 |  | 
 | 1255 | 	if (old->size_items) { | 
 | 1256 | 		new->items = drmMalloc(old->size_items * sizeof(*new->items)); | 
 | 1257 | 		if (!new->items) { | 
 | 1258 | 			free(new); | 
 | 1259 | 			return NULL; | 
 | 1260 | 		} | 
 | 1261 | 		memcpy(new->items, old->items, | 
| Adrian Salido | 763f646 | 2019-04-24 10:08:40 -0700 | [diff] [blame] | 1262 | 		       old->cursor * sizeof(*new->items)); | 
| Ville Syrjälä | ed44e0b | 2015-06-22 17:26:02 +0100 | [diff] [blame] | 1263 | 	} else { | 
 | 1264 | 		new->items = NULL; | 
 | 1265 | 	} | 
 | 1266 |  | 
 | 1267 | 	return new; | 
 | 1268 | } | 
 | 1269 |  | 
| Lucas De Marchi | 26f9ce5 | 2018-09-13 15:42:26 -0700 | [diff] [blame] | 1270 | drm_public int drmModeAtomicMerge(drmModeAtomicReqPtr base, | 
 | 1271 |                                   drmModeAtomicReqPtr augment) | 
| Ville Syrjälä | ed44e0b | 2015-06-22 17:26:02 +0100 | [diff] [blame] | 1272 | { | 
| Emil Velikov | ed3c665 | 2015-09-05 17:20:53 +0100 | [diff] [blame] | 1273 | 	if (!base) | 
 | 1274 | 		return -EINVAL; | 
 | 1275 |  | 
| Ville Syrjälä | ed44e0b | 2015-06-22 17:26:02 +0100 | [diff] [blame] | 1276 | 	if (!augment || augment->cursor == 0) | 
 | 1277 | 		return 0; | 
 | 1278 |  | 
 | 1279 | 	if (base->cursor + augment->cursor >= base->size_items) { | 
 | 1280 | 		drmModeAtomicReqItemPtr new; | 
 | 1281 | 		int saved_size = base->size_items; | 
 | 1282 |  | 
 | 1283 | 		base->size_items = base->cursor + augment->cursor; | 
 | 1284 | 		new = realloc(base->items, | 
 | 1285 | 			      base->size_items * sizeof(*base->items)); | 
 | 1286 | 		if (!new) { | 
 | 1287 | 			base->size_items = saved_size; | 
 | 1288 | 			return -ENOMEM; | 
 | 1289 | 		} | 
 | 1290 | 		base->items = new; | 
 | 1291 | 	} | 
 | 1292 |  | 
 | 1293 | 	memcpy(&base->items[base->cursor], augment->items, | 
 | 1294 | 	       augment->cursor * sizeof(*augment->items)); | 
 | 1295 | 	base->cursor += augment->cursor; | 
 | 1296 |  | 
 | 1297 | 	return 0; | 
 | 1298 | } | 
 | 1299 |  | 
| Lucas De Marchi | 26f9ce5 | 2018-09-13 15:42:26 -0700 | [diff] [blame] | 1300 | drm_public int drmModeAtomicGetCursor(drmModeAtomicReqPtr req) | 
| Ville Syrjälä | ed44e0b | 2015-06-22 17:26:02 +0100 | [diff] [blame] | 1301 | { | 
| Emil Velikov | ed3c665 | 2015-09-05 17:20:53 +0100 | [diff] [blame] | 1302 | 	if (!req) | 
 | 1303 | 		return -EINVAL; | 
| Ville Syrjälä | ed44e0b | 2015-06-22 17:26:02 +0100 | [diff] [blame] | 1304 | 	return req->cursor; | 
 | 1305 | } | 
 | 1306 |  | 
| Lucas De Marchi | 26f9ce5 | 2018-09-13 15:42:26 -0700 | [diff] [blame] | 1307 | drm_public void drmModeAtomicSetCursor(drmModeAtomicReqPtr req, int cursor) | 
| Ville Syrjälä | ed44e0b | 2015-06-22 17:26:02 +0100 | [diff] [blame] | 1308 | { | 
| Emil Velikov | ed3c665 | 2015-09-05 17:20:53 +0100 | [diff] [blame] | 1309 | 	if (req) | 
 | 1310 | 		req->cursor = cursor; | 
| Ville Syrjälä | ed44e0b | 2015-06-22 17:26:02 +0100 | [diff] [blame] | 1311 | } | 
 | 1312 |  | 
| Lucas De Marchi | 26f9ce5 | 2018-09-13 15:42:26 -0700 | [diff] [blame] | 1313 | drm_public int drmModeAtomicAddProperty(drmModeAtomicReqPtr req, | 
 | 1314 |                                         uint32_t object_id, | 
 | 1315 |                                         uint32_t property_id, | 
 | 1316 |                                         uint64_t value) | 
| Ville Syrjälä | ed44e0b | 2015-06-22 17:26:02 +0100 | [diff] [blame] | 1317 | { | 
| Emil Velikov | ed3c665 | 2015-09-05 17:20:53 +0100 | [diff] [blame] | 1318 | 	if (!req) | 
 | 1319 | 		return -EINVAL; | 
 | 1320 |  | 
| Daniel Stone | 45eee3f | 2018-03-07 12:41:12 +0000 | [diff] [blame] | 1321 | 	if (object_id == 0 || property_id == 0) | 
 | 1322 | 		return -EINVAL; | 
 | 1323 |  | 
| Ville Syrjälä | ed44e0b | 2015-06-22 17:26:02 +0100 | [diff] [blame] | 1324 | 	if (req->cursor >= req->size_items) { | 
| Adrian Salido | 763f646 | 2019-04-24 10:08:40 -0700 | [diff] [blame] | 1325 | 		const uint32_t item_size_inc = getpagesize() / sizeof(*req->items); | 
| Ville Syrjälä | ed44e0b | 2015-06-22 17:26:02 +0100 | [diff] [blame] | 1326 | 		drmModeAtomicReqItemPtr new; | 
 | 1327 |  | 
| Adrian Salido | 763f646 | 2019-04-24 10:08:40 -0700 | [diff] [blame] | 1328 | 		req->size_items += item_size_inc; | 
| Ville Syrjälä | ed44e0b | 2015-06-22 17:26:02 +0100 | [diff] [blame] | 1329 | 		new = realloc(req->items, req->size_items * sizeof(*req->items)); | 
 | 1330 | 		if (!new) { | 
| Adrian Salido | 763f646 | 2019-04-24 10:08:40 -0700 | [diff] [blame] | 1331 | 			req->size_items -= item_size_inc; | 
| Ville Syrjälä | ed44e0b | 2015-06-22 17:26:02 +0100 | [diff] [blame] | 1332 | 			return -ENOMEM; | 
 | 1333 | 		} | 
 | 1334 | 		req->items = new; | 
 | 1335 | 	} | 
 | 1336 |  | 
 | 1337 | 	req->items[req->cursor].object_id = object_id; | 
 | 1338 | 	req->items[req->cursor].property_id = property_id; | 
 | 1339 | 	req->items[req->cursor].value = value; | 
 | 1340 | 	req->cursor++; | 
 | 1341 |  | 
 | 1342 | 	return req->cursor; | 
 | 1343 | } | 
 | 1344 |  | 
| Lucas De Marchi | 26f9ce5 | 2018-09-13 15:42:26 -0700 | [diff] [blame] | 1345 | drm_public void drmModeAtomicFree(drmModeAtomicReqPtr req) | 
| Ville Syrjälä | ed44e0b | 2015-06-22 17:26:02 +0100 | [diff] [blame] | 1346 | { | 
 | 1347 | 	if (!req) | 
 | 1348 | 		return; | 
 | 1349 |  | 
 | 1350 | 	if (req->items) | 
 | 1351 | 		drmFree(req->items); | 
 | 1352 | 	drmFree(req); | 
 | 1353 | } | 
 | 1354 |  | 
 | 1355 | static int sort_req_list(const void *misc, const void *other) | 
 | 1356 | { | 
 | 1357 | 	const drmModeAtomicReqItem *first = misc; | 
 | 1358 | 	const drmModeAtomicReqItem *second = other; | 
 | 1359 |  | 
 | 1360 | 	if (first->object_id < second->object_id) | 
 | 1361 | 		return -1; | 
 | 1362 | 	else if (first->object_id > second->object_id) | 
 | 1363 | 		return 1; | 
 | 1364 | 	else | 
 | 1365 | 		return second->property_id - first->property_id; | 
 | 1366 | } | 
 | 1367 |  | 
| Lucas De Marchi | 26f9ce5 | 2018-09-13 15:42:26 -0700 | [diff] [blame] | 1368 | drm_public int drmModeAtomicCommit(int fd, drmModeAtomicReqPtr req, | 
 | 1369 |                                    uint32_t flags, void *user_data) | 
| Ville Syrjälä | ed44e0b | 2015-06-22 17:26:02 +0100 | [diff] [blame] | 1370 | { | 
| Chris Wilson | 1a6efaf | 2015-07-21 13:46:45 +0100 | [diff] [blame] | 1371 | 	drmModeAtomicReqPtr sorted; | 
| Ville Syrjälä | ed44e0b | 2015-06-22 17:26:02 +0100 | [diff] [blame] | 1372 | 	struct drm_mode_atomic atomic; | 
 | 1373 | 	uint32_t *objs_ptr = NULL; | 
 | 1374 | 	uint32_t *count_props_ptr = NULL; | 
 | 1375 | 	uint32_t *props_ptr = NULL; | 
 | 1376 | 	uint64_t *prop_values_ptr = NULL; | 
 | 1377 | 	uint32_t last_obj_id = 0; | 
 | 1378 | 	uint32_t i; | 
 | 1379 | 	int obj_idx = -1; | 
 | 1380 | 	int ret = -1; | 
 | 1381 |  | 
| Emil Velikov | ed3c665 | 2015-09-05 17:20:53 +0100 | [diff] [blame] | 1382 | 	if (!req) | 
 | 1383 | 		return -EINVAL; | 
 | 1384 |  | 
| Chris Wilson | 1a6efaf | 2015-07-21 13:46:45 +0100 | [diff] [blame] | 1385 | 	if (req->cursor == 0) | 
 | 1386 | 		return 0; | 
 | 1387 |  | 
 | 1388 | 	sorted = drmModeAtomicDuplicate(req); | 
 | 1389 | 	if (sorted == NULL) | 
| Ville Syrjälä | ed44e0b | 2015-06-22 17:26:02 +0100 | [diff] [blame] | 1390 | 		return -ENOMEM; | 
 | 1391 |  | 
 | 1392 | 	memclear(atomic); | 
 | 1393 |  | 
 | 1394 | 	/* Sort the list by object ID, then by property ID. */ | 
 | 1395 | 	qsort(sorted->items, sorted->cursor, sizeof(*sorted->items), | 
 | 1396 | 	      sort_req_list); | 
 | 1397 |  | 
 | 1398 | 	/* Now the list is sorted, eliminate duplicate property sets. */ | 
 | 1399 | 	for (i = 0; i < sorted->cursor; i++) { | 
 | 1400 | 		if (sorted->items[i].object_id != last_obj_id) { | 
 | 1401 | 			atomic.count_objs++; | 
 | 1402 | 			last_obj_id = sorted->items[i].object_id; | 
 | 1403 | 		} | 
 | 1404 |  | 
 | 1405 | 		if (i == sorted->cursor - 1) | 
 | 1406 | 			continue; | 
 | 1407 |  | 
 | 1408 | 		if (sorted->items[i].object_id != sorted->items[i + 1].object_id || | 
 | 1409 | 		    sorted->items[i].property_id != sorted->items[i + 1].property_id) | 
 | 1410 | 			continue; | 
 | 1411 |  | 
 | 1412 | 		memmove(&sorted->items[i], &sorted->items[i + 1], | 
 | 1413 | 			(sorted->cursor - i - 1) * sizeof(*sorted->items)); | 
 | 1414 | 		sorted->cursor--; | 
 | 1415 | 	} | 
 | 1416 |  | 
 | 1417 | 	objs_ptr = drmMalloc(atomic.count_objs * sizeof objs_ptr[0]); | 
 | 1418 | 	if (!objs_ptr) { | 
 | 1419 | 		errno = ENOMEM; | 
 | 1420 | 		goto out; | 
 | 1421 | 	} | 
 | 1422 |  | 
 | 1423 | 	count_props_ptr = drmMalloc(atomic.count_objs * sizeof count_props_ptr[0]); | 
 | 1424 | 	if (!count_props_ptr) { | 
 | 1425 | 		errno = ENOMEM; | 
 | 1426 | 		goto out; | 
 | 1427 | 	} | 
 | 1428 |  | 
 | 1429 | 	props_ptr = drmMalloc(sorted->cursor * sizeof props_ptr[0]); | 
 | 1430 | 	if (!props_ptr) { | 
 | 1431 | 		errno = ENOMEM; | 
 | 1432 | 		goto out; | 
 | 1433 | 	} | 
 | 1434 |  | 
 | 1435 | 	prop_values_ptr = drmMalloc(sorted->cursor * sizeof prop_values_ptr[0]); | 
 | 1436 | 	if (!prop_values_ptr) { | 
 | 1437 | 		errno = ENOMEM; | 
 | 1438 | 		goto out; | 
 | 1439 | 	} | 
 | 1440 |  | 
 | 1441 | 	for (i = 0, last_obj_id = 0; i < sorted->cursor; i++) { | 
 | 1442 | 		if (sorted->items[i].object_id != last_obj_id) { | 
 | 1443 | 			obj_idx++; | 
 | 1444 | 			objs_ptr[obj_idx] = sorted->items[i].object_id; | 
 | 1445 | 			last_obj_id = objs_ptr[obj_idx]; | 
 | 1446 | 		} | 
 | 1447 |  | 
 | 1448 | 		count_props_ptr[obj_idx]++; | 
 | 1449 | 		props_ptr[i] = sorted->items[i].property_id; | 
 | 1450 | 		prop_values_ptr[i] = sorted->items[i].value; | 
 | 1451 |  | 
 | 1452 | 	} | 
 | 1453 |  | 
 | 1454 | 	atomic.flags = flags; | 
 | 1455 | 	atomic.objs_ptr = VOID2U64(objs_ptr); | 
 | 1456 | 	atomic.count_props_ptr = VOID2U64(count_props_ptr); | 
 | 1457 | 	atomic.props_ptr = VOID2U64(props_ptr); | 
 | 1458 | 	atomic.prop_values_ptr = VOID2U64(prop_values_ptr); | 
 | 1459 | 	atomic.user_data = VOID2U64(user_data); | 
 | 1460 |  | 
 | 1461 | 	ret = DRM_IOCTL(fd, DRM_IOCTL_MODE_ATOMIC, &atomic); | 
 | 1462 |  | 
 | 1463 | out: | 
 | 1464 | 	drmFree(objs_ptr); | 
 | 1465 | 	drmFree(count_props_ptr); | 
 | 1466 | 	drmFree(props_ptr); | 
 | 1467 | 	drmFree(prop_values_ptr); | 
 | 1468 | 	drmModeAtomicFree(sorted); | 
 | 1469 |  | 
 | 1470 | 	return ret; | 
 | 1471 | } | 
| Daniel Stone | 32471b2 | 2015-06-22 17:26:03 +0100 | [diff] [blame] | 1472 |  | 
| Lucas De Marchi | 26f9ce5 | 2018-09-13 15:42:26 -0700 | [diff] [blame] | 1473 | drm_public int | 
 | 1474 | drmModeCreatePropertyBlob(int fd, const void *data, size_t length, | 
 | 1475 |                                      uint32_t *id) | 
| Daniel Stone | 32471b2 | 2015-06-22 17:26:03 +0100 | [diff] [blame] | 1476 | { | 
 | 1477 | 	struct drm_mode_create_blob create; | 
 | 1478 | 	int ret; | 
 | 1479 |  | 
 | 1480 | 	if (length >= 0xffffffff) | 
 | 1481 | 		return -ERANGE; | 
 | 1482 |  | 
 | 1483 | 	memclear(create); | 
 | 1484 |  | 
 | 1485 | 	create.length = length; | 
 | 1486 | 	create.data = (uintptr_t) data; | 
 | 1487 | 	create.blob_id = 0; | 
 | 1488 | 	*id = 0; | 
 | 1489 |  | 
 | 1490 | 	ret = DRM_IOCTL(fd, DRM_IOCTL_MODE_CREATEPROPBLOB, &create); | 
 | 1491 | 	if (ret != 0) | 
 | 1492 | 		return ret; | 
 | 1493 |  | 
 | 1494 | 	*id = create.blob_id; | 
 | 1495 | 	return 0; | 
 | 1496 | } | 
 | 1497 |  | 
| Lucas De Marchi | 26f9ce5 | 2018-09-13 15:42:26 -0700 | [diff] [blame] | 1498 | drm_public int | 
| Daniel Stone | 32471b2 | 2015-06-22 17:26:03 +0100 | [diff] [blame] | 1499 | drmModeDestroyPropertyBlob(int fd, uint32_t id) | 
 | 1500 | { | 
 | 1501 | 	struct drm_mode_destroy_blob destroy; | 
 | 1502 |  | 
 | 1503 | 	memclear(destroy); | 
 | 1504 | 	destroy.blob_id = id; | 
 | 1505 | 	return DRM_IOCTL(fd, DRM_IOCTL_MODE_DESTROYPROPBLOB, &destroy); | 
 | 1506 | } | 
| Keith Packard | c417153 | 2017-03-16 18:11:05 -0700 | [diff] [blame] | 1507 |  | 
| Lucas De Marchi | 26f9ce5 | 2018-09-13 15:42:26 -0700 | [diff] [blame] | 1508 | drm_public int | 
 | 1509 | drmModeCreateLease(int fd, const uint32_t *objects, int num_objects, int flags, | 
 | 1510 |                    uint32_t *lessee_id) | 
| Keith Packard | c417153 | 2017-03-16 18:11:05 -0700 | [diff] [blame] | 1511 | { | 
 | 1512 | 	struct drm_mode_create_lease create; | 
 | 1513 | 	int ret; | 
 | 1514 |  | 
 | 1515 | 	memclear(create); | 
 | 1516 | 	create.object_ids = (uintptr_t) objects; | 
 | 1517 | 	create.object_count = num_objects; | 
 | 1518 | 	create.flags = flags; | 
 | 1519 |  | 
 | 1520 | 	ret = DRM_IOCTL(fd, DRM_IOCTL_MODE_CREATE_LEASE, &create); | 
 | 1521 | 	if (ret == 0) { | 
 | 1522 | 		*lessee_id = create.lessee_id; | 
 | 1523 | 		return create.fd; | 
 | 1524 | 	} | 
 | 1525 | 	return -errno; | 
 | 1526 | } | 
 | 1527 |  | 
| Lucas De Marchi | 26f9ce5 | 2018-09-13 15:42:26 -0700 | [diff] [blame] | 1528 | drm_public drmModeLesseeListPtr | 
| Keith Packard | c417153 | 2017-03-16 18:11:05 -0700 | [diff] [blame] | 1529 | drmModeListLessees(int fd) | 
 | 1530 | { | 
 | 1531 | 	struct drm_mode_list_lessees list; | 
 | 1532 | 	uint32_t count; | 
 | 1533 | 	drmModeLesseeListPtr ret; | 
 | 1534 |  | 
 | 1535 | 	memclear(list); | 
 | 1536 |  | 
 | 1537 | 	if (DRM_IOCTL(fd, DRM_IOCTL_MODE_LIST_LESSEES, &list)) | 
 | 1538 | 		return NULL; | 
 | 1539 |  | 
 | 1540 | 	count = list.count_lessees; | 
 | 1541 | 	ret = drmMalloc(sizeof (drmModeLesseeListRes) + count * sizeof (ret->lessees[0])); | 
 | 1542 | 	if (!ret) | 
 | 1543 | 		return NULL; | 
 | 1544 |  | 
 | 1545 | 	list.lessees_ptr = VOID2U64(&ret->lessees[0]); | 
 | 1546 | 	if (DRM_IOCTL(fd, DRM_IOCTL_MODE_LIST_LESSEES, &list)) { | 
 | 1547 | 		drmFree(ret); | 
 | 1548 | 		return NULL; | 
 | 1549 | 	} | 
 | 1550 |  | 
 | 1551 | 	ret->count = count; | 
 | 1552 | 	return ret; | 
 | 1553 | } | 
 | 1554 |  | 
| Lucas De Marchi | 26f9ce5 | 2018-09-13 15:42:26 -0700 | [diff] [blame] | 1555 | drm_public drmModeObjectListPtr | 
| Keith Packard | c417153 | 2017-03-16 18:11:05 -0700 | [diff] [blame] | 1556 | drmModeGetLease(int fd) | 
 | 1557 | { | 
 | 1558 | 	struct drm_mode_get_lease get; | 
 | 1559 | 	uint32_t count; | 
 | 1560 | 	drmModeObjectListPtr ret; | 
 | 1561 |  | 
 | 1562 | 	memclear(get); | 
 | 1563 |  | 
 | 1564 | 	if (DRM_IOCTL(fd, DRM_IOCTL_MODE_GET_LEASE, &get)) | 
 | 1565 | 		return NULL; | 
 | 1566 |  | 
 | 1567 | 	count = get.count_objects; | 
 | 1568 | 	ret = drmMalloc(sizeof (drmModeObjectListRes) + count * sizeof (ret->objects[0])); | 
 | 1569 | 	if (!ret) | 
 | 1570 | 		return NULL; | 
 | 1571 |  | 
 | 1572 | 	get.objects_ptr = VOID2U64(&ret->objects[0]); | 
 | 1573 | 	if (DRM_IOCTL(fd, DRM_IOCTL_MODE_GET_LEASE, &get)) { | 
 | 1574 | 		drmFree(ret); | 
 | 1575 | 		return NULL; | 
 | 1576 | 	} | 
 | 1577 |  | 
 | 1578 | 	ret->count = count; | 
 | 1579 | 	return ret; | 
 | 1580 | } | 
 | 1581 |  | 
| Lucas De Marchi | 26f9ce5 | 2018-09-13 15:42:26 -0700 | [diff] [blame] | 1582 | drm_public int | 
| Keith Packard | c417153 | 2017-03-16 18:11:05 -0700 | [diff] [blame] | 1583 | drmModeRevokeLease(int fd, uint32_t lessee_id) | 
 | 1584 | { | 
 | 1585 | 	struct drm_mode_revoke_lease revoke; | 
 | 1586 | 	int ret; | 
 | 1587 |  | 
 | 1588 | 	memclear(revoke); | 
 | 1589 |  | 
 | 1590 | 	revoke.lessee_id = lessee_id; | 
 | 1591 |  | 
 | 1592 | 	ret = DRM_IOCTL(fd, DRM_IOCTL_MODE_REVOKE_LEASE, &revoke); | 
 | 1593 | 	if (ret == 0) | 
 | 1594 | 		return 0; | 
 | 1595 | 	return -errno; | 
 | 1596 | } |