Skip to content

Commit af1e010

Browse files
Merge pull request #57 from tiagocoutinho/frame-buffer
Initial version of frame buffer
2 parents 1153599 + 2f68d73 commit af1e010

File tree

7 files changed

+596
-0
lines changed

7 files changed

+596
-0
lines changed

docs/api/fb.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# 📺 Frame buffer
2+
3+
::: linuxpy.fb.device

docs/user_guide/fb.md

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
# 📺 Frame buffer
2+
3+
Human friendly interface to linux frame buffer.
4+
5+
Without further ado:
6+
7+
<div class="termy" data-ty-macos>
8+
<span data-ty="input" data-ty-prompt="$">python</span>
9+
<span data-ty="input" data-ty-prompt=">>>">from linuxpy.fb.device import find</span>
10+
<span data-ty="input" data-ty-prompt=">>>">with find() as fb:</span>
11+
<span data-ty="input" data-ty-prompt="..."> print(fb.get_fix_screen_info())</span>
12+
<span data-ty>
13+
FixScreenInfo(name='i915drmfb',
14+
memory_start=0,
15+
memory_size=33177600,
16+
type=Type.PACKED_PIXELS: 0,
17+
type_aux=Text.MDA: 0,
18+
visual=Visual.TRUECOLOR: 2,
19+
x_pan_step=1,
20+
y_pan_step=1,
21+
y_wrap_step=0,
22+
line_size=15360,
23+
mmap_start=0,
24+
mmap_size=0,
25+
acceleration=Acceleration.NONE: 0,
26+
capabilities=Capability: 0)
27+
</span>
28+
</div>

linuxpy/codegen/fb.py

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
#
2+
# This file is part of the linuxpy project
3+
#
4+
# Copyright (c) 2024 Tiago Coutinho
5+
# Distributed under the GPLv3 license. See LICENSE for more info.
6+
7+
import pathlib
8+
9+
from linuxpy.codegen.base import CEnum, run
10+
11+
HEADERS = [
12+
"/usr/include/linux/fb.h",
13+
]
14+
15+
16+
TEMPLATE = """\
17+
#
18+
# This file is part of the linuxpy project
19+
#
20+
# Copyright (c) 2024 Tiago Coutinho
21+
# Distributed under the GPLv3 license. See LICENSE for more info.
22+
23+
# This file has been generated by {name}
24+
# Date: {date}
25+
# System: {system}
26+
# Release: {release}
27+
# Version: {version}
28+
29+
import enum
30+
31+
from linuxpy.ioctl import IOR as _IOR, IOW as _IOW, IOWR as _IOWR
32+
from linuxpy.ctypes import u8, u16, u32, cuint, cint, cchar, culong
33+
from linuxpy.ctypes import Struct, Union, POINTER, cvoidp
34+
35+
36+
{enums_body}
37+
38+
39+
{structs_body}
40+
41+
42+
{iocs_body}
43+
"""
44+
45+
46+
def no_mask(key, value):
47+
return not key.endswith("_MASK")
48+
49+
50+
# macros from #define statements
51+
MACRO_ENUMS = [
52+
CEnum("Type", "FB_TYPE_"),
53+
CEnum("Text", "FB_AUX_TEXT_", filter=no_mask),
54+
CEnum("VGAPlanes", "FB_AUX_VGA_PLANES_"),
55+
CEnum("Visual", "FB_VISUAL_"),
56+
CEnum("Acceleration", "FB_ACCEL_"),
57+
CEnum("Activate", ["FB_ACTIVATE_", "FB_CHANGE_"], klass="IntFlag", filter=no_mask),
58+
CEnum("Sync", "FB_SYNC_", klass="IntFlag"),
59+
CEnum("VarMode", "FB_VMODE_", klass="IntFlag", filter=no_mask),
60+
CEnum("Rotation", "FB_ROTATE_"),
61+
CEnum("VESABlank", "VESA_"),
62+
CEnum("VarBlank", "FB_VBLANK_", klass="IntFlag"),
63+
CEnum("Cursor", "FB_CUR_", klass="IntFlag"),
64+
CEnum("Capability", "FB_CAP_", klass="IntFlag"),
65+
CEnum("IOC", "FBIO"),
66+
]
67+
68+
69+
this_dir = pathlib.Path(__file__).parent
70+
71+
72+
def main(output=this_dir.parent / "fb" / "raw.py"):
73+
import logging
74+
75+
logging.basicConfig(level="DEBUG")
76+
run(__name__, HEADERS, TEMPLATE, MACRO_ENUMS, output=output)
77+
78+
79+
if __name__ == "__main__":
80+
main()

