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

Add built-in swtfb client and enable musl builds on rM 2 #78

Merged
merged 40 commits into from
Dec 8, 2021
Merged
Show file tree
Hide file tree
Changes from 14 commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
d6a1e2a
Integrate swtfb client into lib (failing)
LinusCDE Nov 12, 2021
1a112db
Remove test
LinusCDE Nov 12, 2021
df614c4
Fix wrong size of mtype
LinusCDE Nov 12, 2021
5e0536c
Implement wait_for_update_completed
LinusCDE Nov 12, 2021
1828218
More debugging
LinusCDE Nov 12, 2021
cf8d742
Fix framebuffer "bus error"
LinusCDE Nov 13, 2021
9c443d4
Intercept sysv communication for debugging
LinusCDE Nov 13, 2021
874d8c6
FIX STUPID MISTAKE!
LinusCDE Nov 13, 2021
a0879a9
Remove most debugging
LinusCDE Nov 13, 2021
695f0d0
Cleanup
LinusCDE Nov 13, 2021
4905b0d
Remove debug message
LinusCDE Nov 13, 2021
1deb9e6
Add method to get current framebuffer path
LinusCDE Nov 13, 2021
359a1c3
Clarify comment
LinusCDE Nov 13, 2021
f01449e
Make clippy happy
LinusCDE Nov 13, 2021
9343082
Remove panic in drop since it's bad practice in rust
LinusCDE Nov 13, 2021
88c97d7
Remove duplicated global const
LinusCDE Nov 13, 2021
a0c0ea9
Make c compatibility of structs explicit
LinusCDE Nov 13, 2021
c7efec6
Make send_xochitl_update() non-pub
LinusCDE Nov 14, 2021
3dc5f92
Fix broken format (visual)
LinusCDE Nov 14, 2021
6f270a8
Remove duplicated fb path
LinusCDE Nov 14, 2021
8893349
Make branches easier to read
LinusCDE Nov 14, 2021
a027578
Clarify format of SEM_WAIT_TIMEOUT
LinusCDE Nov 14, 2021
0c5dbcc
Fix error caused by commit a027578 "Clarify format of SEM_WAIT_TIMEOUT"
LinusCDE Nov 14, 2021
79816f0
Fix grammar
LinusCDE Nov 16, 2021
a4e3fd5
Remove hardcoded resolution in swtfb_client
LinusCDE Nov 16, 2021
71f0f81
Fix type mismatch error
LinusCDE Nov 16, 2021
a281c97
Remove duplicate fb path
LinusCDE Nov 16, 2021
81f942f
Prevent usage of swtfb on rm 1
LinusCDE Nov 16, 2021
aa333c8
refreshing on rM1: do not log update failures as they happen too often
fenollp Nov 16, 2021
41cb7d5
duh
fenollp Nov 16, 2021
eec9f4a
ci: musl all the things!
fenollp Nov 16, 2021
0ac0bab
use libc types for platform indepence + have CI run tests on x64 as w…
fenollp Nov 16, 2021
46eb945
typo
fenollp Nov 16, 2021
d61c5e2
Merge pull request #79 from fenollp/feature/integrate_swtfb_client-rM1
LinusCDE Nov 16, 2021
c2d7c4a
typooooo
fenollp Nov 16, 2021
36719d7
cargo fmt
fenollp Nov 16, 2021
8b660be
Makefile: restore target for cargo calls
fenollp Nov 26, 2021
3bd976c
Fix timespec overflow
LinusCDE Nov 30, 2021
6a8dbe1
Remove envs
LinusCDE Dec 6, 2021
e2708f4
Fix compile error
LinusCDE Dec 6, 2021
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
5 changes: 5 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,11 @@ name = "spy"
path = "examples/spy.rs"
crate-type = ["dylib"]

[[example]]
name = "swtfb_sysv_spy"
path = "examples/swtfb_sysv_spy.rs"
crate-type = ["dylib"]

[[example]]
name = "demo"
path = "examples/demo.rs"
Expand Down
49 changes: 49 additions & 0 deletions examples/swtfb_sysv_spy.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
use libc::{c_int, c_void, key_t, msqid_ds, size_t};
use redhook::{hook, real};

use libremarkable::framebuffer::swtfb_client;

