#include #include #include #include #include #ifndef DRM_CLIENT_CAP_ATOMIC #define DRM_MODE_ATOMIC_TEST_ONLY 0 #define DRM_MODE_ATOMIC_NONBLOCK 0 struct _drmModeAtomicReq; typedef struct _drmModeAtomicReq* drmModeAtomicReqPtr; static inline drmModeAtomicReqPtr drmModeAtomicAlloc() { return 0; } static inline void drmModeAtomicFree(drmModeAtomicReqPtr) { } static inline int drmModeAtomicAddProperty(drmModeAtomicReqPtr, uint32_t, uint32_t, uint64_t) { return 0; } static inline int drmModeAtomicCommit(int, drmModeAtomicReqPtr, int, void*) { return 0; } #endif // DRM_CLIENT_CAP_ATOMIC using namespace std; namespace kms { AtomicReq::AtomicReq(Card& card) : m_card(card) { assert(card.has_atomic()); m_req = drmModeAtomicAlloc(); } AtomicReq::~AtomicReq() { drmModeAtomicFree(m_req); } void AtomicReq::add(uint32_t ob_id, uint32_t prop_id, uint64_t value) { int r = drmModeAtomicAddProperty(m_req, ob_id, prop_id, value); if (r <= 0) throw std::invalid_argument("foo"); } void AtomicReq::add(DrmPropObject* ob, Property* prop, uint64_t value) { add(ob->id(), prop->id(), value); } void AtomicReq::add(kms::DrmPropObject* ob, const string& prop, uint64_t value) { Property* p = ob->get_prop(prop); if (!p) throw runtime_error("Property not found"); add(ob, p, value); } void AtomicReq::add(kms::DrmPropObject* ob, const map& values) { for (const auto& kvp : values) add(ob, kvp.first, kvp.second); } void AtomicReq::add_display(Connector* conn, Crtc* crtc, Blob* videomode, Plane* primary, Framebuffer* fb) { add(conn, { { "CRTC_ID", crtc->id() }, }); add(crtc, { { "ACTIVE", 1 }, { "MODE_ID", videomode->id() }, }); add(primary, { { "FB_ID", fb->id() }, { "CRTC_ID", crtc->id() }, { "SRC_X", 0 << 16 }, { "SRC_Y", 0 << 16 }, { "SRC_W", fb->width() << 16 }, { "SRC_H", fb->height() << 16 }, { "CRTC_X", 0 }, { "CRTC_Y", 0 }, { "CRTC_W", fb->width() }, { "CRTC_H", fb->height() }, }); } int AtomicReq::test(bool allow_modeset) { uint32_t flags = DRM_MODE_ATOMIC_TEST_ONLY; if (allow_modeset) flags |= DRM_MODE_ATOMIC_ALLOW_MODESET; return drmModeAtomicCommit(m_card.fd(), m_req, flags, 0); } int AtomicReq::commit(void* data, bool allow_modeset) { uint32_t flags = DRM_MODE_PAGE_FLIP_EVENT | DRM_MODE_ATOMIC_NONBLOCK; if (allow_modeset) flags |= DRM_MODE_ATOMIC_ALLOW_MODESET; return drmModeAtomicCommit(m_card.fd(), m_req, flags, data); } int AtomicReq::commit_sync(bool allow_modeset) { uint32_t flags = 0; if (allow_modeset) flags |= DRM_MODE_ATOMIC_ALLOW_MODESET; return drmModeAtomicCommit(m_card.fd(), m_req, flags, 0); } } // namespace kms