Home | History | Annotate | Download | only in src
      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