summaryrefslogtreecommitdiff
path: root/linux-core
AgeCommit message (Expand)Author
2001-08-11new multihead code was missing Voodoo3 2000 and Voodoo4 support.Alan Hourihane
2001-08-10Commit Keith Owens kernel Makefile changes, merge and commit alpha patchJeff Hartmann
2001-08-08Update to the code I sent Linus and Alan this morning. Added some missingJeff Hartmann
2001-08-07Avoid compiler warning about r_list being used uninitialized.Jeff Hartmann
2001-08-07Lots of DRM fixes: added new pieces of template code so the ffb driver canJeff Hartmann
2001-07-30Merge the multihead-1-0-0 branch into the trunk, with the exception of theDavid Dawes
2001-07-23Fixes that allow the modules to be built into the kernelJeff Hartmann
2001-07-20Merge checker fixes from Alan Cox made to the drm in the ac kernel tree.Jeff Hartmann
2001-07-18Add module version name at a lower layer of the code, allows things to beJeff Hartmann
2001-07-17Someone forgot to bump the r128 and i810 drivers properly before the 4.1.0Jeff Hartmann
2001-07-16Added version string to the end of the kernel module name. This allowsJeff Hartmann
2001-07-16i810 drm security fixJeff Hartmann
2001-06-18Fix 5 security bugs found by the Stanford toolsJeff Hartmann
2001-06-18Forgot to bump date stamp.Gareth Hughes
2001-06-18Enable shared IRQs in DMA template, use in i810 driver.Gareth Hughes
2001-06-14First pass of 4.1.0 merge.David Dawes
2001-05-23Only authenticated clients can mmap() (Jeff Hartmann).Gareth Hughes
2001-05-17Make the SiS module work again. At least glxinfo reports it's working, yetAlan Hourihane
2001-05-03Make SiS driver compile with the new templated format. Not tested. minorAlan Hourihane
2001-05-01Import of XFree86 4.0.99.3David Dawes
2001-04-30fix build of i810 kernel driver for 2.4.3 or greater kernelsAlan Hourihane
2001-04-30- PCIGART patches for Alpha from CompaqKevin E Martin
2001-04-09Import -f XFree86 4.0.99.2David Dawes
2001-04-06Handle drivers that don't have __HAVE_SG defined.Alan Hourihane
2001-04-05Merged ati-pcigart-1-0-0Kevin E Martin
2001-04-03include 2.4.2Alan Hourihane
2001-04-03make 2.4.2 -> 2.4.3 change conditional. works with older than 2.4.3 kernelsAlan Hourihane
2001-04-02Update radeon DRM to v1.1.0 (texture upload changes).Gareth Hughes
2001-03-30merge in 2.4.3 kernel change.Alan Hourihane
2001-03-21- Fix MGA header info.Gareth Hughes
2001-03-19Import of XFree86 4.0.99.1David Dawes
2001-03-19Update version, date stamp.Gareth Hughes
2001-03-19Remove PRIMPTR completely.Gareth Hughes
2001-03-18__REALLY_HAVE_MTRR, vmalloc_32 fixes from Jeff Wiedemeier.Gareth Hughes
2001-03-14Merged sarea-1-0-0Kevin E Martin
2001-03-08Fix ring space calculations, tests. Based on patch by Bruce Stockwell.Gareth Hughes
2001-03-07Change error message to debug message when client dies while holding theGareth Hughes
2001-03-07surround agp calls in drm_memory with __REALLY_HAVE_AGP instead ofAlan Hourihane
2001-03-06Merge tdfx-3-1-0 branch.Gareth Hughes
2001-03-05allow dristat to find out whether AGP is write-combined or not.Alan Hourihane
2001-03-05fix that last patch to initialize the MTRR when AGP available.Alan Hourihane
2001-03-04Don't try and setup the MTRR for AGP when AGP not available. CheckAlan Hourihane
2001-02-21Add Linux 2.2.x support for stubsRik Faith
2001-02-16- Clean up the way customization of the templates is done.Gareth Hughes
2001-02-15Added missing include "drm_lists.h".Keith Whitwell
2001-02-15- Fix up merge.Gareth Hughes
2001-02-15Merge mga-1-0-0-branch into trunk.Gareth Hughes
2001-01-29Corresponding sync with PCI GART updates.Gareth Hughes
2001-01-24- Misc cleanups.Gareth Hughes
2001-01-08Merged tdfx-3-0-0Nathan Hand
#n404'>404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539
#include <cstdio>
#include <algorithm>
#include <iostream>
#include <string>
#include <unistd.h>
#include <inttypes.h>

#include "kms++.h"
#include "opts.h"
#include "kms++util.h"
#include "strhelpers.h"

