pub struct Framebuffer { /* private fields */ }
Expand description
Represents a single framebuffer device
Example usage:
// Instead of hardcoding the path, you could also use `Framebuffer::list()`
// to find paths to available devices.
let fb = linuxfb::Framebuffer::new("/dev/fb0").unwrap();
println!("Size in pixels: {:?}", fb.get_size());
println!("Bytes per pixel: {:?}", fb.get_bytes_per_pixel());
println!("Physical size in mm: {:?}", fb.get_physical_size());
// Map the framebuffer into memory, so we can write to it:
let mut data = fb.map().unwrap();
// Make everything black:
for i in 0..data.len() {
data[i] = 0;
}
// Make everything white:
for i in 0..data.len() {
data[i] = 0xFF;
}
Implementations§
Source§impl Framebuffer
impl Framebuffer
Sourcepub fn list() -> Result<Vec<PathBuf>>
pub fn list() -> Result<Vec<PathBuf>>
Returns a list of paths to device nodes, which are handled by the “fb” driver.
Relies on /proc/devices
to discover the major number of the device,
and on the device nodes to exist in /dev
.
Example, assuming there is one framebuffer named fb0
:
let devices = linuxfb::Framebuffer::list().unwrap();
println!("Devices: {:?}", devices);
// prints:
// Devices: ["/dev/fb0"]
Sourcepub fn new(path: impl AsRef<Path>) -> Result<Framebuffer, Error>
pub fn new(path: impl AsRef<Path>) -> Result<Framebuffer, Error>
Attempts to open the framebuffer device at the given path
, and query it’s properties.
This operation can fail for one of these reasons:
- The device cannot be opened. In this case the error has
ErrorKind::Io
, anderror.io
is set. This can happen for example when given apath
to a file that does not exist, or when the user lacks permission to open the device. - Any of the
ioctl
calls querying device properties fails. In this case the error hasErrorKind::Fb
, anderror.fb
is set. Useerror.fb.errno
anderror.fb.message
to find out what failed. This can happen for example when the givenpath
does not refer to a framebuffer device, or when the driver encounters an error.
Sourcepub fn map(&self) -> Result<MmapMut, Error>
pub fn map(&self) -> Result<MmapMut, Error>
Maps the framebuffer device into memory.
Returns a memory mapped region, which can be used to modify screen contents.
The size of the region is chosen based on the current virtual size of the display, and the bytes per pixel. Therefore this method should be called after configuring the device.
Since the returned memmap::MmapMut
object implements the Drop
trait, the region is
automatically unmapped, when the returned map goes out of scope.
Note that changes to the data directly appear on screen, so you will most likely see flicker, if you write to a visible region.
To avoid this, you can set the virtual size to be twice as large as the actual size
of the display, then only draw to the part of that region that’s currently not shown.
Once done drawing, use set_offset
to make the drawn region appear on screen.
See the double
module for a convenient wrapper that does exactly that.
Sourcepub fn get_bytes_per_pixel(&self) -> u32
pub fn get_bytes_per_pixel(&self) -> u32
Returns the number of bytes used to represent one pixel.
This can be used to narrow down the format.
Sourcepub fn set_bytes_per_pixel(&mut self, value: u32) -> Result<(), Error>
pub fn set_bytes_per_pixel(&mut self, value: u32) -> Result<(), Error>
Sets the number of bytes per pixel.
This modifies the bits_per_pixel
attribute of the underlying
device.
The actual consequence of this action depends on the driver.
For at least some drivers, setting a different number of pixels changes the color mode.
Make sure to use get_bytes_per_pixel
afterwards to check if
the value was changed.
Also use get_pixel_layout
, to find out more about the format
being used.
This operation fails, when any of the underlying ioctl
calls fail.
After a failure, the device may be in an undefined state.
Sourcepub fn get_pixel_layout(&self) -> PixelLayout
pub fn get_pixel_layout(&self) -> PixelLayout
Returns the pixel layout, as reported by the driver.
This value may change, after calling set_bytes_per_pixel
.
Some examples:
16-bit, RGB565, meaning rrrrrggggggrrrrr
, with LSB right, aka HighColor:
PixelLayout {
red: PixelLayoutChannel { offset: 11, length: 5, msb_right: false },
green: PixelLayoutChannel { offset: 5, length: 6, msb_right: false },
blue: PixelLayoutChannel { offset: 0, length: 5, msb_right: false },
alpha: PixelLayoutChannel { offset: 0, length: 0, msb_right: false },
};
32-bit, ABGR, meaning aaaaaaaabbbbbbbbbggggggggrrrrrrrr
, with LSB right:
PixelLayout {
red: PixelLayoutChannel { offset: 0, length: 8, msb_right: false },
green: PixelLayoutChannel { offset: 8, length: 8, msb_right: false },
blue: PixelLayoutChannel { offset: 16, length: 8, msb_right: false },
alpha: PixelLayoutChannel { offset: 24, length: 8, msb_right: false },
};
32-bit, RGBA, meaning: rrrrrrrrggggggggbbbbbbbbaaaaaaaa
, with LSB right:
PixelLayout {
red: PixelLayoutChannel { offset: 24, length: 8, msb_right: false },
green: PixelLayoutChannel { offset: 16, length: 8, msb_right: false },
blue: PixelLayoutChannel { offset: 8, length: 8, msb_right: false },
alpha: PixelLayoutChannel { offset: 0, length: 8, msb_right: false },
};
Note that on most devices, setting alpha data does not have any effect, even when an alpha channel is specified in the layout.
Sourcepub fn get_virtual_size(&self) -> (u32, u32)
pub fn get_virtual_size(&self) -> (u32, u32)
Returns the virtual size of the display, in pixels.
See set_virtual_size
for details.
Sourcepub fn set_virtual_size(&mut self, w: u32, h: u32) -> Result<(), Error>
pub fn set_virtual_size(&mut self, w: u32, h: u32) -> Result<(), Error>
Sets the virtual size of the display.
The virtual size defines the area where pixel data can be written to.
It should always be equal to or larger than the values returned from
get_size
.
After setting the virtual size, you can use set_offset
to control what region of the “virtual display” is actually shown on screen.
This operation fails, when any of the underlying ioctl
calls fail.
After a failure, the device may be in an undefined state.
Sourcepub fn get_offset(&self) -> (u32, u32)
pub fn get_offset(&self) -> (u32, u32)
Returns the current xoffset
and yoffset
of the underlying device.
Sourcepub fn set_offset(&mut self, x: u32, y: u32) -> Result<(), Error>
pub fn set_offset(&mut self, x: u32, y: u32) -> Result<(), Error>
Sets the xoffset
and yoffset
of the underlying device.
This can be used to pan the display.
This operation fails, when any of the underlying ioctl
calls fail.
After a failure, the device may be in an undefined state.
Sourcepub fn get_physical_size(&self) -> (u32, u32)
pub fn get_physical_size(&self) -> (u32, u32)
Returns the physical size of the device in millimeters, as reported by the driver.
Sourcepub fn blank(&self, level: BlankingLevel) -> Result<(), Error>
pub fn blank(&self, level: BlankingLevel) -> Result<(), Error>
Sets the blanking level. This can be used to turn off the screen.
See BlankingLevel
for a list of available options, and their
meaning.
Brief example:
use linuxfb::{Framebuffer, BlankingLevel};
let mut fb = Framebuffer::new("/dev/fb0").unwrap();
// Turn off the screen:
fb.blank(BlankingLevel::Powerdown).unwrap();
// Turn the screen back on:
fb.blank(BlankingLevel::Unblank).unwrap();
This operation fails, when the underlying ioctl
call fails.
At least some drivers produce an error, when the new blanking mode does not actually change the state of the device.
For example:
fb.blank(BlankingLevel::Powerdown).unwrap(); // this call goes through fine
fb.blank(BlankingLevel::Powerdown).unwrap(); // this call fails with EBUSY
Since there is no way to determine beforehand what the current state of the screen is, you should always expect that these calls may fail, and continue normally (possibly with a warning).