#define U642VOID(x) ((void *)(unsigned long)(x))
#define VOID2U64(x) ((uint64_t)(unsigned long)(x))
+static inline int DRM_IOCTL(int fd, int cmd, void *arg)
+{
+ int ret = drmIoctl(fd, cmd, arg);
+ return ret < 0 ? -errno : ret;
+}
+
/*
* Util functions
*/
r->crtcs = drmAllocCpy(U642VOID(res.crtc_id_ptr), res.count_crtcs, sizeof(uint32_t));
r->connectors = drmAllocCpy(U642VOID(res.connector_id_ptr), res.count_connectors, sizeof(uint32_t));
r->encoders = drmAllocCpy(U642VOID(res.encoder_id_ptr), res.count_encoders, sizeof(uint32_t));
- if (!r->fbs || !r->crtcs || !r->connectors || !r->encoders) {
+ if ((res.count_fbs && !r->fbs) ||
+ (res.count_crtcs && !r->crtcs) ||
+ (res.count_connectors && !r->connectors) ||
+ (res.count_encoders && !r->encoders))
+ {
drmFree(r->fbs);
drmFree(r->crtcs);
drmFree(r->connectors);
f.depth = depth;
f.handle = bo_handle;
- if ((ret = drmIoctl(fd, DRM_IOCTL_MODE_ADDFB, &f)))
+ if ((ret = DRM_IOCTL(fd, DRM_IOCTL_MODE_ADDFB, &f)))
return ret;
*buf_id = f.fb_id;
int drmModeRmFB(int fd, uint32_t bufferId)
{
- return drmIoctl(fd, DRM_IOCTL_MODE_RMFB, &bufferId);
+ return DRM_IOCTL(fd, DRM_IOCTL_MODE_RMFB, &bufferId);
}
dirty.clips_ptr = VOID2U64(clips);
dirty.num_clips = num_clips;
- return drmIoctl(fd, DRM_IOCTL_MODE_DIRTYFB, &dirty);
+ return DRM_IOCTL(fd, DRM_IOCTL_MODE_DIRTYFB, &dirty);
}
} else
crtc.mode_valid = 0;
- return drmIoctl(fd, DRM_IOCTL_MODE_SETCRTC, &crtc);
+ return DRM_IOCTL(fd, DRM_IOCTL_MODE_SETCRTC, &crtc);
}
/*
arg.height = height;
arg.handle = bo_handle;
- return drmIoctl(fd, DRM_IOCTL_MODE_CURSOR, &arg);
+ return DRM_IOCTL(fd, DRM_IOCTL_MODE_CURSOR, &arg);
}
int drmModeMoveCursor(int fd, uint32_t crtcId, int x, int y)
arg.x = x;
arg.y = y;
- return drmIoctl(fd, DRM_IOCTL_MODE_CURSOR, &arg);
+ return DRM_IOCTL(fd, DRM_IOCTL_MODE_CURSOR, &arg);
}
/*
drmModeConnectorPtr drmModeGetConnector(int fd, uint32_t connector_id)
{
- struct drm_mode_get_connector conn;
+ struct drm_mode_get_connector conn, counts;
drmModeConnectorPtr r = NULL;
+retry:
+ memset(&conn, 0, sizeof(struct drm_mode_get_connector));
conn.connector_id = connector_id;
- conn.connector_type_id = 0;
- conn.connector_type = 0;
- conn.count_modes = 0;
- conn.modes_ptr = 0;
- conn.count_props = 0;
- conn.props_ptr = 0;
- conn.prop_values_ptr = 0;
- conn.count_encoders = 0;
- conn.encoders_ptr = 0;
if (drmIoctl(fd, DRM_IOCTL_MODE_GETCONNECTOR, &conn))
return 0;
+ counts = conn;
+
if (conn.count_props) {
conn.props_ptr = VOID2U64(drmMalloc(conn.count_props*sizeof(uint32_t)));
+ if (!conn.props_ptr)
+ goto err_allocs;
conn.prop_values_ptr = VOID2U64(drmMalloc(conn.count_props*sizeof(uint64_t)));
+ if (!conn.prop_values_ptr)
+ goto err_allocs;
}
- if (conn.count_modes)
+ if (conn.count_modes) {
conn.modes_ptr = VOID2U64(drmMalloc(conn.count_modes*sizeof(struct drm_mode_modeinfo)));
+ if (!conn.modes_ptr)
+ goto err_allocs;
+ }
- if (conn.count_encoders)
+ if (conn.count_encoders) {
conn.encoders_ptr = VOID2U64(drmMalloc(conn.count_encoders*sizeof(uint32_t)));
+ if (!conn.encoders_ptr)
+ goto err_allocs;
+ }
if (drmIoctl(fd, DRM_IOCTL_MODE_GETCONNECTOR, &conn))
goto err_allocs;
+ /* The number of available connectors and etc may have changed with a
+ * hotplug event in between the ioctls, in which case the field is
+ * silently ignored by the kernel.
+ */
+ if (counts.count_props < conn.count_props ||
+ counts.count_modes < conn.count_modes ||
+ counts.count_encoders < conn.count_encoders) {
+ drmFree(U642VOID(conn.props_ptr));
+ drmFree(U642VOID(conn.prop_values_ptr));
+ drmFree(U642VOID(conn.modes_ptr));
+ drmFree(U642VOID(conn.encoders_ptr));
+
+ goto retry;
+ }
+
if(!(r = drmMalloc(sizeof(*r)))) {
goto err_allocs;
}
/* convert subpixel from kernel to userspace */
r->subpixel = conn.subpixel + 1;
r->count_modes = conn.count_modes;
- /* TODO we should test if these alloc & cpy fails. */
r->count_props = conn.count_props;
r->props = drmAllocCpy(U642VOID(conn.props_ptr), conn.count_props, sizeof(uint32_t));
r->prop_values = drmAllocCpy(U642VOID(conn.prop_values_ptr), conn.count_props, sizeof(uint64_t));
r->connector_type = conn.connector_type;
r->connector_type_id = conn.connector_type_id;
- if (!r->props || !r->prop_values || !r->modes || !r->encoders)
- goto err_allocs;
+ if ((r->count_props && !r->props) ||
+ (r->count_props && !r->prop_values) ||
+ (r->count_modes && !r->modes) ||
+ (r->count_encoders && !r->encoders)) {
+ drmFree(r->props);
+ drmFree(r->prop_values);
+ drmFree(r->modes);
+ drmFree(r->encoders);
+ drmFree(r);
+ r = 0;
+ }
err_allocs:
drmFree(U642VOID(conn.prop_values_ptr));
memcpy(&res.mode, mode_info, sizeof(struct drm_mode_modeinfo));
res.connector_id = connector_id;
- return drmIoctl(fd, DRM_IOCTL_MODE_ATTACHMODE, &res);
+ return DRM_IOCTL(fd, DRM_IOCTL_MODE_ATTACHMODE, &res);
}
int drmModeDetachMode(int fd, uint32_t connector_id, drmModeModeInfoPtr mode_info)
memcpy(&res.mode, mode_info, sizeof(struct drm_mode_modeinfo));
res.connector_id = connector_id;
- return drmIoctl(fd, DRM_IOCTL_MODE_DETACHMODE, &res);
+ return DRM_IOCTL(fd, DRM_IOCTL_MODE_DETACHMODE, &res);
}
}
if (!(r = drmMalloc(sizeof(*r))))
- return NULL;
+ goto err_allocs;
r->id = blob.blob_id;
r->length = blob.length;
uint64_t value)
{
struct drm_mode_connector_set_property osp;
- int ret;
osp.connector_id = connector_id;
osp.prop_id = property_id;
osp.value = value;
- if ((ret = drmIoctl(fd, DRM_IOCTL_MODE_SETPROPERTY, &osp)))
- return ret;
-
- return 0;
+ return DRM_IOCTL(fd, DRM_IOCTL_MODE_SETPROPERTY, &osp);
}
/*
int drmModeCrtcGetGamma(int fd, uint32_t crtc_id, uint32_t size,
uint16_t *red, uint16_t *green, uint16_t *blue)
{
- int ret;
struct drm_mode_crtc_lut l;
l.crtc_id = crtc_id;
l.green = VOID2U64(green);
l.blue = VOID2U64(blue);
- if ((ret = drmIoctl(fd, DRM_IOCTL_MODE_GETGAMMA, &l)))
- return ret;
-
- return 0;
+ 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)
{
- int ret;
struct drm_mode_crtc_lut l;
l.crtc_id = crtc_id;
l.green = VOID2U64(green);
l.blue = VOID2U64(blue);
- if ((ret = drmIoctl(fd, DRM_IOCTL_MODE_SETGAMMA, &l)))
- return ret;
-
- return 0;
+ return DRM_IOCTL(fd, DRM_IOCTL_MODE_SETGAMMA, &l);
}
int drmHandleEvent(int fd, drmEventContextPtr evctx)
flip.flags = flags;
flip.reserved = 0;
- return drmIoctl(fd, DRM_IOCTL_MODE_PAGE_FLIP, &flip);
+ return DRM_IOCTL(fd, DRM_IOCTL_MODE_PAGE_FLIP, &flip);
}