using namespace std;
using namespace kms;

static struct {
	bool print_props;
	bool print_modes;
	bool print_list;
	bool x_modeline;
} s_opts;

static string format_mode(const Videomode& m, unsigned idx)
{
	string str;

	str = sformat("  %2u ", idx);

	if (s_opts.x_modeline) {
		str += sformat("%12s %6d %4u %4u %4u %4u %4u %4u %4u %4u  %2u %#x %#x",
			       m.name.c_str(),
			       m.clock,
			       m.hdisplay, m.hsync_start, m.hsync_end, m.htotal,
			       m.vdisplay, m.vsync_start, m.vsync_end, m.vtotal,
			       m.vrefresh,
			       m.flags,
			       m.type);
	} else {
		string h = sformat("%u/%u/%u/%u", m.hdisplay, m.hfp(), m.hsw(), m.hbp());
		string v = sformat("%u/%u/%u/%u", m.vdisplay, m.vfp(), m.vsw(), m.vbp());

		str += sformat("%-12s %6d %-16s %-16s %2u %#10x %#6x",
			       m.name.c_str(),
			       m.clock,
			       h.c_str(), v.c_str(),
			       m.vrefresh,
			       m.flags,
			       m.type);
	}

	return str;
}

static string format_mode_short(const Videomode& m)
{
	string h = sformat("%u/%u/%u/%u", m.hdisplay, m.hfp(), m.hsw(), m.hbp());
	string v = sformat("%u/%u/%u/%u", m.vdisplay, m.vfp(), m.vsw(), m.vbp());

	return sformat("%s %d %s %s %u",
		       m.name.c_str(),
		       m.clock,
		       h.c_str(), v.c_str(),
		       m.vrefresh);
}

static string format_connector(Connector& c)
{
	string str;

	str = sformat("Connector %u (%u) %s",
		      c.idx(), c.id(), c.fullname().c_str());

	if (c.connected())
		str += " (connected)";

	return str;
}

static string format_encoder(Encoder& e)
{
	return sformat("Encoder %u (%u) %s",
		       e.idx(), e.id(), e.get_encoder_type().c_str());
}

static string format_crtc(Crtc& c)
{
	string str;

	str = sformat("Crtc %u (%u)", c.idx(), c.id());

	if (c.mode_valid())
		str += " " + format_mode_short(c.mode());

	return str;
}

static string format_plane(Plane& p)
{
	string str;

	str = sformat("Plane %u (%u)", p.idx(), p.id());

	if (p.fb_id())
		str += sformat(" fb-id: %u", p.fb_id());

	if (p.card().has_atomic()) {
		str += sformat(" %u,%u %ux%u -> %u,%u %ux%u",
			       (uint32_t)p.get_prop_value("SRC_X") >> 16,
			       (uint32_t)p.get_prop_value("SRC_Y") >> 16,
			       (uint32_t)p.get_prop_value("SRC_W") >> 16,
			       (uint32_t)p.get_prop_value("SRC_H") >> 16,
			       (uint32_t)p.get_prop_value("CRTC_X"),
			       (uint32_t)p.get_prop_value("CRTC_Y"),
			       (uint32_t)p.get_prop_value("CRTC_W"),
			       (uint32_t)p.get_prop_value("CRTC_H"));
	}

	string fmts = join<PixelFormat>(p.get_formats(), " ", [](PixelFormat fmt) { return PixelFormatToFourCC(fmt); });

	str += sformat(" (%s)", fmts.c_str());

	return str;
}

static string format_fb(Framebuffer& fb)
{
	return sformat("FB %u %ux%u",
		       fb.id(), fb.width(), fb.height());
}

static string format_property(const Property* prop, uint64_t val)
{
	string ret = sformat("%s = ", prop->name().c_str());

	switch (prop->type()) {
	case PropertyType::Bitmask:
	{
		vector<string> v, vall;

		for (auto kvp : prop->get_enums()) {
			if (val & (1 << kvp.first))
				v.push_back(kvp.second);
			vall.push_back(kvp.second);
		}

		ret += sformat("%s (%s)", join(v, "|").c_str(), join(vall, "|").c_str());

		break;
	}

	case PropertyType::Blob:
	{
		uint32_t blob_id = (uint32_t)val;

		if (blob_id) {
			Blob blob(prop->card(), blob_id);
			auto data = blob.data();

			ret += sformat("blob-id %u len %zu", blob_id, data.size());
		} else {
			ret += sformat("blob-id %u", blob_id);
		}

		break;
	}

	case PropertyType::Enum:
	{
		string cur;
		vector<string> vall;

		for (auto kvp : prop->get_enums()) {
			if (val == kvp.first)
				cur = kvp.second;
			vall.push_back(kvp.second);
		}

		ret += sformat("%s (%s)", cur.c_str(), join(vall, "|").c_str());

		break;
	}

	case PropertyType::Object:
	{
		ret += sformat("object id %u", (uint32_t)val);
		break;
	}

	case PropertyType::Range:
	{
		auto values = prop->get_values();

		ret += sformat("%" PRIu64 " [%" PRIu64 " - %" PRIu64 "]",
			       val, values[0], values[1]);

		break;
	}

	case PropertyType::SignedRange:
	{
		auto values = prop->get_values();

		ret += sformat("%" PRIi64 " [%" PRIi64 " - %" PRIi64 "]",
			       (int64_t)val, (int64_t)values[0], (int64_t)values[1]);

		break;
	}

	}

	if (prop->is_pending())
		ret += " (pending)";
	if (prop->is_immutable())
		ret += " (immutable)";

	return ret;
}

