OSDN Git Service

libdrm: drmNodeIsDRM: Add FreeBSD variant
[android-x86/external-libdrm.git] / xf86drmMode.c
index f7b5948..2399e8e 100644 (file)
  * platforms find which headers to include to get uint32_t
  */
 
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
 #include <limits.h>
 #include <stdint.h>
 #include <stdlib.h>
 #include <sys/ioctl.h>
-#ifdef HAVE_SYS_SYSCTL_H
+#if HAVE_SYS_SYSCTL_H
 #include <sys/sysctl.h>
 #endif
 #include <stdio.h>
 #include <stdbool.h>
 
+#include "libdrm_macros.h"
 #include "xf86drmMode.h"
 #include "xf86drm.h"
 #include <drm.h>
@@ -96,7 +93,7 @@ static void* drmAllocCpy(char *array, int count, int entry_size)
  * A couple of free functions.
  */
 
-void drmModeFreeModeInfo(drmModeModeInfoPtr ptr)
+drm_public void drmModeFreeModeInfo(drmModeModeInfoPtr ptr)
 {
        if (!ptr)
                return;
@@ -104,7 +101,7 @@ void drmModeFreeModeInfo(drmModeModeInfoPtr ptr)
        drmFree(ptr);
 }
 
-void drmModeFreeResources(drmModeResPtr ptr)
+drm_public void drmModeFreeResources(drmModeResPtr ptr)
 {
        if (!ptr)
                return;
@@ -116,7 +113,7 @@ void drmModeFreeResources(drmModeResPtr ptr)
        drmFree(ptr);
 }
 
-void drmModeFreeFB(drmModeFBPtr ptr)
+drm_public void drmModeFreeFB(drmModeFBPtr ptr)
 {
        if (!ptr)
                return;
@@ -125,7 +122,7 @@ void drmModeFreeFB(drmModeFBPtr ptr)
        drmFree(ptr);
 }
 
-void drmModeFreeCrtc(drmModeCrtcPtr ptr)
+drm_public void drmModeFreeCrtc(drmModeCrtcPtr ptr)
 {
        if (!ptr)
                return;
@@ -133,7 +130,7 @@ void drmModeFreeCrtc(drmModeCrtcPtr ptr)
        drmFree(ptr);
 }
 
-void drmModeFreeConnector(drmModeConnectorPtr ptr)
+drm_public void drmModeFreeConnector(drmModeConnectorPtr ptr)
 {
        if (!ptr)
                return;
@@ -145,7 +142,7 @@ void drmModeFreeConnector(drmModeConnectorPtr ptr)
        drmFree(ptr);
 }
 
-void drmModeFreeEncoder(drmModeEncoderPtr ptr)
+drm_public void drmModeFreeEncoder(drmModeEncoderPtr ptr)
 {
        drmFree(ptr);
 }
@@ -154,7 +151,7 @@ void drmModeFreeEncoder(drmModeEncoderPtr ptr)
  * ModeSetting functions.
  */
 
-drmModeResPtr drmModeGetResources(int fd)
+drm_public drmModeResPtr drmModeGetResources(int fd)
 {
        struct drm_mode_card_res res, counts;
        drmModeResPtr r = 0;
@@ -248,9 +245,10 @@ err_allocs:
        return r;
 }
 
