Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FB interface fixup #93

Merged
merged 5 commits into from
Jan 17, 2022
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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion examples/live.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use libremarkable::framebuffer::common::{DISPLAYHEIGHT, DISPLAYWIDTH};
/// An HTTP server that listens on :8000 and responds to all incoming requests
/// with the full contents of the framebuffer properly exported as a JPEG.
fn main() {
let fb = Framebuffer::from_path("/dev/fb0");
let fb = Framebuffer::new();
println!("libremarkable Framebuffer device initialized");

let server = Server::http("0.0.0.0:8000").unwrap();
Expand Down
4 changes: 2 additions & 2 deletions examples/screenshot.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
use image::{DynamicImage, ImageOutputFormat};
use libremarkable::device::CURRENT_DEVICE;

use libremarkable::framebuffer::common::*;
use libremarkable::framebuffer::core::*;
use libremarkable::framebuffer::*;
use libremarkable::image::RgbImage;
use std::fs::OpenOptions;

fn main() {
let fb = Framebuffer::from_path(CURRENT_DEVICE.get_framebuffer_path());
let fb = Framebuffer::new();
let width = DISPLAYWIDTH as u32;
let height = DISPLAYHEIGHT as u32;
let contents = fb
Expand Down
20 changes: 9 additions & 11 deletions src/framebuffer/core.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use memmap2::{MmapOptions, MmapRaw};

use std::fs::{File, OpenOptions};
use std::os::unix::io::AsRawFd;
use std::path::Path;
use std::sync::atomic::AtomicU32;

use crate::device;
Expand Down Expand Up @@ -49,7 +50,7 @@ impl Framebuffer {
let device = &*device::CURRENT_DEVICE;
match device.model {
Model::Gen1 => Framebuffer::device(device.get_framebuffer_path()),
Model::Gen2 => Framebuffer::rm2fb(),
Model::Gen2 => Framebuffer::rm2fb(device.get_framebuffer_path()),
}
}

Expand All @@ -59,7 +60,7 @@ impl Framebuffer {
/// This matches the pre-0.6.0 behaviour, and relies on the rm2fb client
/// shim on RM2. `new` is generally preferred, though existing apps may
/// wish to use this method to avoid some risk of changing behaviour.
pub fn device(path: &str) -> Framebuffer {
pub fn device(path: impl AsRef<Path>) -> Framebuffer {
let device = OpenOptions::new()
.read(true)
.write(true)
Expand All @@ -73,16 +74,16 @@ impl Framebuffer {
///
/// This will not work at all on RM1; consider using `new` to autodetect
/// the right interface for the current hardware.
pub fn rm2fb() -> Framebuffer {
Framebuffer::build(FramebufferUpdate::Swtfb(SwtfbClient::default()))
pub fn rm2fb(path: impl AsRef<Path>) -> Framebuffer {
Framebuffer::build(FramebufferUpdate::Swtfb(SwtfbClient::new(path)))
}

#[deprecated = "Use `new` to autodetect the right update method based on your device version, or `device` or `rm2fb` to choose one explicitly."]
pub fn from_path(path_to_device: &str) -> Framebuffer {
if path_to_device == crate::device::Model::Gen2.framebuffer_path() {
Framebuffer::device(path_to_device)
} else {
Framebuffer::rm2fb()
Framebuffer::rm2fb(path_to_device)
}
}

Expand Down Expand Up @@ -122,12 +123,9 @@ impl Framebuffer {
.len(frame_length)
.map_raw(device)
.expect("Unable to map provided path"),
FramebufferUpdate::Swtfb(swtfb_client) => {
let (_, mem_map) = swtfb_client
.open_buffer()
.expect("Failed to open swtfb shared buffer");
mem_map
}
FramebufferUpdate::Swtfb(swtfb_client) => swtfb_client
.open_buffer()
.expect("Failed to open swtfb shared buffer"),
};

Framebuffer {
Expand Down
22 changes: 13 additions & 9 deletions src/framebuffer/swtfb_client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,10 @@ use crate::device;
use crate::framebuffer::screeninfo::{FixScreeninfo, VarScreeninfo};
use memmap2::{MmapOptions, MmapRaw};
use std::ffi::{c_void, CStr, CString};
use std::fs::{File, OpenOptions};
use std::fs::OpenOptions;
use std::io::Error as IoError;
use std::os::unix::prelude::AsRawFd;
use std::path::{Path, PathBuf};
use std::{env, mem, ptr};

const SWTFB_MESSAGE_QUEUE_ID: i32 = 0x2257c;
Expand Down Expand Up @@ -76,11 +77,18 @@ pub union swtfb_update_data {

pub struct SwtfbClient {
msqid: i32,
path: PathBuf,
do_wait_ioctl: bool,
}

impl Default for SwtfbClient {
fn default() -> Self {
Self::new(device::Model::Gen2.framebuffer_path())
}
}

impl SwtfbClient {
pub fn new(path: impl AsRef<Path>) -> SwtfbClient {
assert!(
device::CURRENT_DEVICE.model == device::Model::Gen2,
"SWTFB is not supported on devices other than rM 2"
Expand All @@ -96,23 +104,19 @@ impl Default for SwtfbClient {

Self {
msqid,
path: PathBuf::from(path.as_ref()),
do_wait_ioctl: env::var("RM2FB_NO_WAIT_IOCTL").is_err(),
}
}
}

impl SwtfbClient {
pub fn open_buffer(&self) -> Result<(File, MmapRaw), IoError> {
let device = OpenOptions::new()
.read(true)
.write(true)
.open(crate::device::Model::Gen2.framebuffer_path())?;
pub fn open_buffer(&self) -> Result<MmapRaw, IoError> {
let device = OpenOptions::new().read(true).write(true).open(&self.path)?;
let ret = unsafe { libc::ftruncate(device.as_raw_fd(), BUF_SIZE as libc::off_t) };
if ret < 0 {
return Err(IoError::last_os_error());
}
let mem_map = MmapOptions::new().len(BUF_SIZE as usize).map_raw(&device)?;
Ok((device, mem_map))
Ok(mem_map)
}

pub fn send(&self, update: &swtfb_update) -> bool {
Expand Down