Skip to content
Open
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
19 changes: 18 additions & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,10 @@ use libc::ioctl;
use std::error::Error;
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you give an example where you would want to read the frame? You have previously written it yourself, so why not keep this data stored somewhere?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have made my own display that is using SPI and I want to read the framebuffer and push it over SPI to the display. In my case the OS/applications are writing to the framebuffer and I'm just pushing it to the display.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I want to make screenshot of the framebuffer (drawn by an another application), so I need this logic too.

use std::fmt;
use std::fs::{File, OpenOptions};
use std::io::Write;
use std::io::{Read, Write};
use std::os::unix::io::AsRawFd;
use std::path::Path;
use std::ops::Index;

use memmap::{Mmap, Protection};

Expand Down Expand Up @@ -201,6 +202,13 @@ impl Framebuffer {
.unwrap();
}

///Reads a frame from the Framebuffer.
pub fn read_frame(&self, frame: &mut Vec<u8>) {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using &mut Vec as parameter requires the user of this function to use a Vec, which will allocate the required memory to fit the entire frame. This means that after every read the user will have to call .clear() on the vector before being able to use the same vector for the next read. Also it would not be possible to only read a small part of the frame.

Wouldn't it be better to change it to:

pub fn read_frame(&self, frame: &mut [u8]) {

and then use .read_exact(frame) later on?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For reading parts of the framebuffer I would suggest we implement Index<Range> so that people can read it any way they want, e.g. let v = fb[4096..8192].to_vec();.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For reading the entire frame I wanted to use Vec to not have to deal with the size(preallocating memory in case of an array)... but I guess we could also solve this in terms of Index<Range> => let v = fb[..].to_vec(), let slice = fb[..], and maybe writing too using IndexMut.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This would give the user the choice to do whatever they want with the returned slice

unsafe { self.frame.as_slice() }
.read_to_end(frame)
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

.read_exact(frame)

.unwrap();
}

///Creates a FixScreeninfo struct and fills it using ioctl.
pub fn get_fix_screeninfo(device: &File) -> Result<FixScreeninfo, FramebufferError> {
let mut info: FixScreeninfo = Default::default();
Expand Down Expand Up @@ -252,3 +260,12 @@ impl Framebuffer {
}
}
}

impl Index<usize> for Framebuffer {
type Output = u8;

fn index(&self, index: usize) -> &u8 {
unsafe { self.frame.as_slice() }
.index(index)
}
}