aboutsummaryrefslogtreecommitdiff
path: root/kms++/src/card.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'kms++/src/card.cpp')
-rw-r--r--kms++/src/card.cpp90
1 files changed, 69 insertions, 21 deletions
diff --git a/kms++/src/card.cpp b/kms++/src/card.cpp
index 5b3d69e..935969d 100644
--- a/kms++/src/card.cpp
+++ b/kms++/src/card.cpp
@@ -9,6 +9,10 @@
#include <algorithm>
#include <glob.h>
+#include <sys/stat.h>
+#include <sys/sysmacros.h>
+#include <sys/types.h>
+
#include <xf86drm.h>
#include <xf86drmMode.h>
@@ -18,20 +22,19 @@ using namespace std;
namespace kms
{
-
static vector<string> glob(const string& pattern)
{
glob_t glob_result;
memset(&glob_result, 0, sizeof(glob_result));
int r = glob(pattern.c_str(), 0, NULL, &glob_result);
- if(r != 0) {
+ if (r != 0) {
globfree(&glob_result);
throw runtime_error("failed to find DRM cards");
}
vector<string> filenames;
- for(size_t i = 0; i < glob_result.gl_pathc; ++i)
+ for (size_t i = 0; i < glob_result.gl_pathc; ++i)
filenames.push_back(string(glob_result.gl_pathv[i]));
globfree(&glob_result);
@@ -104,6 +107,16 @@ static int open_device_by_driver(string name, uint32_t idx)
throw invalid_argument("Failed to find a DRM device " + name + ":" + to_string(idx));
}
+std::unique_ptr<Card> Card::open_named_card(const std::string& name)
+{
+ int fd = drmOpen(name.c_str(), 0);
+
+ if (fd < 0)
+ throw invalid_argument(string(strerror(errno)) + " opening card \"" + name + "\"");
+
+ return std::unique_ptr<Card>(new Card(fd, true));
+}
+
Card::Card(const std::string& dev_path)
{
const char* drv_p = getenv("KMSXX_DRIVER");
@@ -148,6 +161,20 @@ Card::Card(const std::string& driver, uint32_t idx)
setup();
}
+Card::Card(int fd, bool take_ownership)
+{
+ if (take_ownership) {
+ m_fd = fd;
+ } else {
+ m_fd = fcntl(fd, F_DUPFD_CLOEXEC, 0);
+
+ if (m_fd < 0)
+ throw invalid_argument(string(strerror(errno)) + " duplicating fd");
+ }
+
+ setup();
+}
+
void Card::setup()
{
drmVersionPtr ver = drmGetVersion(m_fd);
@@ -159,8 +186,15 @@ void Card::setup()
m_version.desc = string(ver->desc, ver->desc_len);
drmFreeVersion(ver);
+ struct stat stats;
int r;
+ r = fstat(m_fd, &stats);
+ if (r < 0)
+ throw invalid_argument("Can't stat device (" + string(strerror(errno)) + ")");
+
+ m_minor = minor(stats.st_dev);
+
r = drmSetMaster(m_fd);
m_is_master = r == 0;
@@ -280,7 +314,7 @@ void Card::restore_modes()
Connector* Card::get_first_connected_connector() const
{
- for(auto c : m_connectors) {
+ for (auto c : m_connectors) {
if (c->connected())
return c;
}
@@ -299,23 +333,37 @@ DrmObject* Card::get_object(uint32_t id) const
std::vector<kms::DrmObject*> Card::get_objects() const
{
vector<DrmObject*> v;
- for(auto pair : m_obmap)
+ for (auto pair : m_obmap)
v.push_back(pair.second);
return v;
}
-Connector* Card::get_connector(uint32_t id) const { return dynamic_cast<Connector*>(get_object(id)); }
-Crtc* Card::get_crtc(uint32_t id) const { return dynamic_cast<Crtc*>(get_object(id)); }
-Encoder* Card::get_encoder(uint32_t id) const { return dynamic_cast<Encoder*>(get_object(id)); }
-Property* Card::get_prop(uint32_t id) const { return dynamic_cast<Property*>(get_object(id)); }
-Plane* Card::get_plane(uint32_t id) const { return dynamic_cast<Plane*>(get_object(id)); }
+Connector* Card::get_connector(uint32_t id) const
+{
+ return dynamic_cast<Connector*>(get_object(id));
+}
+Crtc* Card::get_crtc(uint32_t id) const
+{
+ return dynamic_cast<Crtc*>(get_object(id));
+}
+Encoder* Card::get_encoder(uint32_t id) const
+{
+ return dynamic_cast<Encoder*>(get_object(id));
+}
+Property* Card::get_prop(uint32_t id) const
+{
+ return dynamic_cast<Property*>(get_object(id));
+}
+Plane* Card::get_plane(uint32_t id) const
+{
+ return dynamic_cast<Plane*>(get_object(id));
+}
std::vector<kms::Pipeline> Card::get_connected_pipelines()
{
vector<Pipeline> outputs;
- for (auto conn : get_connectors())
- {
+ for (auto conn : get_connectors()) {
if (conn->connected() == false)
continue;
@@ -335,7 +383,7 @@ std::vector<kms::Pipeline> Card::get_connected_pipelines()
to_string(conn->idx()) +
" has no possible crtcs");
- outputs.push_back(Pipeline { crtc, conn });
+ outputs.push_back(Pipeline{ crtc, conn });
}
return outputs;
@@ -343,7 +391,7 @@ std::vector<kms::Pipeline> Card::get_connected_pipelines()
static void page_flip_handler(int fd, unsigned int frame,
unsigned int sec, unsigned int usec,
- void *data)
+ void* data)
{
auto handler = (PageFlipHandlerBase*)data;
double time = sec + usec / 1000000.0;
@@ -352,7 +400,7 @@ static void page_flip_handler(int fd, unsigned int frame,
void Card::call_page_flip_handlers()
{
- drmEventContext ev { };
+ drmEventContext ev{};
ev.version = DRM_EVENT_CONTEXT_VERSION;
ev.page_flip_handler = page_flip_handler;
@@ -365,18 +413,18 @@ int Card::disable_all()
for (Crtc* c : m_crtcs) {
req.add(c, {
- { "ACTIVE", 0 },
- });
+ { "ACTIVE", 0 },
+ });
}
for (Plane* p : m_planes) {
req.add(p, {
- { "FB_ID", 0 },
- { "CRTC_ID", 0 },
- });
+ { "FB_ID", 0 },
+ { "CRTC_ID", 0 },
+ });
}
return req.commit_sync(true);
}
-}
+} // namespace kms