Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions docs/api/fb.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# 📺 Frame buffer

::: linuxpy.fb.device
28 changes: 28 additions & 0 deletions docs/user_guide/fb.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# 📺 Frame buffer

Human friendly interface to linux frame buffer.

Without further ado:

<div class="termy" data-ty-macos>
<span data-ty="input" data-ty-prompt="$">python</span>
<span data-ty="input" data-ty-prompt=">>>">from linuxpy.fb.device import find</span>
<span data-ty="input" data-ty-prompt=">>>">with find() as fb:</span>
<span data-ty="input" data-ty-prompt="..."> print(fb.get_fix_screen_info())</span>
<span data-ty>
FixScreenInfo(name='i915drmfb',
memory_start=0,
memory_size=33177600,
type=Type.PACKED_PIXELS: 0,
type_aux=Text.MDA: 0,
visual=Visual.TRUECOLOR: 2,
x_pan_step=1,
y_pan_step=1,
y_wrap_step=0,
line_size=15360,
mmap_start=0,
mmap_size=0,
acceleration=Acceleration.NONE: 0,
capabilities=Capability: 0)
</span>
</div>
80 changes: 80 additions & 0 deletions linuxpy/codegen/fb.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
#
# This file is part of the linuxpy project
#
# Copyright (c) 2024 Tiago Coutinho
# Distributed under the GPLv3 license. See LICENSE for more info.

import pathlib

from linuxpy.codegen.base import CEnum, run

HEADERS = [
"/usr/include/linux/fb.h",
]


TEMPLATE = """\
#
# This file is part of the linuxpy project
#
# Copyright (c) 2024 Tiago Coutinho
# Distributed under the GPLv3 license. See LICENSE for more info.

# This file has been generated by {name}
# Date: {date}
# System: {system}
# Release: {release}
# Version: {version}

import enum

from linuxpy.ioctl import IOR as _IOR, IOW as _IOW, IOWR as _IOWR
from linuxpy.ctypes import u8, u16, u32, cuint, cint, cchar, culong
from linuxpy.ctypes import Struct, Union, POINTER, cvoidp


{enums_body}


{structs_body}


{iocs_body}
"""


def no_mask(key, value):
return not key.endswith("_MASK")


# macros from #define statements
MACRO_ENUMS = [
CEnum("Type", "FB_TYPE_"),
CEnum("Text", "FB_AUX_TEXT_", filter=no_mask),
CEnum("VGAPlanes", "FB_AUX_VGA_PLANES_"),
CEnum("Visual", "FB_VISUAL_"),
CEnum("Acceleration", "FB_ACCEL_"),
CEnum("Activate", ["FB_ACTIVATE_", "FB_CHANGE_"], klass="IntFlag", filter=no_mask),
CEnum("Sync", "FB_SYNC_", klass="IntFlag"),
CEnum("VarMode", "FB_VMODE_", klass="IntFlag", filter=no_mask),
CEnum("Rotation", "FB_ROTATE_"),
CEnum("VESABlank", "VESA_"),
CEnum("VarBlank", "FB_VBLANK_", klass="IntFlag"),
CEnum("Cursor", "FB_CUR_", klass="IntFlag"),
CEnum("Capability", "FB_CAP_", klass="IntFlag"),
CEnum("IOC", "FBIO"),
]


this_dir = pathlib.Path(__file__).parent


def main(output=this_dir.parent / "fb" / "raw.py"):
import logging

logging.basicConfig(level="DEBUG")
run(__name__, HEADERS, TEMPLATE, MACRO_ENUMS, output=output)


if __name__ == "__main__":
main()
5 changes: 5 additions & 0 deletions linuxpy/fb/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#
# This file is part of the linuxpy project
#
# Copyright (c) 2024 Tiago Coutinho
# Distributed under the GPLv3 license. See LICENSE for more info.
93 changes: 93 additions & 0 deletions linuxpy/fb/device.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
from collections.abc import Iterable
from dataclasses import dataclass
from pathlib import Path

from linuxpy.device import BaseDevice, iter_device_files
from linuxpy.ioctl import ioctl
from linuxpy.types import PathLike
from linuxpy.util import make_find

from . import raw


@dataclass
class FixScreenInfo:
name: str
memory_start: int
memory_size: int
type: raw.Type
type_aux: raw.Text
visual: raw.Visual
x_pan_step: int
y_pan_step: int
y_wrap_step: int
line_size: int
mmap_start: int
mmap_size: int
acceleration: raw.Acceleration
capabilities: raw.Capability


def get_raw_fix_screen_info(fd) -> raw.fb_fix_screeninfo:
return ioctl(fd, raw.IOC.GET_FSCREENINFO, raw.fb_fix_screeninfo())


def _translate_fix_fix_screen_info(screeninfo: raw.fb_fix_screeninfo):
return FixScreenInfo(
screeninfo.id.decode(),
screeninfo.smem_start,
screeninfo.smem_len,
raw.Type(screeninfo.type),
raw.Text(screeninfo.type_aux),
raw.Visual(screeninfo.visual),
screeninfo.xpanstep,
screeninfo.ypanstep,
screeninfo.ywrapstep,
screeninfo.line_length,
screeninfo.mmio_start,
screeninfo.mmio_len,
raw.Acceleration(screeninfo.accel),
raw.Capability(screeninfo.capabilities),
)


def get_fix_screen_info(fd) -> FixScreenInfo:
"""Get fixed screen information"""
info = get_raw_fix_screen_info(fd)
return _translate_fix_fix_screen_info(info)


def get_raw_var_screen_info(fd) -> raw.fb_var_screeninfo:
"""Get variable screen information"""
return ioctl(fd, raw.IOC.GET_VSCREENINFO, raw.fb_var_screeninfo())


def get_raw_colormap(fd):
return ioctl(fd, raw.IOC.GETCMAP, raw.fb_cmap())


class Device(BaseDevice):
"""Frame buffer device"""

PREFIX = "/dev/fb"

def get_fix_screen_info(self):
"""Get fixed screen information"""
return get_fix_screen_info(self)

def get_raw_var_screen_info(self):
"""Get variable screen information"""
return get_raw_var_screen_info(self)


def iter_files(path: PathLike = "/dev") -> Iterable[Path]:
"""Returns an iterator over all frame buffer files"""
return iter_device_files(path=path, pattern="fb*")


def iter_devices(path: PathLike = "/dev", **kwargs) -> Iterable[Device]:
"""Returns an iterator over all frame buffer devices"""
return (Device(name, **kwargs) for name in iter_files(path=path))


find = make_find(iter_devices)
Loading