def available(): if os.path.exists('/opt/vc/bin/tvservice'): cea = json.loads( debug.subprocess_check_output( ['/opt/vc/bin/tvservice', '-j', '-m', 'CEA'], stderr=subprocess.STDOUT)) dmt = json.loads( debug.subprocess_check_output( ['/opt/vc/bin/tvservice', '-j', '-m', 'DMT'], stderr=subprocess.STDOUT)) else: logging.error( '/opt/vc/bin/tvservice is missing! No HDMI resolutions will be available' ) cea = [] dmt = [] result = [] for entry in cea: entry['mode'] = 'CEA' entry['depth'] = 32 entry['reverse'] = True result.append(entry) for entry in dmt: entry['mode'] = 'DMT' entry['depth'] = 32 entry['reverse'] = True result.append(entry) internal = display._internaldisplay() if internal: logging.info('Internal display detected') result.append(internal) # Finally, sort by pixelcount return sorted(result, key=lambda k: k['width'] * k['height'])
def current(self): result = None if self.isHDMI() and os.path.exists('/opt/vc/bin/tvservice'): output = debug.subprocess_check_output( ['/opt/vc/bin/tvservice', '-s'], stderr=subprocess.STDOUT) # state 0x120006 [DVI DMT (82) RGB full 16:9], 1920x1080 @ 60.00Hz, progressive m = re.search( 'state 0x[0-9a-f]* \[([A-Z]*) ([A-Z]*) \(([0-9]*)\) [^,]*, ([0-9]*)x([0-9]*) \@ ([0-9]*)\.[0-9]*Hz, (.)', output) if m is None: return None result = { 'mode': m.group(2), 'code': int(m.group(3)), 'width': int(m.group(4)), 'height': int(m.group(5)), 'rate': int(m.group(6)), 'aspect_ratio': '', 'scan': m.group(7), '3d_modes': [], 'depth': 32, 'reverse': True, } else: result = display._internaldisplay() return result
def _isDPI(): if os.path.exists('/opt/vc/bin/tvservice'): output = debug.subprocess_check_output( ['/opt/vc/bin/tvservice', '-s'], stderr=subprocess.STDOUT) else: output = '' return '[LCD]' in output
def _internaldisplay(): entry = { 'mode': 'INTERNAL', 'code': None, 'width': 0, 'height': 0, 'rate': 60, 'aspect_ratio': '', 'scan': '(internal)', '3d_modes': [], 'reverse': False } device = '/dev/fb1' if not os.path.exists(device): if display._isDPI(): device = '/dev/fb0' else: device = None if device: info = debug.subprocess_check_output( ['/bin/fbset', '-fb', device], stderr=subprocess.STDOUT).split('\n') for line in info: line = line.strip() if line.startswith('geometry'): parts = line.split(' ') entry['width'] = int(parts[1]) entry['height'] = int(parts[2]) entry['depth'] = int(parts[5]) entry['code'] = int(device[-1]) # rgba 8/16,8/8,8/0,8/24 <== Detect rgba order if line.startswith('rgba'): m = re.search( 'rgba [0-9]*/([0-9]*),[0-9]*/([0-9]*),[0-9]*/([0-9]*),[0-9]*/([0-9]*)', line) if m is None: logging.error('fbset output has changed, cannot parse') return None entry['reverse'] = m.group(1) != 0 if entry['code'] is not None: logging.debug('Internal display: ' + repr(entry)) return entry return None
def get(self): if self.enabled: args = [ 'convert', '-depth', '8', '-size', '%dx%d' % (self.width + self.xoffset, self.height + self.yoffset), '%s:-' % (self.format), 'jpg:-' ] else: args = [ 'convert', '-size', '%dx%d' % (640, 360), '-background', 'black', '-fill', 'white', '-gravity', 'center', '-weight', '700', '-pointsize', '32', 'label:%s' % "Display off", '-depth', '8', 'jpg:-' ] if not self.enabled: result = debug.subprocess_check_output(args, stderr=self.void) elif self.depth in [24, 32]: device = self.getDevice() if self.emulate: device = '/tmp/fb.bin' with open(device, 'rb') as fb: pip = subprocess.Popen(args, stdin=fb, stdout=subprocess.PIPE, stderr=self.void) result = pip.communicate()[0] elif self.depth == 16: with open(self.getDevice(), 'rb') as fb: src = subprocess.Popen( ['/root/photoframe/rgb565/rgb565', 'reverse'], stdout=subprocess.PIPE, stdin=fb, stderr=self.void) pip = subprocess.Popen(args, stdin=src.stdout, stdout=subprocess.PIPE) src.stdout.close() result = pip.communicate()[0] else: logging.error('Do not know how to grab this kind of framebuffer') return (result, 'image/jpeg')