• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #include <xf86drm.h>
2 #include <xf86drmMode.h>
3 #include <cmath>
4 #include <sstream>
5 #include <fmt/format.h>
6 
7 #include <kms++/kms++.h>
8 #include "helpers.h"
9 
10 using namespace std;
11 
12 namespace kms
13 {
valid() const14 bool Videomode::valid() const
15 {
16 	return !!clock;
17 }
18 
to_blob(Card & card) const19 unique_ptr<Blob> Videomode::to_blob(Card& card) const
20 {
21 	drmModeModeInfo drm_mode = video_mode_to_drm_mode(*this);
22 
23 	return unique_ptr<Blob>(new Blob(card, &drm_mode, sizeof(drm_mode)));
24 }
25 
calculated_vrefresh() const26 float Videomode::calculated_vrefresh() const
27 {
28 	// XXX interlace should only halve visible vertical lines, not blanking
29 	float refresh = (clock * 1000.0) / (htotal * vtotal) * (interlace() ? 2 : 1);
30 	return roundf(refresh * 100.0) / 100.0;
31 }
32 
interlace() const33 bool Videomode::interlace() const
34 {
35 	return flags & DRM_MODE_FLAG_INTERLACE;
36 }
37 
hsync() const38 SyncPolarity Videomode::hsync() const
39 {
40 	if (flags & DRM_MODE_FLAG_PHSYNC)
41 		return SyncPolarity::Positive;
42 	if (flags & DRM_MODE_FLAG_NHSYNC)
43 		return SyncPolarity::Negative;
44 	return SyncPolarity::Undefined;
45 }
46 
vsync() const47 SyncPolarity Videomode::vsync() const
48 {
49 	if (flags & DRM_MODE_FLAG_PVSYNC)
50 		return SyncPolarity::Positive;
51 	if (flags & DRM_MODE_FLAG_NVSYNC)
52 		return SyncPolarity::Negative;
53 	return SyncPolarity::Undefined;
54 }
55 
set_interlace(bool ilace)56 void Videomode::set_interlace(bool ilace)
57 {
58 	if (ilace)
59 		flags |= DRM_MODE_FLAG_INTERLACE;
60 	else
61 		flags &= ~DRM_MODE_FLAG_INTERLACE;
62 }
63 
set_hsync(SyncPolarity pol)64 void Videomode::set_hsync(SyncPolarity pol)
65 {
66 	flags &= ~(DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NHSYNC);
67 
68 	switch (pol) {
69 	case SyncPolarity::Positive:
70 		flags |= DRM_MODE_FLAG_PHSYNC;
71 		break;
72 	case SyncPolarity::Negative:
73 		flags |= DRM_MODE_FLAG_NHSYNC;
74 		break;
75 	default:
76 		break;
77 	}
78 }
79 
set_vsync(SyncPolarity pol)80 void Videomode::set_vsync(SyncPolarity pol)
81 {
82 	flags &= ~(DRM_MODE_FLAG_PVSYNC | DRM_MODE_FLAG_NVSYNC);
83 
84 	switch (pol) {
85 	case SyncPolarity::Positive:
86 		flags |= DRM_MODE_FLAG_PVSYNC;
87 		break;
88 	case SyncPolarity::Negative:
89 		flags |= DRM_MODE_FLAG_NVSYNC;
90 		break;
91 	default:
92 		break;
93 	}
94 }
95 
to_string_short() const96 string Videomode::to_string_short() const
97 {
98 	return fmt::format("{}x{}{}@{:.2f}", hdisplay, vdisplay, interlace() ? "i" : "", calculated_vrefresh());
99 }
100 
sync_to_char(SyncPolarity pol)101 static char sync_to_char(SyncPolarity pol)
102 {
103 	switch (pol) {
104 	case SyncPolarity::Positive:
105 		return '+';
106 	case SyncPolarity::Negative:
107 		return '-';
108 	default:
109 		return '?';
110 	}
111 }
112 
to_string_long() const113 string Videomode::to_string_long() const
114 {
115 	string h = fmt::format("{}/{}/{}/{}/{}", hdisplay, hfp(), hsw(), hbp(), sync_to_char(hsync()));
116 	string v = fmt::format("{}/{}/{}/{}/{}", vdisplay, vfp(), vsw(), vbp(), sync_to_char(vsync()));
117 
118 	string str = fmt::format("{} {:.3f} {} {} {} ({:.2f}) {:#x} {:#x}",
119 				 to_string_short(),
120 				 clock / 1000.0,
121 				 h, v,
122 				 vrefresh, calculated_vrefresh(),
123 				 flags,
124 				 type);
125 
126 	return str;
127 }
128 
to_string_long_padded() const129 string Videomode::to_string_long_padded() const
130 {
131 	string h = fmt::format("{}/{}/{}/{}/{}", hdisplay, hfp(), hsw(), hbp(), sync_to_char(hsync()));
132 	string v = fmt::format("{}/{}/{}/{}/{}", vdisplay, vfp(), vsw(), vbp(), sync_to_char(vsync()));
133 
134 	string str = fmt::format("{:<16} {:7.3f} {:<18} {:<18} {:2} ({:.2f}) {:#10x} {:#6x}",
135 				 to_string_short(),
136 				 clock / 1000.0,
137 				 h, v,
138 				 vrefresh, calculated_vrefresh(),
139 				 flags,
140 				 type);
141 
142 	return str;
143 }
144 
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)145 Videomode videomode_from_timings(uint32_t clock_khz,
146 				 uint16_t hact, uint16_t hfp, uint16_t hsw, uint16_t hbp,
147 				 uint16_t vact, uint16_t vfp, uint16_t vsw, uint16_t vbp)
148 {
149 	Videomode m{};
150 	m.clock = clock_khz;
151 
152 	m.hdisplay = hact;
153 	m.hsync_start = hact + hfp;
154 	m.hsync_end = hact + hfp + hsw;
155 	m.htotal = hact + hfp + hsw + hbp;
156 
157 	m.vdisplay = vact;
158 	m.vsync_start = vact + vfp;
159 	m.vsync_end = vact + vfp + vsw;
160 	m.vtotal = vact + vfp + vsw + vbp;
161 
162 	return m;
163 }
164 
165 } // namespace kms
166