hook! {
unsafe fn msgget(key: key_t, msgflg: c_int) -> c_int => msgget_spy {
let res = real!(msgget)(key, msgflg);
eprintln!("Spy: msgget({:#x}, {:#x}) => {:#x}", key, msgflg, res);
res
}
}

hook! {
unsafe fn msgctl(msqid: c_int, cmd: c_int, buf: *mut msqid_ds) -> c_int => msgctl_spy {
let res = real!(msgctl)(msqid, cmd, buf);
eprintln!("Spy: msgctl({:#x}, {:#x}, {:?}) => {}", msqid, cmd, buf, res);
res
}
}

hook! {
unsafe fn msgsnd(msqid: c_int, msgp: *const c_void, msgsz: size_t, msgflg: c_int) -> c_int => msgsnd_spy {
let res = real!(msgsnd)(msqid, msgp, msgsz, msgflg);
eprintln!("Spy: msgsnd({:#x}, {:?}, {}, {:#x}) => {}", msqid, msgp, msgsz, msgflg, res);
if msgsz == std::mem::size_of::<swtfb_client::swtfb_update>() {
let msg = &*(msgp as *const swtfb_client::swtfb_update);
eprintln!("Spy: msgsnd: Message: swt_update.mtype: {:?}, data: ... }}", msg.mtype);
let data_str_formatted = match msg.mtype {
swtfb_client::MSG_TYPE::INIT_t => {
format!("...")
},
swtfb_client::MSG_TYPE::UPDATE_t => {
format!("{:?}", msg.data.update)
},
swtfb_client::MSG_TYPE::XO_t => {
format!("{:?}", msg.data.xochitl_update)
},
swtfb_client::MSG_TYPE::WAIT_t => {
format!("{:?}", msg.data.wait_update)
}
};
eprintln!("Spy: msgsnd: Message: swt_update.data: {} }}", data_str_formatted);
}else {
fenollp marked this conversation as resolved.
Show resolved Hide resolved
eprintln!("Spy: msgsnd: Error: Message is not sizeof(swtfb_update) (expected {}, got {})", std::mem::size_of::<swtfb_client::swtfb_update>(), msgsz)
}
res
}
}
4 changes: 3 additions & 1 deletion src/appctx.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,9 @@ impl<'a> ApplicationContext<'a> {
on_wacom: fn(&mut ApplicationContext<'_>, WacomEvent),
on_touch: fn(&mut ApplicationContext<'_>, MultitouchEvent),
) -> ApplicationContext<'static> {
let framebuffer = Box::new(core::Framebuffer::from_path("/dev/fb0"));
let framebuffer = Box::new(core::Framebuffer::from_path(
crate::device::CURRENT_DEVICE.get_framebuffer_path(),
));
let yres = framebuffer.var_screen_info.yres;
let xres = framebuffer.var_screen_info.xres;

Expand Down
16 changes: 16 additions & 0 deletions src/device.rs
Original file line number Diff line number Diff line change
Expand Up @@ -118,4 +118,20 @@ impl Device {
Model::Gen2 => "max77818_battery",
}
}

/// Path for gen 1 can be used as long as the rm2fb shim is active:
/// LD_PRELOAD="/opt/lib/librm2fb_client.so.1" <YOUR_BINARY> or
/// rm2fb-client YOUR_BINARY
/// https://github.com/ddvk/remarkable2-framebuffer/
/// If `/dev/shm/swtfb.01` is used for the framebuffer, the
/// internal swtfb_client will be used. This enables the use
/// of musl builds. But the rm2fb server must still be installed.
///
/// TODO: Use proper path (needs breaking change for FramebufferBase::from_path() !)
pub fn get_framebuffer_path(&self) -> &'static str {
match self.model {
Model::Gen1 => "/dev/fb0",
Model::Gen2 => "/dev/shm/swtfb.01",
}
}
}
93 changes: 77 additions & 16 deletions src/framebuffer/core.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ use crate::framebuffer::common::{
MXCFB_ENABLE_EPDC_ACCESS, MXCFB_SET_AUTO_UPDATE_MODE, MXCFB_SET_UPDATE_SCHEME,
};
use crate::framebuffer::screeninfo::{FixScreeninfo, VarScreeninfo};
use crate::framebuffer::swtfb_client::SwtfbClient;

