blob: a57d33fffbeed29ff68507ec04f405b57aba6958 [file] [log] [blame]
#include <cstdio>
#include <algorithm>
#include <iostream>
#include "kms++.h"
#include "opts.h"
using namespace std;
using namespace kms;
namespace kmsprint {
static struct {
bool print_props;
bool print_modes;
bool recurse;
} opts;
string width(int w, string str)
{
str.resize(w, ' ');
return str;
}
void print_mode(const Videomode &m, int ind)
{
printf("%s%s %6d %4d %4d %4d %4d %d %4d %4d %4d %4d %d %2d 0x%04x %2d\n",
width(ind, "").c_str(),
m.name[0] == '\0' ? "" : width(11, m.name).c_str(),
m.clock,
m.hdisplay,
m.hsync_start,
m.hsync_end,
m.htotal,
m.hskew,
m.vdisplay,
m.vsync_start,
m.vsync_end,
m.vtotal,
m.vscan,
m.vrefresh,
m.flags,
m.type);
}
void print_property(uint64_t val, const Property& p, int ind)
{
printf("%s%s (id %d) = %s\n", width(ind, "").c_str(),
p.name().c_str(), p.id(), p.to_str(val).c_str());
}
void print_properties(DrmPropObject& o, int ind)
{
auto pmap = o.get_prop_map();
printf("%sProperties, %u in total:\n", width(ind, "").c_str(),
(unsigned) pmap.size());
for (auto pp : pmap) {
const Property& p = *o.card().get_prop(pp.first);
print_property(pp.second, p, ind + 2);
}
}
void print_plane(Plane& p, int ind)
{
printf("%sPlane Id %d %d,%d -> %dx%d formats:", width(ind, "").c_str(),
p.id(), p.crtc_x(), p.crtc_y(), p.x(), p.y());
for (auto f : p.get_formats())
printf(" %s", PixelFormatToFourCC(f).c_str());
printf("\n");
if (opts.print_props)
print_properties(p, ind+2);
}
void print_crtc(Crtc& cc, int ind)
{
printf("%sCRTC Id %d BufferId %d %dx%d at %dx%d gamma_size %d\n",
width(ind, "").c_str(), cc.id(), cc.buffer_id(), cc.width(),
cc.height(), cc.x(), cc.y(), cc.gamma_size());
printf("%s Mode ", width(ind, "").c_str());
print_mode(cc.mode(), 0);
if (opts.print_props)
print_properties(cc, ind+2);
if (opts.recurse)
for (auto p : cc.get_possible_planes())
print_plane(*p, ind + 2);
}
void print_encoder(Encoder& e, int ind)
{
printf("%sEncoder Id %d type %s\n", width(ind, "").c_str(),
e.id(), e.get_encoder_type().c_str());
if (opts.print_props)
print_properties(e, ind+2);
if (opts.recurse)
for (auto cc : e.get_possible_crtcs())
print_crtc(*cc, ind + 2);
}
void print_connector(Connector& c, int ind)
{
printf("%sConnector %s Id %d %sconnected", width(ind, "").c_str(),
c.fullname().c_str(), c.id(), c.connected() ? "" : "dis");
if (c.subpixel() != 0)
printf(" Subpixel: %s", c.subpixel_str().c_str());
printf("\n");
if (opts.print_props)
print_properties(c, ind+2);
if (opts.recurse)
for (auto enc : c.get_encoders())
print_encoder(*enc, ind + 2);
if (opts.print_modes) {
auto modes = c.get_modes();
printf("%sModes, %u in total:\n", width(ind + 2, "").c_str(),
(unsigned) modes.size());
for (auto mode : modes)
print_mode(mode, ind + 3);
}
}
}
using namespace kmsprint;
static const char* usage_str =
"Usage: kmsprint [OPTIONS]\n\n"
"Options:\n"
" -m, --modes Print modes\n"
" -p, --props Print properties\n"
" -r, --recurse Recursively print all related objects\n"
" --id=<ID> Print object <ID>\n"
;
static void usage()
{
puts(usage_str);
}
int main(int argc, char **argv)
{
string dev_path;
unsigned id = 0;
OptionSet optionset = {
Option("|device=",
[&](string s)
{
dev_path = s;
}),
Option("|id=",
[&](string s)
{
id = stoul(s);
}),
Option("p", [&](string s)
{
opts.print_props = true;
}),
Option("m", [&](string s)
{
opts.print_modes = true;
}),
Option("r", [&](string s)
{
opts.recurse = true;
}),
Option("h|help", [&]()
{
usage();
exit(-1);
}),
};
optionset.parse(argc, argv);
if (optionset.params().size() > 0) {
usage();
exit(-1);
}
Card card;
/* No options impliles recursion */
if (id == 0) {
opts.recurse = true;
for (auto conn : card.get_connectors())
print_connector(*conn, 0);
return 0;
} else {
auto ob = card.get_object(id);
if (!ob) {
cerr << "kmsprint" << ": Object id " <<
id << " not found." << endl;
return -1;
}
if (auto co = dynamic_cast<Connector*>(ob))
print_connector(*co, 0);
else if (auto en = dynamic_cast<Encoder*>(ob))
print_encoder(*en, 0);
else if (auto cr = dynamic_cast<Crtc*>(ob))
print_crtc(*cr, 0);
else if (auto pl = dynamic_cast<Plane*>(ob))
print_plane(*pl, 0);
else {
cerr << "kmsprint" << ": Unkown DRM Object type" <<
endl;
return -1;
}
return 0;
}
}