-int drmModeAddFB(int fd, uint32_t width, uint32_t height, uint8_t depth,
-                uint8_t bpp, uint32_t pitch, uint32_t bo_handle,
-                uint32_t *buf_id)
+
+drm_public int drmModeAddFB(int fd, uint32_t width, uint32_t height, uint8_t depth,
+                            uint8_t bpp, uint32_t pitch, uint32_t bo_handle,
+                            uint32_t *buf_id)
 {
        struct drm_mode_fb_cmd f;
        int ret;
@@ -270,10 +268,10 @@ int drmModeAddFB(int fd, uint32_t width, uint32_t height, uint8_t depth,
        return 0;
 }
 
-int drmModeAddFB2(int fd, uint32_t width, uint32_t height,
-                 uint32_t pixel_format, uint32_t bo_handles[4],
-                 uint32_t pitches[4], uint32_t offsets[4],
-                 uint32_t *buf_id, uint32_t flags)
+drm_public int drmModeAddFB2WithModifiers(int fd, uint32_t width,
+               uint32_t height, uint32_t pixel_format, const uint32_t bo_handles[4],
+               const uint32_t pitches[4], const uint32_t offsets[4],
+               const uint64_t modifier[4], uint32_t *buf_id, uint32_t flags)
 {
        struct drm_mode_fb_cmd2 f;
        int ret;
@@ -286,6 +284,8 @@ int drmModeAddFB2(int fd, uint32_t width, uint32_t height,
        memcpy(f.handles, bo_handles, 4 * sizeof(bo_handles[0]));
        memcpy(f.pitches, pitches, 4 * sizeof(pitches[0]));
        memcpy(f.offsets, offsets, 4 * sizeof(offsets[0]));
+       if (modifier)
+               memcpy(f.modifier, modifier, 4 * sizeof(modifier[0]));
 
        if ((ret = DRM_IOCTL(fd, DRM_IOCTL_MODE_ADDFB2, &f)))
                return ret;
@@ -294,12 +294,23 @@ int drmModeAddFB2(int fd, uint32_t width, uint32_t height,
        return 0;
 }
 
-int drmModeRmFB(int fd, uint32_t bufferId)
+drm_public int drmModeAddFB2(int fd, uint32_t width, uint32_t height,
+               uint32_t pixel_format, const uint32_t bo_handles[4],
+               const uint32_t pitches[4], const uint32_t offsets[4],
+               uint32_t *buf_id, uint32_t flags)
+{
+       return drmModeAddFB2WithModifiers(fd, width, height,
+                                         pixel_format, bo_handles,
+                                         pitches, offsets, NULL,
+                                         buf_id, flags);
+}
+
+drm_public int drmModeRmFB(int fd, uint32_t bufferId)
 {
        return DRM_IOCTL(fd, DRM_IOCTL_MODE_RMFB, &bufferId);
 }
 
-drmModeFBPtr drmModeGetFB(int fd, uint32_t buf)
+drm_public drmModeFBPtr drmModeGetFB(int fd, uint32_t buf)
 {
        struct drm_mode_fb_cmd info;
        drmModeFBPtr r;
@@ -324,7 +335,7 @@ drmModeFBPtr drmModeGetFB(int fd, uint32_t buf)
        return r;
 }
 
-int drmModeDirtyFB(int fd, uint32_t bufferId,
+drm_public int drmModeDirtyFB(int fd, uint32_t bufferId,
                   drmModeClipPtr clips, uint32_t num_clips)
 {
        struct drm_mode_fb_dirty_cmd dirty;
@@ -341,7 +352,7 @@ int drmModeDirtyFB(int fd, uint32_t bufferId,
  * Crtc functions
  */
 
-drmModeCrtcPtr drmModeGetCrtc(int fd, uint32_t crtcId)
+drm_public drmModeCrtcPtr drmModeGetCrtc(int fd, uint32_t crtcId)
 {
        struct drm_mode_crtc crtc;
        drmModeCrtcPtr r;
@@ -373,7 +384,7 @@ drmModeCrtcPtr drmModeGetCrtc(int fd, uint32_t crtcId)
        return r;
 }
 
-int drmModeSetCrtc(int fd, uint32_t crtcId, uint32_t bufferId,
+drm_public int drmModeSetCrtc(int fd, uint32_t crtcId, uint32_t bufferId,
                   uint32_t x, uint32_t y, uint32_t *connectors, int count,
                   drmModeModeInfoPtr mode)
 {
@@ -398,7 +409,8 @@ int drmModeSetCrtc(int fd, uint32_t crtcId, uint32_t bufferId,
  * Cursor manipulation
  */
 
-int drmModeSetCursor(int fd, uint32_t crtcId, uint32_t bo_handle, uint32_t width, uint32_t height)
+drm_public int drmModeSetCursor(int fd, uint32_t crtcId, uint32_t bo_handle,
+                                                               uint32_t width, uint32_t height)
 {
        struct drm_mode_cursor arg;
 
@@ -412,7 +424,9 @@ int drmModeSetCursor(int fd, uint32_t crtcId, uint32_t bo_handle, uint32_t width
        return DRM_IOCTL(fd, DRM_IOCTL_MODE_CURSOR, &arg);
 }
 
-int drmModeSetCursor2(int fd, uint32_t crtcId, uint32_t bo_handle, uint32_t width, uint32_t height, int32_t hot_x, int32_t hot_y)
+drm_public int drmModeSetCursor2(int fd, uint32_t crtcId, uint32_t bo_handle,
+                                                                uint32_t width, uint32_t height, int32_t hot_x,
+                                                                int32_t hot_y)
 {
        struct drm_mode_cursor2 arg;
 
@@ -428,7 +442,7 @@ int drmModeSetCursor2(int fd, uint32_t crtcId, uint32_t bo_handle, uint32_t widt
        return DRM_IOCTL(fd, DRM_IOCTL_MODE_CURSOR2, &arg);
 }
 
-int drmModeMoveCursor(int fd, uint32_t crtcId, int x, int y)
+drm_public int drmModeMoveCursor(int fd, uint32_t crtcId, int x, int y)
 {
        struct drm_mode_cursor arg;
 
@@ -444,7 +458,7 @@ int drmModeMoveCursor(int fd, uint32_t crtcId, int x, int y)
 /*
  * Encoder get
  */
-drmModeEncoderPtr drmModeGetEncoder(int fd, uint32_t encoder_id)
+drm_public drmModeEncoderPtr drmModeGetEncoder(int fd, uint32_t encoder_id)
 {
        struct drm_mode_get_encoder enc;
        drmModeEncoderPtr r = NULL;
@@ -576,17 +590,17 @@ err_allocs:
        return r;
 }
 
-drmModeConnectorPtr drmModeGetConnector(int fd, uint32_t connector_id)
+drm_public drmModeConnectorPtr drmModeGetConnector(int fd, uint32_t connector_id)
 {
        return _drmModeGetConnector(fd, connector_id, 1);
 }
 
-drmModeConnectorPtr drmModeGetConnectorCurrent(int fd, uint32_t connector_id)
+drm_public drmModeConnectorPtr drmModeGetConnectorCurrent(int fd, uint32_t connector_id)
 {
        return _drmModeGetConnector(fd, connector_id, 0);
 }
 
-int drmModeAttachMode(int fd, uint32_t connector_id, drmModeModeInfoPtr mode_info)
+drm_public int drmModeAttachMode(int fd, uint32_t connector_id, drmModeModeInfoPtr mode_info)
 {
        struct drm_mode_mode_cmd res;
 
@@ -597,7 +611,7 @@ int drmModeAttachMode(int fd, uint32_t connector_id, drmModeModeInfoPtr mode_inf
        return DRM_IOCTL(fd, DRM_IOCTL_MODE_ATTACHMODE, &res);
 }
 
-int drmModeDetachMode(int fd, uint32_t connector_id, drmModeModeInfoPtr mode_info)
+drm_public int drmModeDetachMode(int fd, uint32_t connector_id, drmModeModeInfoPtr mode_info)
 {
        struct drm_mode_mode_cmd res;
 
@@ -608,7 +622,7 @@ int drmModeDetachMode(int fd, uint32_t connector_id, drmModeModeInfoPtr mode_inf
        return DRM_IOCTL(fd, DRM_IOCTL_MODE_DETACHMODE, &res);
 }
 
-drmModePropertyPtr drmModeGetProperty(int fd, uint32_t property_id)
+drm_public drmModePropertyPtr drmModeGetProperty(int fd, uint32_t property_id)
 {
        struct drm_mode_get_property prop;
        drmModePropertyPtr r;
@@ -636,7 +650,7 @@ drmModePropertyPtr drmModeGetProperty(int fd, uint32_t property_id)
        }
 
        if (!(r = drmMalloc(sizeof(*r))))
-               return NULL;
+               goto err_allocs;
 
        r->prop_id = prop.prop_id;
        r->count_values = prop.count_values;
@@ -662,7 +676,7 @@ err_allocs:
        return r;
 }
 
-void drmModeFreeProperty(drmModePropertyPtr ptr)
+drm_public void drmModeFreeProperty(drmModePropertyPtr ptr)
 {
        if (!ptr)
                return;
@@ -672,7 +686,8 @@ void drmModeFreeProperty(drmModePropertyPtr ptr)
        drmFree(ptr);
 }
 
-drmModePropertyBlobPtr drmModeGetPropertyBlob(int fd, uint32_t blob_id)
+drm_public drmModePropertyBlobPtr drmModeGetPropertyBlob(int fd,
+                                                                                                                uint32_t blob_id)
 {
        struct drm_mode_get_blob blob;
        drmModePropertyBlobPtr r;
@@ -703,7 +718,7 @@ err_allocs:
        return r;
 }
 
-void drmModeFreePropertyBlob(drmModePropertyBlobPtr ptr)
+drm_public void drmModeFreePropertyBlob(drmModePropertyBlobPtr ptr)
 {
        if (!ptr)
                return;
@@ -712,8 +727,9 @@ void drmModeFreePropertyBlob(drmModePropertyBlobPtr ptr)
        drmFree(ptr);
 }
 
-int drmModeConnectorSetProperty(int fd, uint32_t connector_id, uint32_t property_id,
-                            uint64_t value)
+drm_public int drmModeConnectorSetProperty(int fd, uint32_t connector_id,
+                                                                                  uint32_t property_id,
+                                                                                  uint64_t value)
 {
        struct drm_mode_connector_set_property osp;
 
@@ -731,7 +747,7 @@ int drmModeConnectorSetProperty(int fd, uint32_t connector_id, uint32_t property
  *  -EINVAL or invalid bus id
  *  -ENOSYS if no modesetting support
 */
-int drmCheckModesettingSupported(const char *busid)
+drm_public int drmCheckModesettingSupported(const char *busid)
 {
 #if defined (__linux__)
        char pci_dev_dir[1024];
@@ -818,8 +834,7 @@ int drmCheckModesettingSupported(const char *busid)
        }
 #elif defined(__DragonFly__)
        return 0;
-#endif
-#ifdef __OpenBSD__
+#elif defined(__OpenBSD__)
        int     fd;
        struct drm_mode_card_res res;
        drmModeResPtr r = 0;
@@ -840,8 +855,9 @@ int drmCheckModesettingSupported(const char *busid)
        return -ENOSYS;
 }
 
-int drmModeCrtcGetGamma(int fd, uint32_t crtc_id, uint32_t size,
-                       uint16_t *red, uint16_t *green, uint16_t *blue)
+drm_public int drmModeCrtcGetGamma(int fd, uint32_t crtc_id, uint32_t size,
+                                                                  uint16_t *red, uint16_t *green,
+                                                                  uint16_t *blue)
 {
        struct drm_mode_crtc_lut l;
 
@@ -855,8 +871,9 @@ int drmModeCrtcGetGamma(int fd, uint32_t crtc_id, uint32_t size,
        return DRM_IOCTL(fd, DRM_IOCTL_MODE_GETGAMMA, &l);
 }
 
-int drmModeCrtcSetGamma(int fd, uint32_t crtc_id, uint32_t size,
-                       uint16_t *red, uint16_t *green, uint16_t *blue)
+drm_public int drmModeCrtcSetGamma(int fd, uint32_t crtc_id, uint32_t size,
+                                                                  uint16_t *red, uint16_t *green,
+                                                                  uint16_t *blue)
 {
        struct drm_mode_crtc_lut l;
 
@@ -870,12 +887,14 @@ int drmModeCrtcSetGamma(int fd, uint32_t crtc_id, uint32_t size,
        return DRM_IOCTL(fd, DRM_IOCTL_MODE_SETGAMMA, &l);
 }
 
-int drmHandleEvent(int fd, drmEventContextPtr evctx)
+drm_public int drmHandleEvent(int fd, drmEventContextPtr evctx)
 {
        char buffer[1024];
        int len, i;
        struct drm_event *e;
        struct drm_event_vblank *vblank;
+       struct drm_event_crtc_sequence *seq;
+       void *user_data;
 
        /* The DRM read semantics guarantees that we always get only
         * complete events. */
@@ -888,7 +907,7 @@ int drmHandleEvent(int fd, drmEventContextPtr evctx)
 
        i = 0;
        while (i < len) {
-               e = (struct drm_event *) &buffer[i];
+               e = (struct drm_event *)(buffer + i);
                switch (e->type) {
                case DRM_EVENT_VBLANK:
                        if (evctx->version < 1 ||
@@ -902,15 +921,30 @@ int drmHandleEvent(int fd, drmEventContextPtr evctx)
                                              U642VOID (vblank->user_data));
                        break;
                case DRM_EVENT_FLIP_COMPLETE:
-                       if (evctx->version < 2 ||
-                           evctx->page_flip_handler == NULL)
-                               break;
                        vblank = (struct drm_event_vblank *) e;
-                       evctx->page_flip_handler(fd,
-                                                vblank->sequence,
-                                                vblank->tv_sec,
-                                                vblank->tv_usec,
-                                                U642VOID (vblank->user_data));
+                       user_data = U642VOID (vblank->user_data);
+
+                       if (evctx->version >= 3 && evctx->page_flip_handler2)
+                               evctx->page_flip_handler2(fd,
+                                                        vblank->sequence,
+                                                        vblank->tv_sec,
+                                                        vblank->tv_usec,
+                                                        vblank->crtc_id,
+                                                        user_data);
+                       else if (evctx->version >= 2 && evctx->page_flip_handler)
+                               evctx->page_flip_handler(fd,
+                                                        vblank->sequence,
+                                                        vblank->tv_sec,
+                                                        vblank->tv_usec,
+                                                        user_data);
+                       break;
+               case DRM_EVENT_CRTC_SEQUENCE:
+                       seq = (struct drm_event_crtc_sequence *) e;
+                       if (evctx->version >= 4 && evctx->sequence_handler)
+                               evctx->sequence_handler(fd,
+                                                       seq->sequence,
+                                                       seq->time_ns,
+                                                       seq->user_data);
                        break;
                default:
                        break;
@@ -921,7 +955,7 @@ int drmHandleEvent(int fd, drmEventContextPtr evctx)
        return 0;
 }
 
-int drmModePageFlip(int fd, uint32_t crtc_id, uint32_t fb_id,
+drm_public int drmModePageFlip(int fd, uint32_t crtc_id, uint32_t fb_id,
                    uint32_t flags, void *user_data)
 {
        struct drm_mode_crtc_page_flip flip;
@@ -935,7 +969,23 @@ int drmModePageFlip(int fd, uint32_t crtc_id, uint32_t fb_id,
        return DRM_IOCTL(fd, DRM_IOCTL_MODE_PAGE_FLIP, &flip);
 }
 
-int drmModeSetPlane(int fd, uint32_t plane_id, uint32_t crtc_id,
+drm_public int drmModePageFlipTarget(int fd, uint32_t crtc_id, uint32_t fb_id,
+                         uint32_t flags, void *user_data,
+                         uint32_t target_vblank)
+{
+       struct drm_mode_crtc_page_flip_target flip_target;
+
+       memclear(flip_target);
+       flip_target.fb_id = fb_id;
+       flip_target.crtc_id = crtc_id;
+       flip_target.user_data = VOID2U64(user_data);
+       flip_target.flags = flags;
+       flip_target.sequence = target_vblank;
+
+       return DRM_IOCTL(fd, DRM_IOCTL_MODE_PAGE_FLIP, &flip_target);
+}
+
+drm_public int drmModeSetPlane(int fd, uint32_t plane_id, uint32_t crtc_id,
                    uint32_t fb_id, uint32_t flags,
                    int32_t crtc_x, int32_t crtc_y,
                    uint32_t crtc_w, uint32_t crtc_h,
@@ -961,7 +1011,7 @@ int drmModeSetPlane(int fd, uint32_t plane_id, uint32_t crtc_id,
        return DRM_IOCTL(fd, DRM_IOCTL_MODE_SETPLANE, &s);
 }
 
-drmModePlanePtr drmModeGetPlane(int fd, uint32_t plane_id)
+drm_public drmModePlanePtr drmModeGetPlane(int fd, uint32_t plane_id)
 {
        struct drm_mode_get_plane ovr, counts;
        drmModePlanePtr r = 0;
@@ -1012,7 +1062,7 @@ err_allocs:
        return r;
 }
 
-void drmModeFreePlane(drmModePlanePtr ptr)
+drm_public void drmModeFreePlane(drmModePlanePtr ptr)
 {
        if (!ptr)
                return;
@@ -1021,7 +1071,7 @@ void drmModeFreePlane(drmModePlanePtr ptr)
        drmFree(ptr);
 }
 
-drmModePlaneResPtr drmModeGetPlaneResources(int fd)
+drm_public drmModePlaneResPtr drmModeGetPlaneResources(int fd)
 {
        struct drm_mode_get_plane_res res, counts;
        drmModePlaneResPtr r = 0;
@@ -1066,7 +1116,7 @@ err_allocs:
        return r;
 }
 
-void drmModeFreePlaneResources(drmModePlaneResPtr ptr)
+drm_public void drmModeFreePlaneResources(drmModePlaneResPtr ptr)
 {
        if (!ptr)
                return;
@@ -1075,7 +1125,7 @@ void drmModeFreePlaneResources(drmModePlaneResPtr ptr)
        drmFree(ptr);
 }
 
-drmModeObjectPropertiesPtr drmModeObjectGetProperties(int fd,
+drm_public drmModeObjectPropertiesPtr drmModeObjectGetProperties(int fd,
                                                      uint32_t object_id,
                                                      uint32_t object_type)
 {
@@ -1136,7 +1186,7 @@ err_allocs:
        return ret;
 }
 
-void drmModeFreeObjectProperties(drmModeObjectPropertiesPtr ptr)
+drm_public void drmModeFreeObjectProperties(drmModeObjectPropertiesPtr ptr)
 {
        if (!ptr)
                return;
@@ -1145,7 +1195,7 @@ void drmModeFreeObjectProperties(drmModeObjectPropertiesPtr ptr)
        drmFree(ptr);
 }
 
-int drmModeObjectSetProperty(int fd, uint32_t object_id, uint32_t object_type,
+drm_public int drmModeObjectSetProperty(int fd, uint32_t object_id, uint32_t object_type,
                             uint32_t property_id, uint64_t value)
 {
        struct drm_mode_obj_set_property prop;
@@ -1173,7 +1223,7 @@ struct _drmModeAtomicReq {
        drmModeAtomicReqItemPtr items;
 };
 
-drmModeAtomicReqPtr drmModeAtomicAlloc(void)
+drm_public drmModeAtomicReqPtr drmModeAtomicAlloc(void)
 {
        drmModeAtomicReqPtr req;
 
@@ -1188,7 +1238,7 @@ drmModeAtomicReqPtr drmModeAtomicAlloc(void)
        return req;
 }
 
-drmModeAtomicReqPtr drmModeAtomicDuplicate(drmModeAtomicReqPtr old)
+drm_public drmModeAtomicReqPtr drmModeAtomicDuplicate(drmModeAtomicReqPtr old)
 {
        drmModeAtomicReqPtr new;
 
@@ -1209,7 +1259,7 @@ drmModeAtomicReqPtr drmModeAtomicDuplicate(drmModeAtomicReqPtr old)
                        return NULL;
                }
                memcpy(new->items, old->items,
-                      old->size_items * sizeof(*new->items));
+                      old->cursor * sizeof(*new->items));
        } else {
                new->items = NULL;
        }
@@ -1217,7 +1267,8 @@ drmModeAtomicReqPtr drmModeAtomicDuplicate(drmModeAtomicReqPtr old)
        return new;
 }
 
-int drmModeAtomicMerge(drmModeAtomicReqPtr base, drmModeAtomicReqPtr augment)
+drm_public int drmModeAtomicMerge(drmModeAtomicReqPtr base,
+                                  drmModeAtomicReqPtr augment)
 {
        if (!base)
                return -EINVAL;
@@ -1246,34 +1297,38 @@ int drmModeAtomicMerge(drmModeAtomicReqPtr base, drmModeAtomicReqPtr augment)
        return 0;
 }
 
-int drmModeAtomicGetCursor(drmModeAtomicReqPtr req)
+drm_public int drmModeAtomicGetCursor(drmModeAtomicReqPtr req)
 {
        if (!req)
                return -EINVAL;
        return req->cursor;
 }
 
-void drmModeAtomicSetCursor(drmModeAtomicReqPtr req, int cursor)
+drm_public void drmModeAtomicSetCursor(drmModeAtomicReqPtr req, int cursor)
 {
        if (req)
                req->cursor = cursor;
 }
 
-int drmModeAtomicAddProperty(drmModeAtomicReqPtr req,
-                            uint32_t object_id,
-                            uint32_t property_id,
-                            uint64_t value)
+drm_public int drmModeAtomicAddProperty(drmModeAtomicReqPtr req,
+                                        uint32_t object_id,
+                                        uint32_t property_id,
+                                        uint64_t value)
 {
        if (!req)
                return -EINVAL;
 
+       if (object_id == 0 || property_id == 0)
+               return -EINVAL;
+
        if (req->cursor >= req->size_items) {
+               const uint32_t item_size_inc = getpagesize() / sizeof(*req->items);
                drmModeAtomicReqItemPtr new;
 
-               req->size_items += 16;
+               req->size_items += item_size_inc;
                new = realloc(req->items, req->size_items * sizeof(*req->items));
                if (!new) {
-                       req->size_items -= 16;
+                       req->size_items -= item_size_inc;
                        return -ENOMEM;
                }
                req->items = new;
@@ -1287,7 +1342,7 @@ int drmModeAtomicAddProperty(drmModeAtomicReqPtr req,
        return req->cursor;
 }
 
-void drmModeAtomicFree(drmModeAtomicReqPtr req)
+drm_public void drmModeAtomicFree(drmModeAtomicReqPtr req)
 {
        if (!req)
                return;
@@ -1310,8 +1365,8 @@ static int sort_req_list(const void *misc, const void *other)
                return second->property_id - first->property_id;
 }
 
-int drmModeAtomicCommit(int fd, drmModeAtomicReqPtr req, uint32_t flags,
-                       void *user_data)
+drm_public int drmModeAtomicCommit(int fd, drmModeAtomicReqPtr req,
+                                   uint32_t flags, void *user_data)
 {
        drmModeAtomicReqPtr sorted;
        struct drm_mode_atomic atomic;
@@ -1415,8 +1470,9 @@ out:
        return ret;
 }
 
-int
-drmModeCreatePropertyBlob(int fd, const void *data, size_t length, uint32_t *id)
+drm_public int
+drmModeCreatePropertyBlob(int fd, const void *data, size_t length,
+                                     uint32_t *id)
 {
        struct drm_mode_create_blob create;
        int ret;
@@ -1439,7 +1495,7 @@ drmModeCreatePropertyBlob(int fd, const void *data, size_t length, uint32_t *id)
        return 0;
 }
 
-int
+drm_public int
 drmModeDestroyPropertyBlob(int fd, uint32_t id)
 {
        struct drm_mode_destroy_blob destroy;
@@ -1448,3 +1504,128 @@ drmModeDestroyPropertyBlob(int fd, uint32_t id)
        destroy.blob_id = id;
        return DRM_IOCTL(fd, DRM_IOCTL_MODE_DESTROYPROPBLOB, &destroy);
 }
+
+drm_public int
+drmModeCreateLease(int fd, const uint32_t *objects, int num_objects, int flags,
+                   uint32_t *lessee_id)
+{
+       struct drm_mode_create_lease create;
+       int ret;
+
+       memclear(create);
+       create.object_ids = (uintptr_t) objects;
+       create.object_count = num_objects;
+       create.flags = flags;
+
+       ret = DRM_IOCTL(fd, DRM_IOCTL_MODE_CREATE_LEASE, &create);
+       if (ret == 0) {
+               *lessee_id = create.lessee_id;
+               return create.fd;
+       }
+       return -errno;
+}
+
+drm_public drmModeLesseeListPtr
+drmModeListLessees(int fd)
+{
+       struct drm_mode_list_lessees list;
+       uint32_t count;
+       drmModeLesseeListPtr ret;
+
+       memclear(list);
+
+       if (DRM_IOCTL(fd, DRM_IOCTL_MODE_LIST_LESSEES, &list))
+               return NULL;
+
+       count = list.count_lessees;
+       ret = drmMalloc(sizeof (drmModeLesseeListRes) + count * sizeof (ret->lessees[0]));
+       if (!ret)
+               return NULL;
+
+       list.lessees_ptr = VOID2U64(&ret->lessees[0]);
+       if (DRM_IOCTL(fd, DRM_IOCTL_MODE_LIST_LESSEES, &list)) {
+               drmFree(ret);
+               return NULL;
+       }
+
+       ret->count = count;
+       return ret;
+}
+
+drm_public drmModeObjectListPtr
+drmModeGetLease(int fd)
+{
+       struct drm_mode_get_lease get;
+       uint32_t count;
+       drmModeObjectListPtr ret;
+
+       memclear(get);
+
+       if (DRM_IOCTL(fd, DRM_IOCTL_MODE_GET_LEASE, &get))
+               return NULL;
+
+       count = get.count_objects;
+       ret = drmMalloc(sizeof (drmModeObjectListRes) + count * sizeof (ret->objects[0]));
+       if (!ret)
+               return NULL;
+
+       get.objects_ptr = VOID2U64(&ret->objects[0]);
+       if (DRM_IOCTL(fd, DRM_IOCTL_MODE_GET_LEASE, &get)) {
+               drmFree(ret);
+               return NULL;
+       }
+
+       ret->count = count;
+       return ret;
+}
+
+drm_public int
+drmModeRevokeLease(int fd, uint32_t lessee_id)
+{
+       struct drm_mode_revoke_lease revoke;
+       int ret;
+
+       memclear(revoke);
+
+       revoke.lessee_id = lessee_id;
+
+       ret = DRM_IOCTL(fd, DRM_IOCTL_MODE_REVOKE_LEASE, &revoke);
+       if (ret == 0)
+               return 0;
+       return -errno;
+}
+
+drm_public drmModeFB2Ptr
+drmModeGetFB2(int fd, uint32_t fb_id)
+{
+       struct drm_mode_fb_cmd2 get = {
+               .fb_id = fb_id,
+       };
+       drmModeFB2Ptr ret;
+       int err;
+
+       err = DRM_IOCTL(fd, DRM_IOCTL_MODE_GETFB2, &get);
+       if (err != 0)
+               return NULL;
+
+       ret = drmMalloc(sizeof(drmModeFB2));
+       if (!ret)
+               return NULL;
+
+       ret->fb_id = fb_id;
+       ret->width = get.width;
+       ret->height = get.height;
+       ret->pixel_format = get.pixel_format;
+       ret->flags = get.flags;
+       ret->modifier = get.modifier[0];
+       memcpy(ret->handles, get.handles, sizeof(uint32_t) * 4);
+       memcpy(ret->pitches, get.pitches, sizeof(uint32_t) * 4);
+       memcpy(ret->offsets, get.offsets, sizeof(uint32_t) * 4);
+
+       return ret;
+}
+
+drm_public void drmModeFreeFB2(drmModeFB2Ptr ptr)
+{
+       drmFree(ptr);
+}