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 14 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 21 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 28 bool Videomode::interlace() const 29 { 30 return flags & DRM_MODE_FLAG_INTERLACE; 31 } 32 33 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 42 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 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 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 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 91 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 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