Skip to content

Commit ea08384

Browse files
committed
Add virtualterminal and framebuffer support
1 parent f243ec8 commit ea08384

File tree

2 files changed

+280
-0
lines changed

2 files changed

+280
-0
lines changed

ev3dev/framebuffer.py

Lines changed: 181 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,181 @@
1+
#!/usr/bin/env python
2+
3+
# framebuffer.py
4+
#
5+
# Helper class for handling framebuffers for ev3dev
6+
7+
# The MIT License (MIT)
8+
#
9+
# Copyright (c) 2016 David Lechner <[email protected]>
10+
#
11+
# Permission is hereby granted, free of charge, to any person obtaining a copy
12+
# of this software and associated documentation files (the "Software"), to deal
13+
# in the Software without restriction, including without limitation the rights
14+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
15+
# copies of the Software, and to permit persons to whom the Software is
16+
# furnished to do so, subject to the following conditions:
17+
#
18+
# The above copyright notice and this permission notice shall be included in all
19+
# copies or substantial portions of the Software.
20+
#
21+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
27+
# SOFTWARE.
28+
29+
from ctypes import Structure, c_char, c_ulong, c_uint16, c_uint32
30+
from enum import Enum
31+
from fcntl import ioctl
32+
from collections import namedtuple
33+
34+
class FrameBuffer(object):
35+
36+
# ioctls
37+
_FBIOGET_VSCREENINFO = 0x4600
38+
_FBIOGET_FSCREENINFO = 0x4602
39+
_FBIOGET_CON2FBMAP = 0x460F
40+
41+
class Type(Enum):
42+
PACKED_PIXELS = 0 # Packed Pixels
43+
PLANES = 1 # Non interleaved planes
44+
INTERLEAVED_PLANES = 2 # Interleaved planes
45+
TEXT = 3 # Text/attributes
46+
VGA_PLANES = 4 # EGA/VGA planes
47+
FOURCC = 5 # Type identified by a V4L2 FOURCC
48+
49+
class Visual(Enum):
50+
MONO01 = 0 # Monochrome 1=Black 0=White
51+
MONO10 = 1 # Monochrome 1=White 0=Black
52+
TRUECOLOR = 2 # True color
53+
PSEUDOCOLOR = 3 # Pseudo color (like atari)
54+
DIRECTCOLOR = 4 # Direct color
55+
STATIC_PSEUDOCOLOR = 5 # Pseudo color readonly
56+
FOURCC = 6 # Visual identified by a V4L2 FOURCC
57+
58+
class _FixedScreenInfo(Structure):
59+
_fields_ = [
60+
('id', c_char * 16), # identification string eg "TT Builtin"
61+
('smem_start', c_ulong), # Start of frame buffer mem (physical address)
62+
('smem_len', c_uint32), # Length of frame buffer mem
63+
('type', c_uint32), # see FB_TYPE_*
64+
('type_aux', c_uint32), # Interleave for interleaved Planes
65+
('visual', c_uint32), # see FB_VISUAL_*
66+
('xpanstep', c_uint16), # zero if no hardware panning
67+
('ypanstep', c_uint16), # zero if no hardware panning
68+
('ywrapstep', c_uint16), # zero if no hardware ywrap
69+
('line_length', c_uint32), # length of a line in bytes
70+
('mmio_start', c_ulong), # Start of Memory Mapped I/O (physical address)
71+
('mmio_len', c_uint32), # Length of Memory Mapped I/O
72+
('accel', c_uint32), # Indicate to driver which specific chip/card we have
73+
('capabilities', c_uint16), # see FB_CAP_*
74+
('reserved', c_uint16 * 2), # Reserved for future compatibility
75+
]
76+
77+
class _VariableScreenInfo(Structure):
78+
79+
class _Bitfield(Structure):
80+
_fields_ = [
81+
('offset', c_uint32), # beginning of bitfield
82+
('length', c_uint32), # length of bitfield
83+
('msb_right', c_uint32), # != 0 : Most significant bit is right
84+
]
85+
86+
_fields_ = [
87+
('xres', c_uint32), # visible resolution
88+
('yres', c_uint32),
89+
('xres_virtual', c_uint32), # virtual resolution
90+
('yres_virtual', c_uint32),
91+
('xoffset', c_uint32), # offset from virtual to visible
92+
('yoffset', c_uint32), # resolution
93+
('bits_per_pixel', c_uint32), # guess what
94+
('grayscale', c_uint32), # 0 = color, 1 = grayscale, >1 = FOURCC
95+
('red', _Bitfield), # bitfield in fb mem if true color,
96+
('green', _Bitfield), # else only length is significant
97+
('blue', _Bitfield),
98+
('transp', _Bitfield), # transparency
99+
('nonstd', c_uint32), # != 0 Non standard pixel format
100+
('activate', c_uint32), # see FB_ACTIVATE_*
101+
('height', c_uint32), # height of picture in mm
102+
('width', c_uint32), # width of picture in mm
103+
('accel_flags', c_uint32), # (OBSOLETE) see fb_info.flags
104+
# Timing: All values, in pixclocks, except pixclock (of course)
105+
('pixclock', c_uint32), # pixel clock in ps (pico seconds)
106+
('left_margin', c_uint32), # time from sync to picture
107+
('right_margin', c_uint32), # time from picture to sync
108+
('upper_margin', c_uint32), # time from sync to picture
109+
('lower_margin', c_uint32),
110+
('hsync_len', c_uint32), # length of horizontal sync
111+
('vsync_len', c_uint32), # length of vertical sync
112+
('sync', c_uint32), # see FB_SYNC_*
113+
('vmode', c_uint32), # see FB_VMODE_*
114+
('rotate', c_uint32), # angle we rotate counter clockwise
115+
('colorspace', c_uint32), # colorspace for FOURCC-based modes
116+
('reserved', c_uint32 * 4), # Reserved for future compatibility
117+
]
118+
119+
class _Console2FrameBufferMap(Structure):
120+
_fields_ = [
121+
('console', c_uint32),
122+
('framebuffer', c_uint32),
123+
]
124+
125+
def __init__(self, device='/dev/fb0'):
126+
self._fd = open(device, mode='r+b', buffering=0)
127+
self._fixed_info = self._FixedScreenInfo()
128+
ioctl(self._fd, self._FBIOGET_FSCREENINFO, self._fixed_info)
129+
self._variable_info = self._VariableScreenInfo()
130+
ioctl(self._fd, self._FBIOGET_VSCREENINFO, self._variable_info)
131+
132+
def close(self):
133+
self._fd.close()
134+
135+
def clear(self):
136+
self._fd.seek(0)
137+
self._fd.write(b'\0' * self._fixed_info.smem_len)
138+
139+
def write_raw(self, data):
140+
self._fd.seek(0)
141+
self._fd.write(data)
142+
143+
@staticmethod
144+
def get_fb_for_console(console):
145+
with open('/dev/fb0', mode='r+b') as fd:
146+
m = FrameBuffer._Console2FrameBufferMap()
147+
m.console = console
148+
ioctl(fd, FrameBuffer._FBIOGET_CON2FBMAP, m)
149+
return FrameBuffer('/dev/fb{}'.format(m.framebuffer))
150+
151+
@property
152+
def type(self):
153+
return self.Type(self._fixed_info.type)
154+
155+
@property
156+
def visual(self):
157+
return self.Visual(self._fixed_info.visual)
158+
159+
@property
160+
def line_length(self):
161+
return self._fixed_info.line_length
162+
163+
@property
164+
def resolution(self):
165+
"""Visible resolution"""
166+
Resolution = namedtuple('Resolution', 'x y')
167+
return Resolution(self._variable_info.xres, self._variable_info.yres)
168+
169+
@property
170+
def bits_per_pixel(self):
171+
return self._variable_info.bits_per_pixel
172+
173+
@property
174+
def grayscale(self):
175+
return self._variable_info.grayscale
176+
177+
@property
178+
def size(self):
179+
"""Size of picture in mm"""
180+
Size = namedtuple('Size', 'width height')
181+
return Size(self._variable_info.width, self._variable_info.height)