linuxpy/fb/__init__.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
#
2+
# This file is part of the linuxpy project
3+
#
4+
# Copyright (c) 2024 Tiago Coutinho
5+
# Distributed under the GPLv3 license. See LICENSE for more info.

linuxpy/fb/device.py

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
from collections.abc import Iterable
2+
from dataclasses import dataclass
3+
from pathlib import Path
4+
5+
from linuxpy.device import BaseDevice, iter_device_files
6+
from linuxpy.ioctl import ioctl
7+
from linuxpy.types import PathLike
8+
from linuxpy.util import make_find
9+
10+
from . import raw
11+
12+
13+
@dataclass
14+
class FixScreenInfo:
15+
name: str
16+
memory_start: int
17+
memory_size: int
18+
type: raw.Type
19+
type_aux: raw.Text
20+
visual: raw.Visual
21+
x_pan_step: int
22+
y_pan_step: int
23+
y_wrap_step: int
24+
line_size: int
25+
mmap_start: int
26+
mmap_size: int
27+
acceleration: raw.Acceleration
28+
capabilities: raw.Capability
29+
30+
31+
def get_raw_fix_screen_info(fd) -> raw.fb_fix_screeninfo:
32+
return ioctl(fd, raw.IOC.GET_FSCREENINFO, raw.fb_fix_screeninfo())
33+
34+
35+
def _translate_fix_fix_screen_info(screeninfo: raw.fb_fix_screeninfo):
36+
return FixScreenInfo(
37+
screeninfo.id.decode(),
38+
screeninfo.smem_start,
39+
screeninfo.smem_len,
40+
raw.Type(screeninfo.type),
41+
raw.Text(screeninfo.type_aux),
42+
raw.Visual(screeninfo.visual),
43+
screeninfo.xpanstep,
44+
screeninfo.ypanstep,
45+
screeninfo.ywrapstep,
46+
screeninfo.line_length,
47+
screeninfo.mmio_start,
48+
screeninfo.mmio_len,
49+
raw.Acceleration(screeninfo.accel),
50+
raw.Capability(screeninfo.capabilities),
51+
)
52+
53+
54+
def get_fix_screen_info(fd) -> FixScreenInfo:
55+
"""Get fixed screen information"""
56+
info = get_raw_fix_screen_info(fd)
57+
return _translate_fix_fix_screen_info(info)
58+
59+
60+
def get_raw_var_screen_info(fd) -> raw.fb_var_screeninfo:
61+
"""Get variable screen information"""
62+
return ioctl(fd, raw.IOC.GET_VSCREENINFO, raw.fb_var_screeninfo())
63+
64+
65+
def get_raw_colormap(fd):
66+
return ioctl(fd, raw.IOC.GETCMAP, raw.fb_cmap())
67+
68+
69+
class Device(BaseDevice):
70+
"""Frame buffer device"""
71+
72+
PREFIX = "/dev/fb"
73+
74+
def get_fix_screen_info(self):
75+
"""Get fixed screen information"""
76+
return get_fix_screen_info(self)
77+
78+
def get_raw_var_screen_info(self):
79+
"""Get variable screen information"""
80+
return get_raw_var_screen_info(self)
81+
82+
83+
def iter_files(path: PathLike = "/dev") -> Iterable[Path]:
84+
"""Returns an iterator over all frame buffer files"""
85+
return iter_device_files(path=path, pattern="fb*")
86+
87+
88+
def iter_devices(path: PathLike = "/dev", **kwargs) -> Iterable[Device]:
89+
"""Returns an iterator over all frame buffer devices"""
90+
return (Device(name, **kwargs) for name in iter_files(path=path))
91+
92+
93+
find = make_find(iter_devices)

0 commit comments

Comments
 (0)