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) 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>
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:
23 * The above copyright notice and this permission notice shall be included in
24 * all copies or substantial portions of the Software.
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
40 #include <sys/ioctl.h>
43 #include <sys/types.h>
45 #include <sys/sysctl.h>
50 #include "libdrm_macros.h"
51 #include "xf86drmMode.h"
54 #include <drm_fourcc.h>
60 #define memclear(s) memset(&s, 0, sizeof(s))
62 #define U642VOID(x) ((void *)(unsigned long)(x))
63 #define VOID2U64(x) ((uint64_t)(unsigned long)(x))
65 static inline int DRM_IOCTL(int fd
, unsigned long cmd
, void *arg
)
67 int ret
= drmIoctl(fd
, cmd
, arg
);
68 return ret
< 0 ? -errno
: ret
;
75 static void* drmAllocCpy(char *array
, int count
, int entry_size
)
80 if (!count
|| !array
|| !entry_size
)
83 if (!(r
= drmMalloc(count
*entry_size
)))
86 for (i
= 0; i
< count
; i
++)
87 memcpy(r
+(entry_size
*i
), array
+(entry_size
*i
), entry_size
);
93 * A couple of free functions.
96 drm_public
void drmModeFreeModeInfo(drmModeModeInfoPtr ptr
)
104 drm_public
void drmModeFreeResources(drmModeResPtr ptr
)
111 drmFree(ptr
->connectors
);
112 drmFree(ptr
->encoders
);
116 drm_public
void drmModeFreeFB(drmModeFBPtr ptr
)
121 /* we might add more frees later. */
125 drm_public
void drmModeFreeCrtc(drmModeCrtcPtr ptr
)
133 drm_public
void drmModeFreeConnector(drmModeConnectorPtr ptr
)
138 drmFree(ptr
->encoders
);
139 drmFree(ptr
->prop_values
);
145 drm_public
void drmModeFreeEncoder(drmModeEncoderPtr ptr
)
151 * ModeSetting functions.
154 drm_public
int drmIsKMS(int fd
)
156 struct drm_mode_card_res res
= {0};
158 if (drmIoctl(fd
, DRM_IOCTL_MODE_GETRESOURCES
, &res
) != 0)
161 return res
.count_crtcs
> 0 && res
.count_connectors
> 0 && res
.count_encoders
> 0;
164 drm_public drmModeResPtr
drmModeGetResources(int fd
)
166 struct drm_mode_card_res res
, counts
;
171 if (drmIoctl(fd
, DRM_IOCTL_MODE_GETRESOURCES
, &res
))
177 res
.fb_id_ptr
= VOID2U64(drmMalloc(res
.count_fbs
*sizeof(uint32_t)));
181 if (res
.count_crtcs
) {
182 res
.crtc_id_ptr
= VOID2U64(drmMalloc(res
.count_crtcs
*sizeof(uint32_t)));
183 if (!res
.crtc_id_ptr
)
186 if (res
.count_connectors
) {
187 res
.connector_id_ptr
= VOID2U64(drmMalloc(res
.count_connectors
*sizeof(uint32_t)));
188 if (!res
.connector_id_ptr
)
191 if (res
.count_encoders
) {
192 res
.encoder_id_ptr
= VOID2U64(drmMalloc(res
.count_encoders
*sizeof(uint32_t)));
193 if (!res
.encoder_id_ptr
)
197 if (drmIoctl(fd
, DRM_IOCTL_MODE_GETRESOURCES
, &res
))
200 /* The number of available connectors and etc may have changed with a
201 * hotplug event in between the ioctls, in which case the field is
202 * silently ignored by the kernel.
204 if (counts
.count_fbs
< res
.count_fbs
||
205 counts
.count_crtcs
< res
.count_crtcs
||
206 counts
.count_connectors
< res
.count_connectors
||
207 counts
.count_encoders
< res
.count_encoders
)
209 drmFree(U642VOID(res
.fb_id_ptr
));
210 drmFree(U642VOID(res
.crtc_id_ptr
));
211 drmFree(U642VOID(res
.connector_id_ptr
));
212 drmFree(U642VOID(res
.encoder_id_ptr
));
220 if (!(r
= drmMalloc(sizeof(*r
))))
223 r
->min_width
= res
.min_width
;
224 r
->max_width
= res
.max_width
;
225 r
->min_height
= res
.min_height
;
226 r
->max_height
= res
.max_height
;
227 r
->count_fbs
= res
.count_fbs
;
228 r
->count_crtcs
= res
.count_crtcs
;
229 r
->count_connectors
= res
.count_connectors
;
230 r
->count_encoders
= res
.count_encoders
;
232 r
->fbs
= drmAllocCpy(U642VOID(res
.fb_id_ptr
), res
.count_fbs
, sizeof(uint32_t));
233 r
->crtcs
= drmAllocCpy(U642VOID(res
.crtc_id_ptr
), res
.count_crtcs
, sizeof(uint32_t));
234 r
->connectors
= drmAllocCpy(U642VOID(res
.connector_id_ptr
), res
.count_connectors
, sizeof(uint32_t));
235 r
->encoders
= drmAllocCpy(U642VOID(res
.encoder_id_ptr
), res
.count_encoders
, sizeof(uint32_t));
236 if ((res
.count_fbs
&& !r
->fbs
) ||
237 (res
.count_crtcs
&& !r
->crtcs
) ||
238 (res
.count_connectors
&& !r
->connectors
) ||
239 (res
.count_encoders
&& !r
->encoders
))
243 drmFree(r
->connectors
);
244 drmFree(r
->encoders
);
250 drmFree(U642VOID(res
.fb_id_ptr
));
251 drmFree(U642VOID(res
.crtc_id_ptr
));
252 drmFree(U642VOID(res
.connector_id_ptr
));
253 drmFree(U642VOID(res
.encoder_id_ptr
));
259 drm_public
int drmModeAddFB(int fd
, uint32_t width
, uint32_t height
, uint8_t depth
,
260 uint8_t bpp
, uint32_t pitch
, uint32_t bo_handle
,
263 struct drm_mode_fb_cmd f
;
272 f
.handle
= bo_handle
;
274 if ((ret
= DRM_IOCTL(fd
, DRM_IOCTL_MODE_ADDFB
, &f
)))
281 drm_public
int drmModeAddFB2WithModifiers(int fd
, uint32_t width
,
282 uint32_t height
, uint32_t pixel_format
, const uint32_t bo_handles
[4],
283 const uint32_t pitches
[4], const uint32_t offsets
[4],
284 const uint64_t modifier
[4], uint32_t *buf_id
, uint32_t flags
)
286 struct drm_mode_fb_cmd2 f
;
292 f
.pixel_format
= pixel_format
;
294 memcpy(f
.handles
, bo_handles
, 4 * sizeof(bo_handles
[0]));
295 memcpy(f
.pitches
, pitches
, 4 * sizeof(pitches
[0]));
296 memcpy(f
.offsets
, offsets
, 4 * sizeof(offsets
[0]));
298 memcpy(f
.modifier
, modifier
, 4 * sizeof(modifier
[0]));
300 if ((ret
= DRM_IOCTL(fd
, DRM_IOCTL_MODE_ADDFB2
, &f
)))
307 drm_public
int drmModeAddFB2(int fd
, uint32_t width
, uint32_t height
,
308 uint32_t pixel_format
, const uint32_t bo_handles
[4],
309 const uint32_t pitches
[4], const uint32_t offsets
[4],
310 uint32_t *buf_id
, uint32_t flags
)
312 return drmModeAddFB2WithModifiers(fd
, width
, height
,
313 pixel_format
, bo_handles
,
314 pitches
, offsets
, NULL
,
318 drm_public
int drmModeRmFB(int fd
, uint32_t bufferId
)
320 return DRM_IOCTL(fd
, DRM_IOCTL_MODE_RMFB
, &bufferId
);
323 drm_public
int drmModeCloseFB(int fd
, uint32_t buffer_id
)
325 struct drm_mode_closefb closefb
;
328 closefb
.fb_id
= buffer_id
;
330 return DRM_IOCTL(fd
, DRM_IOCTL_MODE_CLOSEFB
, &closefb
);
333 drm_public drmModeFBPtr
drmModeGetFB(int fd
, uint32_t buf
)
335 struct drm_mode_fb_cmd info
;
341 if (drmIoctl(fd
, DRM_IOCTL_MODE_GETFB
, &info
))
344 if (!(r
= drmMalloc(sizeof(*r
))))
347 r
->fb_id
= info
.fb_id
;
348 r
->width
= info
.width
;
349 r
->height
= info
.height
;
350 r
->pitch
= info
.pitch
;
352 r
->handle
= info
.handle
;
353 r
->depth
= info
.depth
;
358 drm_public
int drmModeDirtyFB(int fd
, uint32_t bufferId
,
359 drmModeClipPtr clips
, uint32_t num_clips
)
361 struct drm_mode_fb_dirty_cmd dirty
;
364 dirty
.fb_id
= bufferId
;
365 dirty
.clips_ptr
= VOID2U64(clips
);
366 dirty
.num_clips
= num_clips
;
368 return DRM_IOCTL(fd
, DRM_IOCTL_MODE_DIRTYFB
, &dirty
);
375 drm_public drmModeCrtcPtr
drmModeGetCrtc(int fd
, uint32_t crtcId
)
377 struct drm_mode_crtc crtc
;
381 crtc
.crtc_id
= crtcId
;
383 if (drmIoctl(fd
, DRM_IOCTL_MODE_GETCRTC
, &crtc
))
390 if (!(r
= drmMalloc(sizeof(*r
))))
393 r
->crtc_id
= crtc
.crtc_id
;
396 r
->mode_valid
= crtc
.mode_valid
;
398 memcpy(&r
->mode
, &crtc
.mode
, sizeof(struct drm_mode_modeinfo
));
399 r
->width
= crtc
.mode
.hdisplay
;
400 r
->height
= crtc
.mode
.vdisplay
;
402 r
->buffer_id
= crtc
.fb_id
;
403 r
->gamma_size
= crtc
.gamma_size
;
407 drm_public
int drmModeSetCrtc(int fd
, uint32_t crtcId
, uint32_t bufferId
,
408 uint32_t x
, uint32_t y
, uint32_t *connectors
, int count
,
409 drmModeModeInfoPtr mode
)
411 struct drm_mode_crtc crtc
;
416 crtc
.crtc_id
= crtcId
;
417 crtc
.fb_id
= bufferId
;
418 crtc
.set_connectors_ptr
= VOID2U64(connectors
);
419 crtc
.count_connectors
= count
;
421 memcpy(&crtc
.mode
, mode
, sizeof(struct drm_mode_modeinfo
));
425 return DRM_IOCTL(fd
, DRM_IOCTL_MODE_SETCRTC
, &crtc
);
429 * Cursor manipulation
432 drm_public
int drmModeSetCursor(int fd
, uint32_t crtcId
, uint32_t bo_handle
,
433 uint32_t width
, uint32_t height
)
435 struct drm_mode_cursor arg
;
438 arg
.flags
= DRM_MODE_CURSOR_BO
;
439 arg
.crtc_id
= crtcId
;
442 arg
.handle
= bo_handle
;
444 return DRM_IOCTL(fd
, DRM_IOCTL_MODE_CURSOR
, &arg
);
447 drm_public
int drmModeSetCursor2(int fd
, uint32_t crtcId
, uint32_t bo_handle
,
448 uint32_t width
, uint32_t height
, int32_t hot_x
,
451 struct drm_mode_cursor2 arg
;
454 arg
.flags
= DRM_MODE_CURSOR_BO
;
455 arg
.crtc_id
= crtcId
;
458 arg
.handle
= bo_handle
;
462 return DRM_IOCTL(fd
, DRM_IOCTL_MODE_CURSOR2
, &arg
);
465 drm_public
int drmModeMoveCursor(int fd
, uint32_t crtcId
, int x
, int y
)
467 struct drm_mode_cursor arg
;
470 arg
.flags
= DRM_MODE_CURSOR_MOVE
;
471 arg
.crtc_id
= crtcId
;
475 return DRM_IOCTL(fd
, DRM_IOCTL_MODE_CURSOR
, &arg
);
481 drm_public drmModeEncoderPtr
drmModeGetEncoder(int fd
, uint32_t encoder_id
)
483 struct drm_mode_get_encoder enc
;
484 drmModeEncoderPtr r
= NULL
;
487 enc
.encoder_id
= encoder_id
;
489 if (drmIoctl(fd
, DRM_IOCTL_MODE_GETENCODER
, &enc
))
492 if (!(r
= drmMalloc(sizeof(*r
))))
495 r
->encoder_id
= enc
.encoder_id
;
496 r
->crtc_id
= enc
.crtc_id
;
497 r
->encoder_type
= enc
.encoder_type
;
498 r
->possible_crtcs
= enc
.possible_crtcs
;
499 r
->possible_clones
= enc
.possible_clones
;
505 * Connector manipulation
507 static drmModeConnectorPtr
508 _drmModeGetConnector(int fd
, uint32_t connector_id
, int probe
)
510 struct drm_mode_get_connector conn
, counts
;
511 drmModeConnectorPtr r
= NULL
;
512 struct drm_mode_modeinfo stack_mode
;
515 conn
.connector_id
= connector_id
;
517 conn
.count_modes
= 1;
518 conn
.modes_ptr
= VOID2U64(&stack_mode
);
521 if (drmIoctl(fd
, DRM_IOCTL_MODE_GETCONNECTOR
, &conn
))
527 if (conn
.count_props
) {
528 conn
.props_ptr
= VOID2U64(drmMalloc(conn
.count_props
*sizeof(uint32_t)));
531 conn
.prop_values_ptr
= VOID2U64(drmMalloc(conn
.count_props
*sizeof(uint64_t)));
532 if (!conn
.prop_values_ptr
)
536 if (conn
.count_modes
) {
537 conn
.modes_ptr
= VOID2U64(drmMalloc(conn
.count_modes
*sizeof(struct drm_mode_modeinfo
)));
541 conn
.count_modes
= 1;
542 conn
.modes_ptr
= VOID2U64(&stack_mode
);
545 if (conn
.count_encoders
) {
546 conn
.encoders_ptr
= VOID2U64(drmMalloc(conn
.count_encoders
*sizeof(uint32_t)));
547 if (!conn
.encoders_ptr
)
551 if (drmIoctl(fd
, DRM_IOCTL_MODE_GETCONNECTOR
, &conn
))
554 /* The number of available connectors and etc may have changed with a
555 * hotplug event in between the ioctls, in which case the field is
556 * silently ignored by the kernel.
558 if (counts
.count_props
< conn
.count_props
||
559 counts
.count_modes
< conn
.count_modes
||
560 counts
.count_encoders
< conn
.count_encoders
) {
561 drmFree(U642VOID(conn
.props_ptr
));
562 drmFree(U642VOID(conn
.prop_values_ptr
));
563 if (U642VOID(conn
.modes_ptr
) != &stack_mode
)
564 drmFree(U642VOID(conn
.modes_ptr
));
565 drmFree(U642VOID(conn
.encoders_ptr
));
570 if(!(r
= drmMalloc(sizeof(*r
)))) {
574 r
->connector_id
= conn
.connector_id
;
575 r
->encoder_id
= conn
.encoder_id
;
576 r
->connection
= conn
.connection
;
577 r
->mmWidth
= conn
.mm_width
;
578 r
->mmHeight
= conn
.mm_height
;
579 /* convert subpixel from kernel to userspace */
580 r
->subpixel
= conn
.subpixel
+ 1;
581 r
->count_modes
= conn
.count_modes
;
582 r
->count_props
= conn
.count_props
;
583 r
->props
= drmAllocCpy(U642VOID(conn
.props_ptr
), conn
.count_props
, sizeof(uint32_t));
584 r
->prop_values
= drmAllocCpy(U642VOID(conn
.prop_values_ptr
), conn
.count_props
, sizeof(uint64_t));
585 r
->modes
= drmAllocCpy(U642VOID(conn
.modes_ptr
), conn
.count_modes
, sizeof(struct drm_mode_modeinfo
));
586 r
->count_encoders
= conn
.count_encoders
;
587 r
->encoders
= drmAllocCpy(U642VOID(conn
.encoders_ptr
), conn
.count_encoders
, sizeof(uint32_t));
588 r
->connector_type
= conn
.connector_type
;
589 r
->connector_type_id
= conn
.connector_type_id
;
591 if ((r
->count_props
&& !r
->props
) ||
592 (r
->count_props
&& !r
->prop_values
) ||
593 (r
->count_modes
&& !r
->modes
) ||
594 (r
->count_encoders
&& !r
->encoders
)) {
596 drmFree(r
->prop_values
);
598 drmFree(r
->encoders
);
604 drmFree(U642VOID(conn
.prop_values_ptr
));
605 drmFree(U642VOID(conn
.props_ptr
));
606 if (U642VOID(conn
.modes_ptr
) != &stack_mode
)
607 drmFree(U642VOID(conn
.modes_ptr
));
608 drmFree(U642VOID(conn
.encoders_ptr
));
613 drm_public drmModeConnectorPtr
drmModeGetConnector(int fd
, uint32_t connector_id
)
615 return _drmModeGetConnector(fd
, connector_id
, 1);
618 drm_public drmModeConnectorPtr
drmModeGetConnectorCurrent(int fd
, uint32_t connector_id
)
620 return _drmModeGetConnector(fd
, connector_id
, 0);
623 drm_public
uint32_t drmModeConnectorGetPossibleCrtcs(int fd
,
624 const drmModeConnector
*connector
)
626 drmModeEncoder
*encoder
;
628 uint32_t possible_crtcs
;
631 for (i
= 0; i
< connector
->count_encoders
; i
++) {
632 encoder
= drmModeGetEncoder(fd
, connector
->encoders
[i
]);
637 possible_crtcs
|= encoder
->possible_crtcs
;
638 drmModeFreeEncoder(encoder
);
641 if (possible_crtcs
== 0)
643 return possible_crtcs
;
646 drm_public
int drmModeAttachMode(int fd
, uint32_t connector_id
, drmModeModeInfoPtr mode_info
)
648 struct drm_mode_mode_cmd res
;
651 memcpy(&res
.mode
, mode_info
, sizeof(struct drm_mode_modeinfo
));
652 res
.connector_id
= connector_id
;
654 return DRM_IOCTL(fd
, DRM_IOCTL_MODE_ATTACHMODE
, &res
);
657 drm_public
int drmModeDetachMode(int fd
, uint32_t connector_id
, drmModeModeInfoPtr mode_info
)
659 struct drm_mode_mode_cmd res
;
662 memcpy(&res
.mode
, mode_info
, sizeof(struct drm_mode_modeinfo
));
663 res
.connector_id
= connector_id
;
665 return DRM_IOCTL(fd
, DRM_IOCTL_MODE_DETACHMODE
, &res
);
668 drm_public drmModePropertyPtr
drmModeGetProperty(int fd
, uint32_t property_id
)
670 struct drm_mode_get_property prop
;
671 drmModePropertyPtr r
;
674 prop
.prop_id
= property_id
;
676 if (drmIoctl(fd
, DRM_IOCTL_MODE_GETPROPERTY
, &prop
))
679 if (prop
.count_values
)
680 prop
.values_ptr
= VOID2U64(drmMalloc(prop
.count_values
* sizeof(uint64_t)));
682 if (prop
.count_enum_blobs
&& (prop
.flags
& (DRM_MODE_PROP_ENUM
| DRM_MODE_PROP_BITMASK
)))
683 prop
.enum_blob_ptr
= VOID2U64(drmMalloc(prop
.count_enum_blobs
* sizeof(struct drm_mode_property_enum
)));
685 if (prop
.count_enum_blobs
&& (prop
.flags
& DRM_MODE_PROP_BLOB
)) {
686 prop
.values_ptr
= VOID2U64(drmMalloc(prop
.count_enum_blobs
* sizeof(uint32_t)));
687 prop
.enum_blob_ptr
= VOID2U64(drmMalloc(prop
.count_enum_blobs
* sizeof(uint32_t)));
690 if (drmIoctl(fd
, DRM_IOCTL_MODE_GETPROPERTY
, &prop
)) {
695 if (!(r
= drmMalloc(sizeof(*r
))))
698 r
->prop_id
= prop
.prop_id
;
699 r
->count_values
= prop
.count_values
;
701 r
->flags
= prop
.flags
;
702 if (prop
.count_values
)
703 r
->values
= drmAllocCpy(U642VOID(prop
.values_ptr
), prop
.count_values
, sizeof(uint64_t));
704 if (prop
.flags
& (DRM_MODE_PROP_ENUM
| DRM_MODE_PROP_BITMASK
)) {
705 r
->count_enums
= prop
.count_enum_blobs
;
706 r
->enums
= drmAllocCpy(U642VOID(prop
.enum_blob_ptr
), prop
.count_enum_blobs
, sizeof(struct drm_mode_property_enum
));
707 } else if (prop
.flags
& DRM_MODE_PROP_BLOB
) {
708 r
->values
= drmAllocCpy(U642VOID(prop
.values_ptr
), prop
.count_enum_blobs
, sizeof(uint32_t));
709 r
->blob_ids
= drmAllocCpy(U642VOID(prop
.enum_blob_ptr
), prop
.count_enum_blobs
, sizeof(uint32_t));
710 r
->count_blobs
= prop
.count_enum_blobs
;
712 strncpy(r
->name
, prop
.name
, DRM_PROP_NAME_LEN
);
713 r
->name
[DRM_PROP_NAME_LEN
-1] = 0;
716 drmFree(U642VOID(prop
.values_ptr
));
717 drmFree(U642VOID(prop
.enum_blob_ptr
));
722 drm_public
void drmModeFreeProperty(drmModePropertyPtr ptr
)
727 drmFree(ptr
->values
);
729 drmFree(ptr
->blob_ids
);
733 drm_public drmModePropertyBlobPtr
drmModeGetPropertyBlob(int fd
,
736 struct drm_mode_get_blob blob
;
737 drmModePropertyBlobPtr r
;
740 blob
.blob_id
= blob_id
;
742 if (drmIoctl(fd
, DRM_IOCTL_MODE_GETPROPBLOB
, &blob
))
746 blob
.data
= VOID2U64(drmMalloc(blob
.length
));
748 if (drmIoctl(fd
, DRM_IOCTL_MODE_GETPROPBLOB
, &blob
)) {
753 if (!(r
= drmMalloc(sizeof(*r
))))
756 r
->id
= blob
.blob_id
;
757 r
->length
= blob
.length
;
758 r
->data
= drmAllocCpy(U642VOID(blob
.data
), 1, blob
.length
);
761 drmFree(U642VOID(blob
.data
));
765 static inline const uint32_t *
766 get_formats_ptr(const struct drm_format_modifier_blob
*blob
)
768 return (const uint32_t *)(((uint8_t *)blob
) + blob
->formats_offset
);
771 static inline const struct drm_format_modifier
*
772 get_modifiers_ptr(const struct drm_format_modifier_blob
*blob
)
774 return (const struct drm_format_modifier
*)(((uint8_t *)blob
) +
775 blob
->modifiers_offset
);
778 static bool _drmModeFormatModifierGetNext(const drmModePropertyBlobRes
*blob
,
779 drmModeFormatModifierIterator
*iter
)
781 const struct drm_format_modifier
*blob_modifiers
, *mod
;
782 const struct drm_format_modifier_blob
*fmt_mod_blob
;
783 const uint32_t *blob_formats
;
785 assert(blob
&& iter
);
787 fmt_mod_blob
= blob
->data
;
788 blob_modifiers
= get_modifiers_ptr(fmt_mod_blob
);
789 blob_formats
= get_formats_ptr(fmt_mod_blob
);
791 /* fmt_idx and mod_idx designate the number of processed formats
794 if (iter
->fmt_idx
>= fmt_mod_blob
->count_formats
||
795 iter
->mod_idx
>= fmt_mod_blob
->count_modifiers
)
798 iter
->fmt
= blob_formats
[iter
->fmt_idx
];
799 iter
->mod
= DRM_FORMAT_MOD_INVALID
;
801 /* From the latest valid found, get the next valid modifier */
802 while (iter
->mod_idx
< fmt_mod_blob
->count_modifiers
) {
803 mod
= &blob_modifiers
[iter
->mod_idx
++];
805 /* Check if the format that fmt_idx designates, belongs to
806 * this modifier 64-bit window selected via mod->offset.
808 if (iter
->fmt_idx
< mod
->offset
||
809 iter
->fmt_idx
>= mod
->offset
+ 64)
811 if (!(mod
->formats
& (1 << (iter
->fmt_idx
- mod
->offset
))))
814 iter
->mod
= mod
->modifier
;
818 if (iter
->mod_idx
== fmt_mod_blob
->count_modifiers
) {
823 /* Since mod_idx reset, in order for the caller to iterate over
824 * the last modifier of the last format, always return true here
825 * and early return from the next call.
831 * Iterate over formats first and then over modifiers. On each call, iter->fmt
832 * is retained until all associated modifiers are returned. Then, either update
833 * iter->fmt with the next format, or exit if there aren't any left.
835 * NOTE: clients should not make any assumption on mod_idx and fmt_idx values
837 * @blob: valid kernel blob holding formats and modifiers
838 * @iter: input and output iterator data. Iter data must be initialised to zero
839 * @return: false, on error or there aren't any further formats or modifiers left.
840 * true, on success and there are more formats or modifiers.
842 drm_public
bool drmModeFormatModifierBlobIterNext(const drmModePropertyBlobRes
*blob
,
843 drmModeFormatModifierIterator
*iter
)
845 drmModeFormatModifierIterator tmp
;
851 tmp
.fmt_idx
= iter
->fmt_idx
;
852 tmp
.mod_idx
= iter
->mod_idx
;
854 /* With the current state of things, DRM/KMS drivers are allowed to
855 * construct blobs having formats and no modifiers. Userspace can't
856 * legitimately abort in such cases.
858 * While waiting for the kernel to perhaps disallow formats with no
859 * modifiers in IN_FORMATS blobs, skip the format altogether.
862 has_fmt
= _drmModeFormatModifierGetNext(blob
, &tmp
);
863 if (has_fmt
&& tmp
.mod
!= DRM_FORMAT_MOD_INVALID
)
866 } while (has_fmt
&& tmp
.mod
== DRM_FORMAT_MOD_INVALID
);
871 drm_public
void drmModeFreePropertyBlob(drmModePropertyBlobPtr ptr
)
880 drm_public
int drmModeConnectorSetProperty(int fd
, uint32_t connector_id
,
881 uint32_t property_id
,
884 struct drm_mode_connector_set_property osp
;
887 osp
.connector_id
= connector_id
;
888 osp
.prop_id
= property_id
;
891 return DRM_IOCTL(fd
, DRM_IOCTL_MODE_SETPROPERTY
, &osp
);
895 * checks if a modesetting capable driver has attached to the pci id
896 * returns 0 if modesetting supported.
897 * -EINVAL or invalid bus id
898 * -ENOSYS if no modesetting support
900 drm_public
int drmCheckModesettingSupported(const char *busid
)
902 #if defined (__linux__)
903 char pci_dev_dir
[1024];
904 int domain
, bus
, dev
, func
;
909 ret
= sscanf(busid
, "pci:%04x:%02x:%02x.%d", &domain
, &bus
, &dev
, &func
);
913 sprintf(pci_dev_dir
, "/sys/bus/pci/devices/%04x:%02x:%02x.%d/drm",
914 domain
, bus
, dev
, func
);
916 sysdir
= opendir(pci_dev_dir
);
918 dent
= readdir(sysdir
);
920 if (!strncmp(dent
->d_name
, "controlD", 8)) {
925 dent
= readdir(sysdir
);
932 sprintf(pci_dev_dir
, "/sys/bus/pci/devices/%04x:%02x:%02x.%d/",
933 domain
, bus
, dev
, func
);
935 sysdir
= opendir(pci_dev_dir
);
939 dent
= readdir(sysdir
);
941 if (!strncmp(dent
->d_name
, "drm:controlD", 12)) {
946 dent
= readdir(sysdir
);
952 #elif defined (__FreeBSD__) || defined (__FreeBSD_kernel__)
955 int i
, modesetting
, ret
;
958 /* How many GPUs do we expect in the machine ? */
959 for (i
= 0; i
< 10; i
++) {
960 snprintf(oid
, sizeof(oid
), "hw.dri.%d.busid", i
);
961 len
= sizeof(sbusid
);
962 ret
= sysctlbyname(oid
, sbusid
, &len
, NULL
, 0);
968 if (strcmp(sbusid
, busid
) != 0)
970 snprintf(oid
, sizeof(oid
), "hw.dri.%d.modesetting", i
);
971 len
= sizeof(modesetting
);
972 ret
= sysctlbyname(oid
, &modesetting
, &len
, NULL
, 0);
973 if (ret
== -1 || len
!= sizeof(modesetting
))
975 return (modesetting
? 0 : -ENOSYS
);
977 #elif defined(__DragonFly__)
979 #elif defined(__OpenBSD__)
981 struct drm_mode_card_res res
;
984 if ((fd
= drmOpen(NULL
, busid
)) < 0)
987 memset(&res
, 0, sizeof(struct drm_mode_card_res
));
989 if (drmIoctl(fd
, DRM_IOCTL_MODE_GETRESOURCES
, &res
)) {
1000 drm_public
int drmModeCrtcGetGamma(int fd
, uint32_t crtc_id
, uint32_t size
,
1001 uint16_t *red
, uint16_t *green
,
1004 struct drm_mode_crtc_lut l
;
1007 l
.crtc_id
= crtc_id
;
1008 l
.gamma_size
= size
;
1009 l
.red
= VOID2U64(red
);
1010 l
.green
= VOID2U64(green
);
1011 l
.blue
= VOID2U64(blue
);
1013 return DRM_IOCTL(fd
, DRM_IOCTL_MODE_GETGAMMA
, &l
);
1016 drm_public
int drmModeCrtcSetGamma(int fd
, uint32_t crtc_id
, uint32_t size
,
1017 const uint16_t *red
, const uint16_t *green
,
1018 const uint16_t *blue
)
1020 struct drm_mode_crtc_lut l
;
1023 l
.crtc_id
= crtc_id
;
1024 l
.gamma_size
= size
;
1025 l
.red
= VOID2U64(red
);
1026 l
.green
= VOID2U64(green
);
1027 l
.blue
= VOID2U64(blue
);
1029 return DRM_IOCTL(fd
, DRM_IOCTL_MODE_SETGAMMA
, &l
);
1032 drm_public
int drmHandleEvent(int fd
, drmEventContextPtr evctx
)
1036 struct drm_event
*e
;
1037 struct drm_event_vblank
*vblank
;
1038 struct drm_event_crtc_sequence
*seq
;
1041 /* The DRM read semantics guarantees that we always get only
1042 * complete events. */
1044 len
= read(fd
, buffer
, sizeof buffer
);
1047 if (len
< (int)sizeof *e
)
1052 e
= (struct drm_event
*)(buffer
+ i
);
1054 case DRM_EVENT_VBLANK
:
1055 if (evctx
->version
< 1 ||
1056 evctx
->vblank_handler
== NULL
)
1058 vblank
= (struct drm_event_vblank
*) e
;
1059 evctx
->vblank_handler(fd
,
1063 U642VOID (vblank
->user_data
));
1065 case DRM_EVENT_FLIP_COMPLETE
:
1066 vblank
= (struct drm_event_vblank
*) e
;
1067 user_data
= U642VOID (vblank
->user_data
);
1069 if (evctx
->version
>= 3 && evctx
->page_flip_handler2
)
1070 evctx
->page_flip_handler2(fd
,
1076 else if (evctx
->version
>= 2 && evctx
->page_flip_handler
)
1077 evctx
->page_flip_handler(fd
,
1083 case DRM_EVENT_CRTC_SEQUENCE
:
1084 seq
= (struct drm_event_crtc_sequence
*) e
;
1085 if (evctx
->version
>= 4 && evctx
->sequence_handler
)
1086 evctx
->sequence_handler(fd
,
1100 drm_public
int drmModePageFlip(int fd
, uint32_t crtc_id
, uint32_t fb_id
,
1101 uint32_t flags
, void *user_data
)
1103 struct drm_mode_crtc_page_flip flip
;
1107 flip
.crtc_id
= crtc_id
;
1108 flip
.user_data
= VOID2U64(user_data
);
1111 return DRM_IOCTL(fd
, DRM_IOCTL_MODE_PAGE_FLIP
, &flip
);
1114 drm_public
int drmModePageFlipTarget(int fd
, uint32_t crtc_id
, uint32_t fb_id
,
1115 uint32_t flags
, void *user_data
,
1116 uint32_t target_vblank
)
1118 struct drm_mode_crtc_page_flip_target flip_target
;
1120 memclear(flip_target
);
1121 flip_target
.fb_id
= fb_id
;
1122 flip_target
.crtc_id
= crtc_id
;
1123 flip_target
.user_data
= VOID2U64(user_data
);
1124 flip_target
.flags
= flags
;
1125 flip_target
.sequence
= target_vblank
;
1127 return DRM_IOCTL(fd
, DRM_IOCTL_MODE_PAGE_FLIP
, &flip_target
);
1130 drm_public
int drmModeSetPlane(int fd
, uint32_t plane_id
, uint32_t crtc_id
,
1131 uint32_t fb_id
, uint32_t flags
,
1132 int32_t crtc_x
, int32_t crtc_y
,
1133 uint32_t crtc_w
, uint32_t crtc_h
,
1134 uint32_t src_x
, uint32_t src_y
,
1135 uint32_t src_w
, uint32_t src_h
)
1137 struct drm_mode_set_plane s
;
1140 s
.plane_id
= plane_id
;
1141 s
.crtc_id
= crtc_id
;
1153 return DRM_IOCTL(fd
, DRM_IOCTL_MODE_SETPLANE
, &s
);
1156 drm_public drmModePlanePtr
drmModeGetPlane(int fd
, uint32_t plane_id
)
1158 struct drm_mode_get_plane ovr
, counts
;
1159 drmModePlanePtr r
= 0;
1163 ovr
.plane_id
= plane_id
;
1164 if (drmIoctl(fd
, DRM_IOCTL_MODE_GETPLANE
, &ovr
))
1169 if (ovr
.count_format_types
) {
1170 ovr
.format_type_ptr
= VOID2U64(drmMalloc(ovr
.count_format_types
*
1172 if (!ovr
.format_type_ptr
)
1176 if (drmIoctl(fd
, DRM_IOCTL_MODE_GETPLANE
, &ovr
))
1179 if (counts
.count_format_types
< ovr
.count_format_types
) {
1180 drmFree(U642VOID(ovr
.format_type_ptr
));
1184 if (!(r
= drmMalloc(sizeof(*r
))))
1187 r
->count_formats
= ovr
.count_format_types
;
1188 r
->plane_id
= ovr
.plane_id
;
1189 r
->crtc_id
= ovr
.crtc_id
;
1190 r
->fb_id
= ovr
.fb_id
;
1191 r
->possible_crtcs
= ovr
.possible_crtcs
;
1192 r
->gamma_size
= ovr
.gamma_size
;
1193 r
->formats
= drmAllocCpy(U642VOID(ovr
.format_type_ptr
),
1194 ovr
.count_format_types
, sizeof(uint32_t));
1195 if (ovr
.count_format_types
&& !r
->formats
) {
1196 drmFree(r
->formats
);
1202 drmFree(U642VOID(ovr
.format_type_ptr
));
1207 drm_public
void drmModeFreePlane(drmModePlanePtr ptr
)
1212 drmFree(ptr
->formats
);
1216 drm_public drmModePlaneResPtr
drmModeGetPlaneResources(int fd
)
1218 struct drm_mode_get_plane_res res
, counts
;
1219 drmModePlaneResPtr r
= 0;
1223 if (drmIoctl(fd
, DRM_IOCTL_MODE_GETPLANERESOURCES
, &res
))
1228 if (res
.count_planes
) {
1229 res
.plane_id_ptr
= VOID2U64(drmMalloc(res
.count_planes
*
1231 if (!res
.plane_id_ptr
)
1235 if (drmIoctl(fd
, DRM_IOCTL_MODE_GETPLANERESOURCES
, &res
))
1238 if (counts
.count_planes
< res
.count_planes
) {
1239 drmFree(U642VOID(res
.plane_id_ptr
));
1243 if (!(r
= drmMalloc(sizeof(*r
))))
1246 r
->count_planes
= res
.count_planes
;
1247 r
->planes
= drmAllocCpy(U642VOID(res
.plane_id_ptr
),
1248 res
.count_planes
, sizeof(uint32_t));
1249 if (res
.count_planes
&& !r
->planes
) {
1256 drmFree(U642VOID(res
.plane_id_ptr
));
1261 drm_public
void drmModeFreePlaneResources(drmModePlaneResPtr ptr
)
1266 drmFree(ptr
->planes
);
1270 drm_public drmModeObjectPropertiesPtr
drmModeObjectGetProperties(int fd
,
1272 uint32_t object_type
)
1274 struct drm_mode_obj_get_properties properties
;
1275 drmModeObjectPropertiesPtr ret
= NULL
;
1279 memclear(properties
);
1280 properties
.obj_id
= object_id
;
1281 properties
.obj_type
= object_type
;
1283 if (drmIoctl(fd
, DRM_IOCTL_MODE_OBJ_GETPROPERTIES
, &properties
))
1286 count
= properties
.count_props
;
1289 properties
.props_ptr
= VOID2U64(drmMalloc(count
*
1291 if (!properties
.props_ptr
)
1293 properties
.prop_values_ptr
= VOID2U64(drmMalloc(count
*
1295 if (!properties
.prop_values_ptr
)
1299 if (drmIoctl(fd
, DRM_IOCTL_MODE_OBJ_GETPROPERTIES
, &properties
))
1302 if (count
< properties
.count_props
) {
1303 drmFree(U642VOID(properties
.props_ptr
));
1304 drmFree(U642VOID(properties
.prop_values_ptr
));
1307 count
= properties
.count_props
;
1309 ret
= drmMalloc(sizeof(*ret
));
1313 ret
->count_props
= count
;
1314 ret
->props
= drmAllocCpy(U642VOID(properties
.props_ptr
),
1315 count
, sizeof(uint32_t));
1316 ret
->prop_values
= drmAllocCpy(U642VOID(properties
.prop_values_ptr
),
1317 count
, sizeof(uint64_t));
1318 if (ret
->count_props
&& (!ret
->props
|| !ret
->prop_values
)) {
1319 drmFree(ret
->props
);
1320 drmFree(ret
->prop_values
);
1326 drmFree(U642VOID(properties
.props_ptr
));
1327 drmFree(U642VOID(properties
.prop_values_ptr
));
1331 drm_public
void drmModeFreeObjectProperties(drmModeObjectPropertiesPtr ptr
)
1335 drmFree(ptr
->props
);
1336 drmFree(ptr
->prop_values
);
1340 drm_public
int drmModeObjectSetProperty(int fd
, uint32_t object_id
, uint32_t object_type
,
1341 uint32_t property_id
, uint64_t value
)
1343 struct drm_mode_obj_set_property prop
;
1347 prop
.prop_id
= property_id
;
1348 prop
.obj_id
= object_id
;
1349 prop
.obj_type
= object_type
;
1351 return DRM_IOCTL(fd
, DRM_IOCTL_MODE_OBJ_SETPROPERTY
, &prop
);
1354 typedef struct _drmModeAtomicReqItem drmModeAtomicReqItem
, *drmModeAtomicReqItemPtr
;
1356 struct _drmModeAtomicReqItem
{
1358 uint32_t property_id
;
1363 struct _drmModeAtomicReq
{
1365 uint32_t size_items
;
1366 drmModeAtomicReqItemPtr items
;
1369 drm_public drmModeAtomicReqPtr
drmModeAtomicAlloc(void)
1371 drmModeAtomicReqPtr req
;
1373 req
= drmMalloc(sizeof *req
);
1379 req
->size_items
= 0;
1384 drm_public drmModeAtomicReqPtr
drmModeAtomicDuplicate(const drmModeAtomicReqPtr old
)
1386 drmModeAtomicReqPtr
new;
1391 new = drmMalloc(sizeof *new);
1395 new->cursor
= old
->cursor
;
1396 new->size_items
= old
->size_items
;
1398 if (old
->size_items
) {
1399 new->items
= drmMalloc(old
->size_items
* sizeof(*new->items
));
1404 memcpy(new->items
, old
->items
,
1405 old
->cursor
* sizeof(*new->items
));
1413 drm_public
int drmModeAtomicMerge(drmModeAtomicReqPtr base
,
1414 const drmModeAtomicReqPtr augment
)
1421 if (!augment
|| augment
->cursor
== 0)
1424 if (base
->cursor
+ augment
->cursor
>= base
->size_items
) {
1425 drmModeAtomicReqItemPtr
new;
1426 int saved_size
= base
->size_items
;
1428 base
->size_items
= base
->cursor
+ augment
->cursor
;
1429 new = realloc(base
->items
,
1430 base
->size_items
* sizeof(*base
->items
));
1432 base
->size_items
= saved_size
;
1438 memcpy(&base
->items
[base
->cursor
], augment
->items
,
1439 augment
->cursor
* sizeof(*augment
->items
));
1440 for (i
= base
->cursor
; i
< base
->cursor
+ augment
->cursor
; i
++)
1441 base
->items
[i
].cursor
= i
;
1442 base
->cursor
+= augment
->cursor
;
1447 drm_public
int drmModeAtomicGetCursor(const drmModeAtomicReqPtr req
)
1454 drm_public
void drmModeAtomicSetCursor(drmModeAtomicReqPtr req
, int cursor
)
1457 req
->cursor
= cursor
;
1460 drm_public
int drmModeAtomicAddProperty(drmModeAtomicReqPtr req
,
1462 uint32_t property_id
,
1468 if (object_id
== 0 || property_id
== 0)
1471 if (req
->cursor
>= req
->size_items
) {
1472 const uint32_t item_size_inc
= getpagesize() / sizeof(*req
->items
);
1473 drmModeAtomicReqItemPtr
new;
1475 req
->size_items
+= item_size_inc
;
1476 new = realloc(req
->items
, req
->size_items
* sizeof(*req
->items
));
1478 req
->size_items
-= item_size_inc
;
1484 req
->items
[req
->cursor
].object_id
= object_id
;
1485 req
->items
[req
->cursor
].property_id
= property_id
;
1486 req
->items
[req
->cursor
].value
= value
;
1487 req
->items
[req
->cursor
].cursor
= req
->cursor
;
1493 drm_public
void drmModeAtomicFree(drmModeAtomicReqPtr req
)
1499 drmFree(req
->items
);
1503 static int sort_req_list(const void *misc
, const void *other
)
1505 const drmModeAtomicReqItem
*first
= misc
;
1506 const drmModeAtomicReqItem
*second
= other
;
1508 if (first
->object_id
!= second
->object_id
)
1509 return first
->object_id
- second
->object_id
;
1510 else if (first
->property_id
!= second
->property_id
)
1511 return first
->property_id
- second
->property_id
;
1513 return first
->cursor
- second
->cursor
;
1516 drm_public
int drmModeAtomicCommit(int fd
, const drmModeAtomicReqPtr req
,
1517 uint32_t flags
, void *user_data
)
1519 drmModeAtomicReqPtr sorted
;
1520 struct drm_mode_atomic atomic
;
1521 uint32_t *objs_ptr
= NULL
;
1522 uint32_t *count_props_ptr
= NULL
;
1523 uint32_t *props_ptr
= NULL
;
1524 uint64_t *prop_values_ptr
= NULL
;
1525 uint32_t last_obj_id
= 0;
1533 if (req
->cursor
== 0)
1536 sorted
= drmModeAtomicDuplicate(req
);
1542 /* Sort the list by object ID, then by property ID. */
1543 qsort(sorted
->items
, sorted
->cursor
, sizeof(*sorted
->items
),
1546 /* Now the list is sorted, eliminate duplicate property sets. */
1547 for (i
= 0; i
< sorted
->cursor
; i
++) {
1548 if (sorted
->items
[i
].object_id
!= last_obj_id
) {
1549 atomic
.count_objs
++;
1550 last_obj_id
= sorted
->items
[i
].object_id
;
1553 if (i
== sorted
->cursor
- 1)
1556 if (sorted
->items
[i
].object_id
!= sorted
->items
[i
+ 1].object_id
||
1557 sorted
->items
[i
].property_id
!= sorted
->items
[i
+ 1].property_id
)
1560 memmove(&sorted
->items
[i
], &sorted
->items
[i
+ 1],
1561 (sorted
->cursor
- i
- 1) * sizeof(*sorted
->items
));
1565 for (i
= 0; i
< sorted
->cursor
; i
++)
1566 sorted
->items
[i
].cursor
= i
;
1568 objs_ptr
= drmMalloc(atomic
.count_objs
* sizeof objs_ptr
[0]);
1574 count_props_ptr
= drmMalloc(atomic
.count_objs
* sizeof count_props_ptr
[0]);
1575 if (!count_props_ptr
) {
1580 props_ptr
= drmMalloc(sorted
->cursor
* sizeof props_ptr
[0]);
1586 prop_values_ptr
= drmMalloc(sorted
->cursor
* sizeof prop_values_ptr
[0]);
1587 if (!prop_values_ptr
) {
1592 for (i
= 0, last_obj_id
= 0; i
< sorted
->cursor
; i
++) {
1593 if (sorted
->items
[i
].object_id
!= last_obj_id
) {
1595 objs_ptr
[obj_idx
] = sorted
->items
[i
].object_id
;
1596 last_obj_id
= objs_ptr
[obj_idx
];
1599 count_props_ptr
[obj_idx
]++;
1600 props_ptr
[i
] = sorted
->items
[i
].property_id
;
1601 prop_values_ptr
[i
] = sorted
->items
[i
].value
;
1605 atomic
.flags
= flags
;
1606 atomic
.objs_ptr
= VOID2U64(objs_ptr
);
1607 atomic
.count_props_ptr
= VOID2U64(count_props_ptr
);
1608 atomic
.props_ptr
= VOID2U64(props_ptr
);
1609 atomic
.prop_values_ptr
= VOID2U64(prop_values_ptr
);
1610 atomic
.user_data
= VOID2U64(user_data
);
1612 ret
= DRM_IOCTL(fd
, DRM_IOCTL_MODE_ATOMIC
, &atomic
);
1616 drmFree(count_props_ptr
);
1618 drmFree(prop_values_ptr
);
1619 drmModeAtomicFree(sorted
);
1625 drmModeCreatePropertyBlob(int fd
, const void *data
, size_t length
,
1628 struct drm_mode_create_blob create
;
1631 if (length
>= 0xffffffff)
1636 create
.length
= length
;
1637 create
.data
= (uintptr_t) data
;
1641 ret
= DRM_IOCTL(fd
, DRM_IOCTL_MODE_CREATEPROPBLOB
, &create
);
1645 *id
= create
.blob_id
;
1650 drmModeDestroyPropertyBlob(int fd
, uint32_t id
)
1652 struct drm_mode_destroy_blob destroy
;
1655 destroy
.blob_id
= id
;
1656 return DRM_IOCTL(fd
, DRM_IOCTL_MODE_DESTROYPROPBLOB
, &destroy
);
1660 drmModeCreateLease(int fd
, const uint32_t *objects
, int num_objects
, int flags
,
1661 uint32_t *lessee_id
)
1663 struct drm_mode_create_lease create
;
1667 create
.object_ids
= (uintptr_t) objects
;
1668 create
.object_count
= num_objects
;
1669 create
.flags
= flags
;
1671 ret
= DRM_IOCTL(fd
, DRM_IOCTL_MODE_CREATE_LEASE
, &create
);
1673 *lessee_id
= create
.lessee_id
;
1679 drm_public drmModeLesseeListPtr
1680 drmModeListLessees(int fd
)
1682 struct drm_mode_list_lessees list
;
1684 drmModeLesseeListPtr ret
;
1688 if (DRM_IOCTL(fd
, DRM_IOCTL_MODE_LIST_LESSEES
, &list
))
1691 count
= list
.count_lessees
;
1692 ret
= drmMalloc(sizeof (drmModeLesseeListRes
) + count
* sizeof (ret
->lessees
[0]));
1696 list
.lessees_ptr
= VOID2U64(&ret
->lessees
[0]);
1697 if (DRM_IOCTL(fd
, DRM_IOCTL_MODE_LIST_LESSEES
, &list
)) {
1706 drm_public drmModeObjectListPtr
1707 drmModeGetLease(int fd
)
1709 struct drm_mode_get_lease get
;
1711 drmModeObjectListPtr ret
;
1715 if (DRM_IOCTL(fd
, DRM_IOCTL_MODE_GET_LEASE
, &get
))
1718 count
= get
.count_objects
;
1719 ret
= drmMalloc(sizeof (drmModeObjectListRes
) + count
* sizeof (ret
->objects
[0]));
1723 get
.objects_ptr
= VOID2U64(&ret
->objects
[0]);
1724 if (DRM_IOCTL(fd
, DRM_IOCTL_MODE_GET_LEASE
, &get
)) {
1734 drmModeRevokeLease(int fd
, uint32_t lessee_id
)
1736 struct drm_mode_revoke_lease revoke
;
1741 revoke
.lessee_id
= lessee_id
;
1743 ret
= DRM_IOCTL(fd
, DRM_IOCTL_MODE_REVOKE_LEASE
, &revoke
);
1749 drm_public drmModeFB2Ptr
1750 drmModeGetFB2(int fd
, uint32_t fb_id
)
1752 struct drm_mode_fb_cmd2 get
= {
1758 err
= DRM_IOCTL(fd
, DRM_IOCTL_MODE_GETFB2
, &get
);
1762 ret
= drmMalloc(sizeof(drmModeFB2
));
1767 ret
->width
= get
.width
;
1768 ret
->height
= get
.height
;
1769 ret
->pixel_format
= get
.pixel_format
;
1770 ret
->flags
= get
.flags
;
1771 ret
->modifier
= get
.modifier
[0];
1772 memcpy(ret
->handles
, get
.handles
, sizeof(uint32_t) * 4);
1773 memcpy(ret
->pitches
, get
.pitches
, sizeof(uint32_t) * 4);
1774 memcpy(ret
->offsets
, get
.offsets
, sizeof(uint32_t) * 4);
1779 drm_public
void drmModeFreeFB2(drmModeFB2Ptr ptr
)
1784 drm_public
const char *
1785 drmModeGetConnectorTypeName(uint32_t connector_type
)
1787 /* Keep the strings in sync with the kernel's drm_connector_enum_list in
1788 * drm_connector.c. */
1789 switch (connector_type
) {
1790 case DRM_MODE_CONNECTOR_Unknown
:
1792 case DRM_MODE_CONNECTOR_VGA
:
1794 case DRM_MODE_CONNECTOR_DVII
:
1796 case DRM_MODE_CONNECTOR_DVID
:
1798 case DRM_MODE_CONNECTOR_DVIA
:
1800 case DRM_MODE_CONNECTOR_Composite
:
1802 case DRM_MODE_CONNECTOR_SVIDEO
:
1804 case DRM_MODE_CONNECTOR_LVDS
:
1806 case DRM_MODE_CONNECTOR_Component
:
1808 case DRM_MODE_CONNECTOR_9PinDIN
:
1810 case DRM_MODE_CONNECTOR_DisplayPort
:
1812 case DRM_MODE_CONNECTOR_HDMIA
:
1814 case DRM_MODE_CONNECTOR_HDMIB
:
1816 case DRM_MODE_CONNECTOR_TV
:
1818 case DRM_MODE_CONNECTOR_eDP
:
1820 case DRM_MODE_CONNECTOR_VIRTUAL
:
1822 case DRM_MODE_CONNECTOR_DSI
:
1824 case DRM_MODE_CONNECTOR_DPI
:
1826 case DRM_MODE_CONNECTOR_WRITEBACK
:
1828 case DRM_MODE_CONNECTOR_SPI
:
1830 case DRM_MODE_CONNECTOR_USB
:
1838 drmModeCreateDumbBuffer(int fd
, uint32_t width
, uint32_t height
, uint32_t bpp
,
1839 uint32_t flags
, uint32_t *handle
, uint32_t *pitch
,
1843 struct drm_mode_create_dumb create
= {
1850 ret
= DRM_IOCTL(fd
, DRM_IOCTL_MODE_CREATE_DUMB
, &create
);
1854 *handle
= create
.handle
;
1855 *pitch
= create
.pitch
;
1856 *size
= create
.size
;
1861 drmModeDestroyDumbBuffer(int fd
, uint32_t handle
)
1863 struct drm_mode_destroy_dumb destroy
= {
1867 return DRM_IOCTL(fd
, DRM_IOCTL_MODE_DESTROY_DUMB
, &destroy
);
1871 drmModeMapDumbBuffer(int fd
, uint32_t handle
, uint64_t *offset
)
1874 struct drm_mode_map_dumb map
= {
1878 ret
= DRM_IOCTL(fd
, DRM_IOCTL_MODE_MAP_DUMB
, &map
);
1882 *offset
= map
.offset
;