ev3dev/virtualterminal.py

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
#!/usr/bin/env python
2+
3+
# virtualterminal.py
4+
#
5+
# Helper class for handling framebuffers for ev3dev
6+
7+
# The MIT License (MIT)
8+
#
9+
# Copyright (c) 2016 David Lechner <[email protected]>
10+
#
11+
# Permission is hereby granted, free of charge, to any person obtaining a copy
12+
# of this software and associated documentation files (the "Software"), to deal
13+
# in the Software without restriction, including without limitation the rights
14+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
15+
# copies of the Software, and to permit persons to whom the Software is
16+
# furnished to do so, subject to the following conditions:
17+
#
18+
# The above copyright notice and this permission notice shall be included in all
19+
# copies or substantial portions of the Software.
20+
#
21+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
27+
# SOFTWARE.
28+
29+
from ctypes import Structure, c_char, c_short, c_ushort, c_uint
30+
from enum import Enum
31+
from fcntl import ioctl
32+
33+
class VirtualTerminal(object):
34+
35+
# ioctls
36+
_VT_OPENQRY = 0x5600 # find next available vt
37+
_VT_GETMODE = 0x5601 # get mode of active vt
38+
_VT_SETMODE = 0x5602 # set mode of active vt
39+
_VT_GETSTATE = 0x5603 # get global vt state info
40+
_VT_SENDSIG = 0x5604 # signal to send to bitmask of vts
41+
_VT_RELDISP = 0x5605 # release display
42+
_VT_ACTIVATE = 0x5606 # make vt active
43+
_VT_WAITACTIVE = 0x5607 # wait for vt active
44+
_VT_DISALLOCATE = 0x5608 # free memory associated to vt
45+
_VT_SETACTIVATE = 0x560F # Activate and set the mode of a console
46+
_KDSETMODE = 0x4B3A # set text/graphics mode
47+
48+
class _VtMode(Structure):
49+
_fields_ = [
50+
('mode', c_char), # vt mode
51+
('waitv', c_char), # if set, hang on writes if not active
52+
('relsig', c_short), # signal to raise on release request
53+
('acqsig', c_short), # signal to raise on acquisition
54+
('frsig', c_short), # unused (set to 0)
55+
]
56+
57+
class VtMode(Enum):
58+
AUTO = 0
59+
PROCESS = 1
60+
ACKACQ = 2
61+
62+
class _VtState(Structure):
63+
_fields_ = [
64+
('v_active', c_ushort), # active vt
65+
('v_signal', c_ushort), # signal to send
66+
('v_state', c_ushort), # vt bitmask
67+
]
68+
69+
class KdMode(Enum):
70+
TEXT = 0x00
71+
GRAPHICS = 0x01
72+
TEXT0 = 0x02 # obsolete
73+
TEXT1 = 0x03 # obsolete
74+
75+
def __init__(self):
76+
self._fd = open('/dev/tty', 'r')
77+
78+
def close(self):
79+
self._fd.close()
80+
81+
def get_next_available(self):
82+
n = c_uint()
83+
ioctl(self._fd, self._VT_OPENQRY, n)
84+
return n.value
85+
86+
def activate(self, num):
87+
ioctl(self._fd, self._VT_ACTIVATE, num)
88+
ioctl(self._fd, self._VT_WAITACTIVE, num)
89+
90+
def get_active(self):
91+
state = VirtualTerminal._VtState()
92+
ioctl(self._fd, self._VT_GETSTATE, state)
93+
return state.v_active
94+
95+
def set_graphics_mode(self):
96+
ioctl(self._fd, self._KDSETMODE, self.KdMode.GRAPHICS.value)
97+
98+
def set_text_mode(self):
99+
ioctl(self._fd, self._KDSETMODE, self.KdMode.TEXT.value)

0 commit comments

Comments
 (0)