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