summaryrefslogtreecommitdiff
path: root/kms++/src/crtc.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'kms++/src/crtc.cpp')
-rw-r--r--kms++/src/crtc.cpp140
1 files changed, 140 insertions, 0 deletions
diff --git a/kms++/src/crtc.cpp b/kms++/src/crtc.cpp
new file mode 100644
index 0000000..bad7d31
--- /dev/null
+++ b/kms++/src/crtc.cpp
@@ -0,0 +1,140 @@
+#include <stdio.h>
+#include <iostream>
+#include <unistd.h>
+#include <fcntl.h>
+#include <cassert>
+
+#include <kms++/kms++.h>
+#include "helpers.h"
+
+using namespace std;
+
+namespace kms
+{
+
+struct CrtcPriv
+{
+ drmModeCrtcPtr drm_crtc;
+};
+
+Crtc::Crtc(Card &card, uint32_t id, uint32_t idx)
+ :DrmPropObject(card, id, DRM_MODE_OBJECT_CRTC, idx)
+{
+ m_priv = new CrtcPriv();
+ m_priv->drm_crtc = drmModeGetCrtc(this->card().fd(), this->id());
+ assert(m_priv->drm_crtc);
+}
+
+Crtc::~Crtc()
+{
+ drmModeFreeCrtc(m_priv->drm_crtc);
+ delete m_priv;
+}
+
+void Crtc::setup()
+{
+ for (Plane* plane : card().get_planes()) {
+ if (plane->supports_crtc(this))
+ m_possible_planes.push_back(plane);
+ }
+}
+
+void Crtc::restore_mode(Connector* conn)
+{
+ auto c = m_priv->drm_crtc;
+
+ uint32_t conns[] = { conn->id() };
+
+ drmModeSetCrtc(card().fd(), id(), c->buffer_id,
+ c->x, c->y,
+ conns, 1, &c->mode);
+}
+
+int Crtc::set_mode(Connector* conn, Framebuffer& fb, const Videomode& mode)
+{
+ uint32_t conns[] = { conn->id() };
+ drmModeModeInfo drmmode = video_mode_to_drm_mode(mode);
+
+ return drmModeSetCrtc(card().fd(), id(), fb.id(),
+ 0, 0,
+ conns, 1, &drmmode);
+}
+
+static inline uint32_t conv(float x)
+{
+ // XXX fix the conversion for fractional part
+ return ((uint32_t)x) << 16;
+}
+
+int Crtc::set_plane(Plane* plane, Framebuffer& fb,
+ int32_t dst_x, int32_t dst_y, uint32_t dst_w, uint32_t dst_h,
+ float src_x, float src_y, float src_w, float src_h)
+{
+ return drmModeSetPlane(card().fd(), plane->id(), id(), fb.id(), 0,
+ dst_x, dst_y, dst_w, dst_h,
+ conv(src_x), conv(src_y), conv(src_w), conv(src_h));
+}
+
+int Crtc::disable_plane(Plane* plane)
+{
+ return drmModeSetPlane(card().fd(), plane->id(), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
+}
+
+Plane* Crtc::get_primary_plane()
+{
+ for (Plane* p : get_possible_planes()) {
+ if (p->plane_type() != PlaneType::Primary)
+ continue;
+
+ return p;
+ }
+
+ throw invalid_argument(string("No primary plane for crtc ") + to_string(id()));
+}
+
+int Crtc::page_flip(Framebuffer& fb, void *data)
+{
+ return drmModePageFlip(card().fd(), id(), fb.id(), DRM_MODE_PAGE_FLIP_EVENT, data);
+}
+
+uint32_t Crtc::buffer_id() const
+{
+ return m_priv->drm_crtc->buffer_id;
+}
+
+uint32_t Crtc::x() const
+{
+ return m_priv->drm_crtc->x;
+}
+
+uint32_t Crtc::y() const
+{
+ return m_priv->drm_crtc->y;
+}
+
+uint32_t Crtc::width() const
+{
+ return m_priv->drm_crtc->width;
+}
+
+uint32_t Crtc::height() const
+{
+ return m_priv->drm_crtc->height;
+}
+
+int Crtc::mode_valid() const
+{
+ return m_priv->drm_crtc->mode_valid;
+}
+
+Videomode Crtc::mode() const
+{
+ return drm_mode_to_video_mode(m_priv->drm_crtc->mode);
+}
+
+int Crtc::gamma_size() const
+{
+ return m_priv->drm_crtc->gamma_size;
+}
+
+}