static void flush(struct etna_cmd_stream *stream) { struct etna_cmd_stream_priv *priv = etna_cmd_stream_priv(stream); int ret, id = priv->pipe->id; struct etna_gpu *gpu = priv->pipe->gpu; struct drm_etnaviv_gem_submit req; req.pipe = gpu->core; req.exec_state = id; req.bos = VOID2U64(priv->submit.bos); req.nr_bos = priv->submit.nr_bos; req.relocs = VOID2U64(priv->submit.relocs); req.nr_relocs = priv->submit.nr_relocs; req.stream = VOID2U64(stream->buffer); req.stream_size = stream->offset * 4; /* in bytes */ ret = drmCommandWriteRead(gpu->dev->fd, DRM_ETNAVIV_GEM_SUBMIT, &req, sizeof(req)); if (ret) { ERROR_MSG("submit failed: %d (%s)", ret, strerror(errno)); } else { priv->last_timestamp = req.fence; } for (uint32_t i = 0; i < priv->nr_bos; i++) { struct etna_bo *bo = priv->bos[i]; bo->current_stream = NULL; etna_bo_del(bo); } }
drmModeObjectPropertiesPtr drmModeObjectGetProperties(int fd, uint32_t object_id, uint32_t object_type) { struct drm_mode_obj_get_properties properties; drmModeObjectPropertiesPtr ret = NULL; uint32_t count; retry: memset(&properties, 0, sizeof(struct drm_mode_obj_get_properties)); properties.obj_id = object_id; properties.obj_type = object_type; if (drmIoctl(fd, DRM_IOCTL_MODE_OBJ_GETPROPERTIES, &properties)) return 0; count = properties.count_props; if (count) { properties.props_ptr = VOID2U64(drmMalloc(count * sizeof(uint32_t))); if (!properties.props_ptr) goto err_allocs; properties.prop_values_ptr = VOID2U64(drmMalloc(count * sizeof(uint64_t))); if (!properties.prop_values_ptr) goto err_allocs; } if (drmIoctl(fd, DRM_IOCTL_MODE_OBJ_GETPROPERTIES, &properties)) goto err_allocs; if (count < properties.count_props) { drmFree(U642VOID(properties.props_ptr)); drmFree(U642VOID(properties.prop_values_ptr)); goto retry; } count = properties.count_props; ret = drmMalloc(sizeof(*ret)); if (!ret) goto err_allocs; ret->count_props = count; ret->props = drmAllocCpy(U642VOID(properties.props_ptr), count, sizeof(uint32_t)); ret->prop_values = drmAllocCpy(U642VOID(properties.prop_values_ptr), count, sizeof(uint64_t)); if (ret->count_props && (!ret->props || !ret->prop_values)) { drmFree(ret->props); drmFree(ret->prop_values); drmFree(ret); ret = NULL; } err_allocs: drmFree(U642VOID(properties.props_ptr)); drmFree(U642VOID(properties.prop_values_ptr)); return ret; }
drmModePropertyPtr drmModeGetProperty(int fd, uint32_t property_id) { struct drm_mode_get_property prop; drmModePropertyPtr r; VG_CLEAR(prop); prop.prop_id = property_id; prop.count_enum_blobs = 0; prop.count_values = 0; prop.flags = 0; prop.enum_blob_ptr = 0; prop.values_ptr = 0; if (drmIoctl(fd, DRM_IOCTL_MODE_GETPROPERTY, &prop)) return 0; if (prop.count_values) prop.values_ptr = VOID2U64(drmMalloc(prop.count_values * sizeof(uint64_t))); if (prop.count_enum_blobs && (prop.flags & (DRM_MODE_PROP_ENUM | DRM_MODE_PROP_BITMASK))) prop.enum_blob_ptr = VOID2U64(drmMalloc(prop.count_enum_blobs * sizeof(struct drm_mode_property_enum))); if (prop.count_enum_blobs && (prop.flags & DRM_MODE_PROP_BLOB)) { prop.values_ptr = VOID2U64(drmMalloc(prop.count_enum_blobs * sizeof(uint32_t))); prop.enum_blob_ptr = VOID2U64(drmMalloc(prop.count_enum_blobs * sizeof(uint32_t))); } if (drmIoctl(fd, DRM_IOCTL_MODE_GETPROPERTY, &prop)) { r = NULL; goto err_allocs; } if (!(r = drmMalloc(sizeof(*r)))) return NULL; r->prop_id = prop.prop_id; r->count_values = prop.count_values; r->flags = prop.flags; if (prop.count_values) r->values = drmAllocCpy(U642VOID(prop.values_ptr), prop.count_values, sizeof(uint64_t)); if (prop.flags & (DRM_MODE_PROP_ENUM | DRM_MODE_PROP_BITMASK)) { r->count_enums = prop.count_enum_blobs; r->enums = drmAllocCpy(U642VOID(prop.enum_blob_ptr), prop.count_enum_blobs, sizeof(struct drm_mode_property_enum)); } else if (prop.flags & DRM_MODE_PROP_BLOB) { r->values = drmAllocCpy(U642VOID(prop.values_ptr), prop.count_enum_blobs, sizeof(uint32_t)); r->blob_ids = drmAllocCpy(U642VOID(prop.enum_blob_ptr), prop.count_enum_blobs, sizeof(uint32_t)); r->count_blobs = prop.count_enum_blobs; } strncpy(r->name, prop.name, DRM_PROP_NAME_LEN); r->name[DRM_PROP_NAME_LEN-1] = 0; err_allocs: drmFree(U642VOID(prop.values_ptr)); drmFree(U642VOID(prop.enum_blob_ptr)); return r; }
static void flush(struct etna_cmd_stream *stream, int in_fence_fd, int *out_fence_fd) { struct etna_cmd_stream_priv *priv = etna_cmd_stream_priv(stream); int ret, id = priv->pipe->id; struct etna_gpu *gpu = priv->pipe->gpu; struct drm_etnaviv_gem_submit req = { .pipe = gpu->core, .exec_state = id, .bos = VOID2U64(priv->submit.bos), .nr_bos = priv->submit.nr_bos, .relocs = VOID2U64(priv->submit.relocs), .nr_relocs = priv->submit.nr_relocs, .stream = VOID2U64(stream->buffer), .stream_size = stream->offset * 4, /* in bytes */ }; if (in_fence_fd != -1) { req.flags |= ETNA_SUBMIT_FENCE_FD_IN | ETNA_SUBMIT_NO_IMPLICIT; req.fence_fd = in_fence_fd; } if (out_fence_fd) req.flags |= ETNA_SUBMIT_FENCE_FD_OUT; /* * Pass the complete submit structure only if flags are set. Otherwise, * only pass the fields up to, but not including the flags field for * backwards compatiblity with older kernels. */ ret = drmCommandWriteRead(gpu->dev->fd, DRM_ETNAVIV_GEM_SUBMIT, &req, req.flags ? sizeof(req) : offsetof(struct drm_etnaviv_gem_submit, flags)); if (ret) ERROR_MSG("submit failed: %d (%s)", ret, strerror(errno)); else priv->last_timestamp = req.fence; for (uint32_t i = 0; i < priv->nr_bos; i++) { struct etna_bo *bo = priv->bos[i]; bo->current_stream = NULL; etna_bo_del(bo); } if (out_fence_fd) *out_fence_fd = req.fence_fd; } void etna_cmd_stream_flush(struct etna_cmd_stream *stream) { flush(stream, -1, NULL); reset_buffer(stream); }
drmModeResPtr drmModeGetResources(int fd) { struct drm_mode_card_res res; drmModeResPtr r = 0; memset(&res, 0, sizeof(struct drm_mode_card_res)); if (drmIoctl(fd, DRM_IOCTL_MODE_GETRESOURCES, &res)) return 0; if (res.count_fbs) res.fb_id_ptr = VOID2U64(drmMalloc(res.count_fbs*sizeof(uint32_t))); if (res.count_crtcs) res.crtc_id_ptr = VOID2U64(drmMalloc(res.count_crtcs*sizeof(uint32_t))); if (res.count_connectors) res.connector_id_ptr = VOID2U64(drmMalloc(res.count_connectors*sizeof(uint32_t))); if (res.count_encoders) res.encoder_id_ptr = VOID2U64(drmMalloc(res.count_encoders*sizeof(uint32_t))); if (drmIoctl(fd, DRM_IOCTL_MODE_GETRESOURCES, &res)) { r = NULL; goto err_allocs; } /* * return */ if (!(r = drmMalloc(sizeof(*r)))) return 0; r->min_width = res.min_width; r->max_width = res.max_width; r->min_height = res.min_height; r->max_height = res.max_height; r->count_fbs = res.count_fbs; r->count_crtcs = res.count_crtcs; r->count_connectors = res.count_connectors; r->count_encoders = res.count_encoders; /* TODO we realy should test if these allocs fails. */ r->fbs = drmAllocCpy(U642VOID(res.fb_id_ptr), res.count_fbs, sizeof(uint32_t)); 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)); err_allocs: drmFree(U642VOID(res.fb_id_ptr)); drmFree(U642VOID(res.crtc_id_ptr)); drmFree(U642VOID(res.connector_id_ptr)); drmFree(U642VOID(res.encoder_id_ptr)); return r; }
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; l.crtc_id = crtc_id; l.gamma_size = size; l.red = VOID2U64(red); l.green = VOID2U64(green); l.blue = VOID2U64(blue); return DRM_IOCTL(fd, DRM_IOCTL_MODE_SETGAMMA, &l); }
drmModePropertyBlobPtr drmModeGetPropertyBlob(int fd, uint32_t blob_id) { struct drm_mode_get_blob blob; drmModePropertyBlobPtr r; blob.length = 0; blob.data = 0; blob.blob_id = blob_id; if (drmIoctl(fd, DRM_IOCTL_MODE_GETPROPBLOB, &blob)) return NULL; if (blob.length) blob.data = VOID2U64(drmMalloc(blob.length)); if (drmIoctl(fd, DRM_IOCTL_MODE_GETPROPBLOB, &blob)) { r = NULL; goto err_allocs; } if (!(r = drmMalloc(sizeof(*r)))) goto err_allocs; r->id = blob.blob_id; r->length = blob.length; r->data = drmAllocCpy(U642VOID(blob.data), 1, blob.length); err_allocs: drmFree(U642VOID(blob.data)); return r; }
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.gamma_size = size; l.red = VOID2U64(red); l.green = VOID2U64(green); l.blue = VOID2U64(blue); if ((ret = drmIoctl(fd, DRM_IOCTL_MODE_GETGAMMA, &l))) return ret; return 0; }
static int drm_atomic_commit(uint32_t fb_id, uint32_t flags) { drmModeAtomicReq *req; uint32_t plane_id = drm.plane->plane->plane_id; uint32_t blob_id; int ret; req = drmModeAtomicAlloc(); if (flags & DRM_MODE_ATOMIC_ALLOW_MODESET) { if (add_connector_property(req, drm.connector_id, "CRTC_ID", drm.crtc_id) < 0) return -1; if (drmModeCreatePropertyBlob(drm.fd, drm.mode, sizeof(*drm.mode), &blob_id) != 0) return -1; if (add_crtc_property(req, drm.crtc_id, "MODE_ID", blob_id) < 0) return -1; if (add_crtc_property(req, drm.crtc_id, "ACTIVE", 1) < 0) return -1; } add_plane_property(req, plane_id, "FB_ID", fb_id); add_plane_property(req, plane_id, "CRTC_ID", drm.crtc_id); add_plane_property(req, plane_id, "SRC_X", 0); add_plane_property(req, plane_id, "SRC_Y", 0); add_plane_property(req, plane_id, "SRC_W", drm.mode->hdisplay << 16); add_plane_property(req, plane_id, "SRC_H", drm.mode->vdisplay << 16); add_plane_property(req, plane_id, "CRTC_X", 0); add_plane_property(req, plane_id, "CRTC_Y", 0); add_plane_property(req, plane_id, "CRTC_W", drm.mode->hdisplay); add_plane_property(req, plane_id, "CRTC_H", drm.mode->vdisplay); if (drm.kms_in_fence_fd != -1) { add_crtc_property(req, drm.crtc_id, "OUT_FENCE_PTR", VOID2U64(&drm.kms_out_fence_fd)); add_plane_property(req, plane_id, "IN_FENCE_FD", drm.kms_in_fence_fd); } ret = drmModeAtomicCommit(drm.fd, req, flags, NULL); if (ret) goto out; if (drm.kms_in_fence_fd != -1) { close(drm.kms_in_fence_fd); drm.kms_in_fence_fd = -1; } out: drmModeAtomicFree(req); return ret; }
int drmModeDirtyFB(int fd, uint32_t bufferId, drmModeClipPtr clips, uint32_t num_clips) { struct drm_mode_fb_dirty_cmd dirty = { 0 }; dirty.fb_id = bufferId; dirty.clips_ptr = VOID2U64(clips); dirty.num_clips = num_clips; return DRM_IOCTL(fd, DRM_IOCTL_MODE_DIRTYFB, &dirty); }
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; flip.fb_id = fb_id; flip.crtc_id = crtc_id; flip.user_data = VOID2U64(user_data); flip.flags = flags; flip.reserved = 0; return DRM_IOCTL(fd, DRM_IOCTL_MODE_PAGE_FLIP, &flip); }
drmModePlanePtr drmModeGetPlane(int fd, uint32_t plane_id) { struct drm_mode_get_plane ovr, counts; drmModePlanePtr r = 0; retry: memset(&ovr, 0, sizeof(struct drm_mode_get_plane)); ovr.plane_id = plane_id; if (drmIoctl(fd, DRM_IOCTL_MODE_GETPLANE, &ovr)) return 0; counts = ovr; if (ovr.count_format_types) { ovr.format_type_ptr = VOID2U64(drmMalloc(ovr.count_format_types * sizeof(uint32_t))); if (!ovr.format_type_ptr) goto err_allocs; } if (drmIoctl(fd, DRM_IOCTL_MODE_GETPLANE, &ovr)) goto err_allocs; if (counts.count_format_types < ovr.count_format_types) { drmFree(U642VOID(ovr.format_type_ptr)); goto retry; } if (!(r = drmMalloc(sizeof(*r)))) goto err_allocs; r->count_formats = ovr.count_format_types; r->plane_id = ovr.plane_id; r->crtc_id = ovr.crtc_id; r->fb_id = ovr.fb_id; r->possible_crtcs = ovr.possible_crtcs; r->gamma_size = ovr.gamma_size; r->formats = drmAllocCpy(U642VOID(ovr.format_type_ptr), ovr.count_format_types, sizeof(uint32_t)); if (ovr.count_format_types && !r->formats) { drmFree(r->formats); drmFree(r); r = 0; } err_allocs: drmFree(U642VOID(ovr.format_type_ptr)); return r; }
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); }
drmModePlaneResPtr drmModeGetPlaneResources(int fd) { struct drm_mode_get_plane_res res, counts; drmModePlaneResPtr r = 0; retry: memset(&res, 0, sizeof(struct drm_mode_get_plane_res)); if (drmIoctl(fd, DRM_IOCTL_MODE_GETPLANERESOURCES, &res)) return 0; counts = res; if (res.count_planes) { res.plane_id_ptr = VOID2U64(drmMalloc(res.count_planes * sizeof(uint32_t))); if (!res.plane_id_ptr) goto err_allocs; } if (drmIoctl(fd, DRM_IOCTL_MODE_GETPLANERESOURCES, &res)) goto err_allocs; if (counts.count_planes < res.count_planes) { drmFree(U642VOID(res.plane_id_ptr)); goto retry; } if (!(r = drmMalloc(sizeof(*r)))) goto err_allocs; r->count_planes = res.count_planes; r->planes = drmAllocCpy(U642VOID(res.plane_id_ptr), res.count_planes, sizeof(uint32_t)); if (res.count_planes && !r->planes) { drmFree(r->planes); drmFree(r); r = 0; } err_allocs: drmFree(U642VOID(res.plane_id_ptr)); return r; }
int drmModeSetCrtc(int fd, uint32_t crtcId, uint32_t bufferId, uint32_t x, uint32_t y, uint32_t *connectors, int count, drmModeModeInfoPtr mode) { struct drm_mode_crtc crtc; crtc.x = x; crtc.y = y; crtc.crtc_id = crtcId; crtc.fb_id = bufferId; crtc.set_connectors_ptr = VOID2U64(connectors); crtc.count_connectors = count; if (mode) { memcpy(&crtc.mode, mode, sizeof(struct drm_mode_modeinfo)); crtc.mode_valid = 1; } else crtc.mode_valid = 0; return DRM_IOCTL(fd, DRM_IOCTL_MODE_SETCRTC, &crtc); }
drmModeConnectorPtr drmModeGetConnector(int fd, uint32_t connector_id) { 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; 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) { conn.modes_ptr = VOID2U64(drmMalloc(conn.count_modes*sizeof(struct drm_mode_modeinfo))); if (!conn.modes_ptr) goto err_allocs; } 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; } r->connector_id = conn.connector_id; r->encoder_id = conn.encoder_id; r->connection = conn.connection; r->mmWidth = conn.mm_width; r->mmHeight = conn.mm_height; /* convert subpixel from kernel to userspace */ r->subpixel = conn.subpixel + 1; r->count_modes = conn.count_modes; 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->modes = drmAllocCpy(U642VOID(conn.modes_ptr), conn.count_modes, sizeof(struct drm_mode_modeinfo)); r->count_encoders = conn.count_encoders; r->encoders = drmAllocCpy(U642VOID(conn.encoders_ptr), conn.count_encoders, sizeof(uint32_t)); r->connector_type = conn.connector_type; r->connector_type_id = conn.connector_type_id; 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)); drmFree(U642VOID(conn.props_ptr)); drmFree(U642VOID(conn.modes_ptr)); drmFree(U642VOID(conn.encoders_ptr)); return r; }
drmModeResPtr drmModeGetResources(int fd) { struct drm_mode_card_res res, counts; drmModeResPtr r = 0; retry: memset(&res, 0, sizeof(struct drm_mode_card_res)); if (drmIoctl(fd, DRM_IOCTL_MODE_GETRESOURCES, &res)) return 0; counts = res; if (res.count_fbs) { res.fb_id_ptr = VOID2U64(drmMalloc(res.count_fbs*sizeof(uint32_t))); if (!res.fb_id_ptr) goto err_allocs; } if (res.count_crtcs) { res.crtc_id_ptr = VOID2U64(drmMalloc(res.count_crtcs*sizeof(uint32_t))); if (!res.crtc_id_ptr) goto err_allocs; } if (res.count_connectors) { res.connector_id_ptr = VOID2U64(drmMalloc(res.count_connectors*sizeof(uint32_t))); if (!res.connector_id_ptr) goto err_allocs; } if (res.count_encoders) { res.encoder_id_ptr = VOID2U64(drmMalloc(res.count_encoders*sizeof(uint32_t))); if (!res.encoder_id_ptr) goto err_allocs; } if (drmIoctl(fd, DRM_IOCTL_MODE_GETRESOURCES, &res)) 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_fbs < res.count_fbs || counts.count_crtcs < res.count_crtcs || counts.count_connectors < res.count_connectors || counts.count_encoders < res.count_encoders) { drmFree(U642VOID(res.fb_id_ptr)); drmFree(U642VOID(res.crtc_id_ptr)); drmFree(U642VOID(res.connector_id_ptr)); drmFree(U642VOID(res.encoder_id_ptr)); goto retry; } /* * return */ if (!(r = drmMalloc(sizeof(*r)))) goto err_allocs; r->min_width = res.min_width; r->max_width = res.max_width; r->min_height = res.min_height; r->max_height = res.max_height; r->count_fbs = res.count_fbs; r->count_crtcs = res.count_crtcs; r->count_connectors = res.count_connectors; r->count_encoders = res.count_encoders; r->fbs = drmAllocCpy(U642VOID(res.fb_id_ptr), res.count_fbs, sizeof(uint32_t)); 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 ((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); drmFree(r->encoders); drmFree(r); r = 0; } err_allocs: drmFree(U642VOID(res.fb_id_ptr)); drmFree(U642VOID(res.crtc_id_ptr)); drmFree(U642VOID(res.connector_id_ptr)); drmFree(U642VOID(res.encoder_id_ptr)); return r; }
drmModeConnectorPtr drmModeGetConnector(int fd, uint32_t connector_id) { struct drm_mode_get_connector conn; drmModeConnectorPtr r = NULL; 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; if (conn.count_props) { conn.props_ptr = VOID2U64(drmMalloc(conn.count_props*sizeof(uint32_t))); conn.prop_values_ptr = VOID2U64(drmMalloc(conn.count_props*sizeof(uint64_t))); } if (conn.count_modes) conn.modes_ptr = VOID2U64(drmMalloc(conn.count_modes*sizeof(struct drm_mode_modeinfo))); if (conn.count_encoders) conn.encoders_ptr = VOID2U64(drmMalloc(conn.count_encoders*sizeof(uint32_t))); if (drmIoctl(fd, DRM_IOCTL_MODE_GETCONNECTOR, &conn)) goto err_allocs; if(!(r = drmMalloc(sizeof(*r)))) { goto err_allocs; } r->connector_id = conn.connector_id; r->encoder_id = conn.encoder_id; r->connection = conn.connection; r->mmWidth = conn.mm_width; r->mmHeight = conn.mm_height; /* 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->modes = drmAllocCpy(U642VOID(conn.modes_ptr), conn.count_modes, sizeof(struct drm_mode_modeinfo)); r->count_encoders = conn.count_encoders; r->encoders = drmAllocCpy(U642VOID(conn.encoders_ptr), conn.count_encoders, sizeof(uint32_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; err_allocs: drmFree(U642VOID(conn.prop_values_ptr)); drmFree(U642VOID(conn.props_ptr)); drmFree(U642VOID(conn.modes_ptr)); drmFree(U642VOID(conn.encoders_ptr)); return r; }