3 * Header for DRM modesetting interface.
5 * \author Jakob Bornecrantz <wallbraker@gmail.com>
7 * \par Acknowledgements:
8 * Feb 2007, Dave Airlie <airlied@linux.ie>
12 * Copyright (c) <year> <copyright holders>
14 * Permission is hereby granted, free of charge, to any person obtaining a
15 * copy of this software and associated documentation files (the "Software"),
16 * to deal in the Software without restriction, including without limitation
17 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
18 * and/or sell copies of the Software, and to permit persons to whom the
19 * Software is furnished to do so, subject to the following conditions:
21 * The above copyright notice and this permission notice shall be included in
22 * all copies or substantial portions of the Software.
24 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
25 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
26 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
27 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
28 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
29 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
35 * TODO the types we are after are defined in diffrent headers on diffrent
36 * platforms find which headers to include to get uint32_t
40 #include "xf86drmMode.h"
49 void* drmAllocCpy(void *array, int count, int entry_size)
54 if (!count || !array || !entry_size)
57 if (!(r = drmMalloc(count*entry_size)))
60 for (i = 0; i < count; i++)
61 memcpy(r+(entry_size*i), array+(entry_size*i), entry_size);
67 * Generate crtc and output ids.
69 * Will generate ids starting from 1 up to count if count is greater then 0.
71 static uint32_t* drmAllocGenerate(int count)
79 if (!(r = drmMalloc(count*sizeof(*r))))
82 for (i = 0; i < count; r[i] = ++i);
88 * A couple of free functions.
91 void drmModeFreeModeInfo(struct drm_mode_modeinfo *ptr)
99 void drmModeFreeResources(drmModeResPtr ptr)
109 void drmModeFreeFB(drmModeFBPtr ptr)
114 /* we might add more frees later. */
118 void drmModeFreeCrtc(drmModeCrtcPtr ptr)
127 void drmModeFreeOutput(drmModeOutputPtr ptr)
138 * ModeSetting functions.
141 drmModeResPtr drmModeGetResources(int fd)
143 struct drm_mode_card_res res;
147 memset(&res, 0, sizeof(struct drm_mode_card_res));
149 if (ioctl(fd, DRM_IOCTL_MODE_GETRESOURCES, &res))
153 res.fb_id = drmMalloc(res.count_fbs*sizeof(uint32_t));
155 res.crtc_id = drmMalloc(res.count_crtcs*sizeof(uint32_t));
156 if (res.count_outputs)
157 res.output_id = drmMalloc(res.count_outputs*sizeof(uint32_t));
159 res.modes = drmMalloc(res.count_modes*sizeof(*res.modes));
161 if (ioctl(fd, DRM_IOCTL_MODE_GETRESOURCES, &res)) {
171 if (!(r = drmMalloc(sizeof(*r))))
174 r->count_fbs = res.count_fbs;
175 r->count_crtcs = res.count_crtcs;
176 r->count_outputs = res.count_outputs;
177 r->count_modes = res.count_modes;
178 /* TODO we realy should test if these allocs fails. */
179 r->fbs = drmAllocCpy(res.fb_id, res.count_fbs, sizeof(uint32_t));
180 r->crtcs = drmAllocCpy(res.crtc_id, res.count_crtcs, sizeof(uint32_t));
181 r->outputs = drmAllocCpy(res.output_id, res.count_outputs, sizeof(uint32_t));
182 r->modes = drmAllocCpy(res.modes, res.count_modes, sizeof(struct drm_mode_modeinfo));
186 drmFree(res.crtc_id);
187 drmFree(res.output_id);
193 int drmModeAddFB(int fd, uint32_t width, uint32_t height, uint8_t depth,
194 uint8_t bpp, uint32_t pitch, drmBO *bo, uint32_t *buf_id)
196 struct drm_mode_fb_cmd f;
204 f.handle = bo->handle;
206 if (ret = ioctl(fd, DRM_IOCTL_MODE_ADDFB, &f))
209 *buf_id = f.buffer_id;
213 int drmModeRmFB(int fd, uint32_t bufferId)
215 return ioctl(fd, DRM_IOCTL_MODE_RMFB, bufferId);
218 drmModeFBPtr drmModeGetFB(int fd, uint32_t buf)
220 struct drm_mode_fb_cmd info;
223 info.buffer_id = buf;
225 if (ioctl(fd, DRM_IOCTL_MODE_GETFB, &info))
228 if (!(r = drmMalloc(sizeof(*r))))
231 r->buffer_id = info.buffer_id;
232 r->width = info.width;
233 r->height = info.height;
234 r->pitch = info.pitch;
236 r->handle = info.handle;
237 r->depth = info.depth;
247 drmModeCrtcPtr drmModeGetCrtc(int fd, uint32_t crtcId)
249 struct drm_mode_crtc crtc;
253 crtc.count_outputs = 0;
255 crtc.count_possibles = 0;
257 crtc.crtc_id = crtcId;
259 if (ioctl(fd, DRM_IOCTL_MODE_GETCRTC, &crtc))
266 if (!(r = drmMalloc(sizeof(*r))))
272 r->buffer_id = crtc.fb_id;
273 r->gamma_size = crtc.gamma_size;
274 r->count_outputs = crtc.count_outputs;
275 r->count_possibles = crtc.count_possibles;
276 /* TODO we realy should test if these alloc & cpy fails. */
277 r->outputs = crtc.outputs;
278 r->possibles = crtc.possibles;
288 int drmModeSetCrtc(int fd, uint32_t crtcId, uint32_t bufferId,
289 uint32_t x, uint32_t y, uint32_t modeId,
290 uint32_t *outputs, int count)
292 struct drm_mode_crtc crtc;
294 crtc.count_outputs = 0;
296 crtc.count_possibles = 0;
301 crtc.crtc_id = crtcId;
302 crtc.fb_id = bufferId;
303 crtc.set_outputs = outputs;
304 crtc.count_outputs = count;
307 return ioctl(fd, DRM_IOCTL_MODE_SETCRTC, &crtc);
312 * Output manipulation
315 drmModeOutputPtr drmModeGetOutput(int fd, uint32_t output_id)
317 struct drm_mode_get_output out;
318 drmModeOutputPtr r = 0;
320 out.output = output_id;
323 out.count_clones = 0;
328 if (ioctl(fd, DRM_IOCTL_MODE_GETOUTPUT, &out))
332 out.modes = drmMalloc(out.count_modes*sizeof(uint32_t));
334 if (ioctl(fd, DRM_IOCTL_MODE_GETOUTPUT, &out))
337 if(!(r = drmMalloc(sizeof(*r))))
340 r->connection = out.connection;
341 r->mmWidth = out.mm_width;
342 r->mmHeight = out.mm_height;
343 r->subpixel = out.subpixel;
344 r->count_crtcs = out.count_crtcs;
345 r->count_clones = out.count_clones;
346 r->count_modes = out.count_modes;
347 /* TODO we should test if these alloc & cpy fails. */
348 r->crtcs = out.crtcs;
349 r->clones = out.clones;
350 r->modes = drmAllocCpy(out.modes, out.count_modes, sizeof(uint32_t));
351 strncpy(r->name, out.name, DRM_OUTPUT_NAME_LEN);
352 r->name[DRM_OUTPUT_NAME_LEN-1] = 0;
361 uint32_t drmModeAddMode(int fd, struct drm_mode_modeinfo *mode_info)
363 if (ioctl(fd, DRM_IOCTL_MODE_ADDMODE, mode_info))
366 return mode_info->id;
369 int drmModeRmMode(int fd, uint32_t mode_id)
371 return ioctl(fd, DRM_IOCTL_MODE_RMMODE, mode_id);
374 int drmModeAttachMode(int fd, uint32_t output_id, uint32_t mode_id)
377 struct drm_mode_mode_cmd res;
379 res.output_id = output_id;
380 res.mode_id = mode_id;
382 return ioctl(fd, DRM_IOCTL_MODE_ATTACHMODE, &res);
385 int drmModeDetachMode(int fd, uint32_t output_id, uint32_t mode_id)
387 struct drm_mode_mode_cmd res;
389 res.output_id = output_id;
390 res.mode_id = mode_id;
392 return ioctl(fd, DRM_IOCTL_MODE_DETACHMODE, &res);