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;
242 int drmModeForceProbe(int fd, uint32_t outputId)
244 /* TODO impl/keep? */
252 drmModeCrtcPtr drmModeGetCrtc(int fd, uint32_t crtcId)
254 struct drm_mode_crtc crtc;
258 crtc.count_outputs = 0;
260 crtc.count_possibles = 0;
262 crtc.crtc_id = crtcId;
264 if (ioctl(fd, DRM_IOCTL_MODE_GETCRTC, &crtc))
271 if (!(r = drmMalloc(sizeof(*r))))
277 // r->width = crtc.width;
278 // r->height = crtc.height;
279 r->buffer_id = crtc.fb_id;
280 r->gamma_size = crtc.gamma_size;
281 r->count_outputs = crtc.count_outputs;
282 r->count_possibles = crtc.count_possibles;
283 /* TODO we realy should test if these alloc & cpy fails. */
284 r->outputs = crtc.outputs;
285 r->possibles = crtc.possibles;
295 int drmModeSetCrtc(int fd, uint32_t crtcId, uint32_t bufferId,
296 uint32_t x, uint32_t y, uint32_t modeId,
297 uint32_t *outputs, int count)
299 struct drm_mode_crtc crtc;
301 crtc.count_outputs = 0;
303 crtc.count_possibles = 0;
308 crtc.crtc_id = crtcId;
309 crtc.fb_id = bufferId;
310 crtc.set_outputs = outputs;
311 crtc.count_outputs = count;
314 return ioctl(fd, DRM_IOCTL_MODE_SETCRTC, &crtc);
318 drmModeGammaTriplePtr drmModeGetCrtcGamma(int fd, uint32_t crtc, int *count)
323 int drmModeSetCrtcGamma(int fd, uint32_t crtcId,
324 drmModeGammaTriplePtr ptr, int count)
331 * Output manipulation
333 drmModeOutputPtr drmModeGetOutput(int fd, uint32_t output_id)
335 struct drm_mode_get_output out;
336 drmModeOutputPtr r = 0;
338 out.output = output_id;
341 out.count_clones = 0;
346 if (ioctl(fd, DRM_IOCTL_MODE_GETOUTPUT, &out))
350 out.modes = drmMalloc(out.count_modes*sizeof(uint32_t));
352 if (ioctl(fd, DRM_IOCTL_MODE_GETOUTPUT, &out))
355 if(!(r = drmMalloc(sizeof(*r))))
358 r->connection = out.connection;
359 r->mmWidth = out.mm_width;
360 r->mmHeight = out.mm_height;
361 r->subpixel = out.subpixel;
362 r->count_crtcs = out.count_crtcs;
363 r->count_clones = out.count_clones;
364 r->count_modes = out.count_modes;
365 /* TODO we should test if these alloc & cpy fails. */
366 r->crtcs = out.crtcs;
367 r->clones = out.clones;
368 r->modes = drmAllocCpy(out.modes, out.count_modes, sizeof(uint32_t));
369 strncpy(r->name, out.name, DRM_OUTPUT_NAME_LEN);
370 r->name[DRM_OUTPUT_NAME_LEN-1] = 0;
379 uint32_t drmModeAddMode(int fd, struct drm_mode_modeinfo *mode_info)
381 if (ioctl(fd, DRM_IOCTL_MODE_ADDMODE, mode_info))
384 return mode_info->id;
387 int drmModeRmMode(int fd, uint32_t mode_id)
389 return ioctl(fd, DRM_IOCTL_MODE_RMMODE, mode_id);
392 int drmModeAttachMode(int fd, uint32_t output_id, uint32_t mode_id)
395 struct drm_mode_mode_cmd res;
397 res.output_id = output_id;
398 res.mode_id = mode_id;
400 return ioctl(fd, DRM_IOCTL_MODE_ATTACHMODE, &res);
403 int drmModeDetachMode(int fd, uint32_t output_id, uint32_t mode_id)
405 struct drm_mode_mode_cmd res;
407 res.output_id = output_id;
408 res.mode_id = mode_id;
410 return ioctl(fd, DRM_IOCTL_MODE_DETACHMODE, &res);