• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #include <xf86drm.h>
2 #include <xf86drmMode.h>
3 #include <math.h>
4 #include <sstream>
5 
6 #include <kms++/kms++.h>
7 #include "helpers.h"
8 
9 using namespace std;
10 
11 namespace kms
12 {
13 
to_blob(Card & card) const14 unique_ptr<Blob> Videomode::to_blob(Card& card) const
15 {
16 	drmModeModeInfo drm_mode = video_mode_to_drm_mode(*this);
17 
18 	return unique_ptr<Blob>(new Blob(card, &drm_mode, sizeof(drm_mode)));
19 }
20 
calculated_vrefresh() const21 float Videomode::calculated_vrefresh() const
22 {
23 	// XXX interlace should only halve visible vertical lines, not blanking
24 	float refresh = (clock * 1000.0) / (htotal * vtotal) * (interlace() ? 2 : 1);
25 	return roundf(refresh * 100.0) / 100.0;
26 }
27 
interlace() const28 bool Videomode::interlace() const
29 {
30 	return flags & DRM_MODE_FLAG_INTERLACE;
31 }
32 
hsync() const33 SyncPolarity Videomode::hsync() const
34 {
35 	if (flags & DRM_MODE_FLAG_PHSYNC)
36 		return SyncPolarity::Positive;
37 	if (flags & DRM_MODE_FLAG_NHSYNC)
38 		return SyncPolarity::Negative;
39 	return SyncPolarity::Undefined;
40 }
41 
vsync() const42 SyncPolarity Videomode::vsync() const
43 {
44 	if (flags & DRM_MODE_FLAG_PVSYNC)
45 		return SyncPolarity::Positive;
46 	if (flags & DRM_MODE_FLAG_NVSYNC)
47 		return SyncPolarity::Negative;
48 	return SyncPolarity::Undefined;
49 }
50 
set_interlace(bool ilace)51 void Videomode::set_interlace(bool ilace)
52 {
53 	if (ilace)
54 		flags |= DRM_MODE_FLAG_INTERLACE;
55 	else
56 		flags &= ~DRM_MODE_FLAG_INTERLACE;
57 }
58 
set_hsync(SyncPolarity pol)59 void Videomode::set_hsync(SyncPolarity pol)
60 {
61 	flags &= ~(DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NHSYNC);
62 
63 	switch (pol) {
64 	case SyncPolarity::Positive:
65 		flags |= DRM_MODE_FLAG_PHSYNC;
66 		break;
67 	case SyncPolarity::Negative:
68 		flags |= DRM_MODE_FLAG_NHSYNC;
69 		break;
70 	default:
71 		break;
72 	}
73 }
74 
set_vsync(SyncPolarity pol)75 void Videomode::set_vsync(SyncPolarity pol)
76 {
77 	flags &= ~(DRM_MODE_FLAG_PVSYNC | DRM_MODE_FLAG_NVSYNC);
78 
79 	switch (pol) {
80 	case SyncPolarity::Positive:
81 		flags |= DRM_MODE_FLAG_PVSYNC;
82 		break;
83 	case SyncPolarity::Negative:
84 		flags |= DRM_MODE_FLAG_NVSYNC;
85 		break;
86 	default:
87 		break;
88 	}
89 }
90 
to_string() const91 string Videomode::to_string() const
92 {
93 	std::stringstream ss;
94 	ss << hdisplay << "x" << vdisplay;
95 	if (interlace())
96 		ss << "i";
97 	ss << "@" << calculated_vrefresh();
98 	return ss.str();
99 }
100 
videomode_from_timings(uint32_t clock_khz,uint16_t hact,uint16_t hfp,uint16_t hsw,uint16_t hbp,uint16_t vact,uint16_t vfp,uint16_t vsw,uint16_t vbp)101 Videomode videomode_from_timings(uint32_t clock_khz,
102 				 uint16_t hact, uint16_t hfp, uint16_t hsw, uint16_t hbp,
103 				 uint16_t vact, uint16_t vfp, uint16_t vsw, uint16_t vbp)
104 {
105 	Videomode m { };
106 	m.clock = clock_khz;
107 
108 	m.hdisplay = hact;
109 	m.hsync_start = hact + hfp;
110 	m.hsync_end = hact + hfp + hsw;
111 	m.htotal = hact + hfp + hsw + hbp;
112 
113 	m.vdisplay = vact;
114 	m.vsync_start = vact + vfp;
115 	m.vsync_end = vact + vfp + vsw;
116 	m.vtotal = vact + vfp + vsw + vbp;
117 
118 	return m;
119 }
120 
121 }
122