/* SPDX-License-Identifier: MIT */ #include "drm++/drm.hpp" #include "drm++/helper/ioctl.hpp" #include "drm++/helper/types.hpp" #include #include #include #include using namespace drm; Device::Device(int fd) : m_fd(fd) { if (this->m_fd < 0) { throw std::invalid_argument("invalid file descriptor"); } drm_version args{ .version_major = 0, }; ioctl::perform(this->m_fd, DRM_IOCTL_VERSION, args); this->m_version = { args.version_major, args.version_minor, args.version_patchlevel }; this->m_name.resize(args.name_len); this->m_date.resize(args.date_len); this->m_description.resize(args.desc_len); args = { .name_len = this->m_name.size(), .name = this->m_name.data(), .date_len = this->m_date.size(), .date = this->m_date.data(), .desc_len = this->m_description.size(), .desc = this->m_description.data() }; ioctl::perform(this->m_fd, DRM_IOCTL_VERSION, args); } void Device::setClientName(const std::string& name) const { drm_set_client_name name_args{ .name_len = name.size(), .name = reinterpret_cast(name.data()) }; ioctl::perform(this->m_fd, DRM_IOCTL_SET_CLIENT_NAME, name_args); } void Device::destruct() noexcept { if (this->m_fd < 0) { return; } ::close(this->m_fd); this->m_fd = -1; } /* Authentication */ void Device::acquireMaster() const { ioctl::perform(this->m_fd, DRM_IOCTL_SET_MASTER); } void Device::releaseMaster() const { ioctl::perform(this->m_fd, DRM_IOCTL_DROP_MASTER); } u32 Device::magic() const { drm_auth auth_args{ .magic = 0 }; ioctl::perform(this->m_fd, DRM_IOCTL_GET_MAGIC, auth_args); return auth_args.magic; } void Device::authenticate(u32 magic) const { drm_auth args{ .magic = magic }; ioctl::perform(this->m_fd, DRM_IOCTL_AUTH_MAGIC, args); } /* Device information */ std::string Device::unique() const { drm_set_version version_args{ .drm_di_major = 1, .drm_di_minor = 4, // See kernel drm_ioctl.c for why this is here .drm_dd_major = -1, .drm_dd_minor = -1 }; ioctl::perform(this->m_fd, DRM_IOCTL_SET_VERSION, version_args); drm_unique unique_args{ .unique_len = 0, }; ioctl::perform(this->m_fd, DRM_IOCTL_GET_UNIQUE, unique_args); std::string unique(unique_args.unique_len, '\0'); unique_args = { .unique_len = unique.size(), .unique = unique.data() }; ioctl::perform(this->m_fd, DRM_IOCTL_GET_UNIQUE, unique_args); return unique; }