/// Framebuffer struct containing the state (latest update marker etc.)
/// along with the var/fix screeninfo structs.
Expand All @@ -25,20 +26,37 @@ pub struct Framebuffer<'a> {
/// like it has been done in `Framebuffer::new(..)`.
pub var_screen_info: VarScreeninfo,
pub fix_screen_info: FixScreeninfo,
pub swtfb_client: Option<super::swtfb_client::SwtfbClient>,
}

unsafe impl<'a> Send for Framebuffer<'a> {}
unsafe impl<'a> Sync for Framebuffer<'a> {}

impl<'a> framebuffer::FramebufferBase<'a> for Framebuffer<'a> {
fn from_path(path_to_device: &str) -> Framebuffer<'_> {
let device = OpenOptions::new()
.read(true)
.write(true)
.open(path_to_device)
.unwrap();
let swtfb_client = if path_to_device == "/dev/shm/swtfb.01" {
fenollp marked this conversation as resolved.
Show resolved Hide resolved
Some(SwtfbClient::default())
} else {
None
};

let (device, mem_map) = if let Some(ref swtfb_client) = swtfb_client {
let (device, mem_map) = swtfb_client
.open_buffer()
.expect("Failed to open swtfb shared buffer");
(device, Some(mem_map))
} else {
(
OpenOptions::new()
.read(true)
.write(true)
.open(path_to_device)
.unwrap(),
None,
)
LinusCDE marked this conversation as resolved.
Show resolved Hide resolved
};

let mut var_screen_info = Framebuffer::get_var_screeninfo(&device);
let mut var_screen_info = Framebuffer::get_var_screeninfo(&device, swtfb_client.as_ref());
var_screen_info.xres = 1404;
var_screen_info.yres = 1872;
var_screen_info.rotate = 1;
Expand All @@ -55,15 +73,19 @@ impl<'a> framebuffer::FramebufferBase<'a> for Framebuffer<'a> {
var_screen_info.vmode = 0; // FB_VMODE_NONINTERLACED
var_screen_info.accel_flags = 0;

Framebuffer::put_var_screeninfo(&device, &mut var_screen_info);
Framebuffer::put_var_screeninfo(&device, swtfb_client.as_ref(), &mut var_screen_info);

let fix_screen_info = Framebuffer::get_fix_screeninfo(&device);
let fix_screen_info = Framebuffer::get_fix_screeninfo(&device, swtfb_client.as_ref());
let frame_length = (fix_screen_info.line_length * var_screen_info.yres) as usize;

let mem_map = MmapOptions::new()
.len(frame_length)
.map_raw(&device)
.expect("Unable to map provided path");
let mem_map = if let Some(mem_map) = mem_map {
mem_map
} else {
MmapOptions::new()
.len(frame_length)
.map_raw(&device)
.expect("Unable to map provided path")
};

// Load the font
let font_data = include_bytes!("../../assets/Roboto-Regular.ttf");
Expand All @@ -75,10 +97,16 @@ impl<'a> framebuffer::FramebufferBase<'a> for Framebuffer<'a> {
default_font,
var_screen_info,
fix_screen_info,
swtfb_client,
}
}