static vector<string> format_props(DrmPropObject* o)
{
	vector<string> lines;

	auto pmap = o->get_prop_map();
	for (auto pp : pmap) {
		const Property* p = o->card().get_prop(pp.first);
		lines.push_back(format_property(p, pp.second));
	}

	return lines;
}

static string format_ob(DrmObject* ob)
{
	if (auto o = dynamic_cast<Connector*>(ob))
		return format_connector(*o);
	else if (auto o = dynamic_cast<Encoder*>(ob))
		return format_encoder(*o);
	else if (auto o = dynamic_cast<Crtc*>(ob))
		return format_crtc(*o);
	else if (auto o = dynamic_cast<Plane*>(ob))
		return format_plane(*o);
	else if (auto o = dynamic_cast<Framebuffer*>(ob))
		return format_fb(*o);
	else
		EXIT("Unkown DRM Object type\n");
}

template<class T>
vector<T> filter(const vector<T>& sequence, function<bool(T)> predicate)
{
	vector<T> result;

	for(auto it = sequence.begin(); it != sequence.end(); ++it)
		if(predicate(*it))
			result.push_back(*it);

	return result;
}

struct Entry
{
	string title;
	vector<string> lines;
	vector<Entry> children;
};

static Entry& add_entry(vector<Entry>& entries)
{
	entries.emplace_back();
	return entries.back();
}
/*
static bool on_tty()
{
	return isatty(STDOUT_FILENO) > 0;
}
*/
enum class TreeGlyphMode {
	None,
	ASCII,
	UTF8,
};

static TreeGlyphMode s_glyph_mode = TreeGlyphMode::None;

enum class TreeGlyph {
	Vertical,
	Branch,
	Right,
	Space,
};

static const map<TreeGlyph, string> glyphs_utf8 = {
	{ TreeGlyph::Vertical, "│ " },
	{ TreeGlyph::Branch, "├─" },
	{ TreeGlyph::Right, "└─" },
	{ TreeGlyph::Space, "  " },

};

static const map<TreeGlyph, string> glyphs_ascii = {
	{ TreeGlyph::Vertical, "| " },
	{ TreeGlyph::Branch, "|-" },
	{ TreeGlyph::Right, "`-" },
	{ TreeGlyph::Space, "  " },

};

const char* get_glyph(TreeGlyph glyph)
{
	if (s_glyph_mode == TreeGlyphMode::None)
		return "  ";

	const map<TreeGlyph, string>& glyphs = s_glyph_mode == TreeGlyphMode::UTF8 ? glyphs_utf8 : glyphs_ascii;

	return glyphs.at(glyph).c_str();
}

static void print_entry(const Entry& e, const string& prefix, bool is_child, bool is_last)
{
	string prefix1;
	string prefix2;

	if (is_child) {
		prefix1 = prefix + (is_last ? get_glyph(TreeGlyph::Right) : get_glyph(TreeGlyph::Branch));
		prefix2 = prefix + (is_last ? get_glyph(TreeGlyph::Space) : get_glyph(TreeGlyph::Vertical));
	}

	printf("%s%s\n", prefix1.c_str(), e.title.c_str());

	bool has_children = e.children.size() > 0;

	string data_prefix = prefix2 + (has_children ? get_glyph(TreeGlyph::Vertical) : get_glyph(TreeGlyph::Space));

	for (const string& str : e.lines) {
		string p = data_prefix + get_glyph(TreeGlyph::Space);
		printf("%s%s\n", p.c_str(), str.c_str());
	}

	for (const Entry& child : e.children) {
		bool is_last = &child == &e.children.back();

		print_entry(child, prefix2, true, is_last);
	}
}

static void print_entries(const vector<Entry>& entries, const string& prefix)
{