fn set_epdc_access(&mut self, state: bool) {
if self.swtfb_client.is_some() {
// Not catched in rm2fb => noop
fenollp marked this conversation as resolved.
Show resolved Hide resolved
return;
}

unsafe {
libc::ioctl(
self.device.as_raw_fd(),
Expand All @@ -92,6 +120,12 @@ impl<'a> framebuffer::FramebufferBase<'a> for Framebuffer<'a> {
}

fn set_autoupdate_mode(&mut self, mode: u32) {
if self.swtfb_client.is_some() {
// https://github.com/ddvk/remarkable2-framebuffer/blob/1e288aa9/src/client/main.cpp#L137
// Is a noop in rm2fb
return;
}

let m = mode.to_owned();
unsafe {
libc::ioctl(
Expand All @@ -103,6 +137,11 @@ impl<'a> framebuffer::FramebufferBase<'a> for Framebuffer<'a> {
}

fn set_update_scheme(&mut self, scheme: u32) {
if self.swtfb_client.is_some() {
// Not catched in rm2fb => noop
fenollp marked this conversation as resolved.
Show resolved Hide resolved
return;
}

let s = scheme.to_owned();
unsafe {
libc::ioctl(
Expand All @@ -113,26 +152,48 @@ impl<'a> framebuffer::FramebufferBase<'a> for Framebuffer<'a> {
};
}

fn get_fix_screeninfo(device: &File) -> FixScreeninfo {
fn get_fix_screeninfo(device: &File, swtfb_client: Option<&SwtfbClient>) -> FixScreeninfo {
if let Some(swtfb_client) = swtfb_client {
return swtfb_client.get_fix_screeninfo();
}

let mut info: FixScreeninfo = Default::default();
let result = unsafe { ioctl(device.as_raw_fd(), FBIOGET_FSCREENINFO, &mut info) };
assert!(result == 0, "FBIOGET_FSCREENINFO failed");
info
}

fn get_var_screeninfo(device: &File) -> VarScreeninfo {
fn get_var_screeninfo(device: &File, swtfb_client: Option<&SwtfbClient>) -> VarScreeninfo {
if let Some(swtfb_client) = swtfb_client {
return swtfb_client.get_var_screeninfo();
}

let mut info: VarScreeninfo = Default::default();
let result = unsafe { ioctl(device.as_raw_fd(), FBIOGET_VSCREENINFO, &mut info) };
assert!(result == 0, "FBIOGET_VSCREENINFO failed");
info
}

fn put_var_screeninfo(device: &File, var_screen_info: &mut VarScreeninfo) -> bool {
fn put_var_screeninfo(
device: &std::fs::File,
swtfb_client: Option<&SwtfbClient>,
var_screen_info: &mut VarScreeninfo,
) -> bool {
if swtfb_client.is_some() {
// https://github.com/ddvk/remarkable2-framebuffer/blob/1e288aa9/src/client/main.cpp#L214
// Is a noop in rm2fb
return true;
}

let result = unsafe { ioctl(device.as_raw_fd(), FBIOPUT_VSCREENINFO, var_screen_info) };
result == 0
}

fn update_var_screeninfo(&mut self) -> bool {
Self::put_var_screeninfo(&self.device, &mut self.var_screen_info)
Self::put_var_screeninfo(
&self.device,
self.swtfb_client.as_ref(),
&mut self.var_screen_info,
)
}
}
13 changes: 11 additions & 2 deletions src/framebuffer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ pub mod storage;

pub mod io;

pub mod swtfb_client;

pub use cgmath;

pub trait FramebufferIO {
Expand Down Expand Up @@ -119,14 +121,21 @@ pub trait FramebufferBase<'a> {
/// Toggles update scheme
fn set_update_scheme(&mut self, scheme: u32);
/// Creates a FixScreeninfo struct and fills it using ioctl
fn get_fix_screeninfo(device: &std::fs::File) -> screeninfo::FixScreeninfo;
fn get_fix_screeninfo(
device: &std::fs::File,
swtfb_client: Option<&swtfb_client::SwtfbClient>,
) -> screeninfo::FixScreeninfo;
/// Creates a VarScreeninfo struct and fills it using ioctl
fn get_var_screeninfo(device: &std::fs::File) -> screeninfo::VarScreeninfo;
fn get_var_screeninfo(
device: &std::fs::File,
swtfb_client: Option<&swtfb_client::SwtfbClient>,
) -> screeninfo::VarScreeninfo;
/// Makes the proper ioctl call to set the VarScreenInfo.
/// You must first update the contents of self.var_screen_info
/// and then call this function.
fn put_var_screeninfo(
device: &std::fs::File,
swtfb_client: Option<&swtfb_client::SwtfbClient>,
var_screen_info: &mut screeninfo::VarScreeninfo,
) -> bool;

Expand Down
4 changes: 2 additions & 2 deletions src/framebuffer/mxcfb.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ impl ::std::default::Default for mxcfb_update_marker_data {
}
}

#[derive(Debug)]
#[derive(Debug, Clone, Copy)]
#[repr(C)]
pub struct mxcfb_alt_buffer_data {
pub phys_addr: u32,
Expand All @@ -48,7 +48,7 @@ impl ::std::default::Default for mxcfb_alt_buffer_data {
}
}

#[derive(Debug)]
#[derive(Debug, Clone, Copy)]
#[repr(C)]
pub struct mxcfb_update_data {
pub update_region: mxcfb_rect,
Expand Down
Loading