Skip to content

Commit

Permalink
Fix the framebuffer rotation on two devices
Browse files Browse the repository at this point in the history
It would seem that I was misguided by KSM's Plato launch script: the
value that we must write at startup is 3, even for the devices that
exhibit a discrepancy between the written and the read values.

Also, the FBIOPUT_VSCREENINFO ioctl call might fail on the Aura H₂O.
Hence we must check that the read value changes after the call.

The mirroring pattern scheme was generalized to handle the Aura H₂O
Edition 2 Version 2: on this device, an increase of the written rotation
value results in a counter-clockwise rotation of the framebuffer.
  • Loading branch information
baskerville committed Dec 11, 2018
1 parent 2513017 commit 0588b1b
Show file tree
Hide file tree
Showing 5 changed files with 47 additions and 31 deletions.
24 changes: 19 additions & 5 deletions src/device.rs
Expand Up @@ -80,21 +80,35 @@ impl Device {
}
}

pub fn mirroring_pivot(&self) -> i8 {
pub fn should_mirror_axes(&self, rotation: i8) -> (bool, bool) {
let (mxy, dir) = self.mirroring_scheme();
let mx = (4 + (mxy + dir)) % 4;
let my = (4 + (mxy - dir)) % 4;
let mirror_x = mxy == rotation || mx == rotation;
let mirror_y = mxy == rotation || my == rotation;
(mirror_x, mirror_y)
}

// Returns the center and direction of the mirroring pattern.
pub fn mirroring_scheme(&self) -> (i8, i8) {
let model_number = env::var("MODEL_NUMBER").unwrap_or_default();
match self.model {
Model::AuraH2OEdition2 if model_number == "374" => 1,
_ => 2,
Model::AuraH2OEdition2 if model_number == "374" => (1, 1),
Model::AuraH2OEdition2 if model_number == "378" => (0, -1),
_ => (2, 1),
}
}

pub fn startup_rotation(&self) -> i8 {
self.transformed_rotation(3)
3
}

pub fn transformed_rotation(&self, n: i8) -> i8 {
let model_number = env::var("MODEL_NUMBER").unwrap_or_default();
match self.model {
Model::AuraHD | Model::AuraH2O | Model::AuraH2OEdition2 => n ^ 2,
Model::AuraHD | Model::AuraH2O => n ^ 2,
Model::AuraH2OEdition2 if model_number == "374" => n ^ 2,
Model::AuraH2OEdition2 if model_number == "378" => (4 - n) % 4,
Model::Forma => (4 - n) % 4,
_ => n,
}
Expand Down
27 changes: 18 additions & 9 deletions src/framebuffer/kobo.rs
Expand Up @@ -196,24 +196,33 @@ impl Framebuffer for KoboFramebuffer {
Ok(())
}

#[inline]
fn rotation(&self) -> i8 {
self.var_info.rotate as i8
}

fn set_rotation(&mut self, n: i8) -> Result<(u32, u32), Error> {
self.var_info.rotate = n as u32;
let result = unsafe {
libc::ioctl(self.file.as_raw_fd(), FBIOPUT_VSCREENINFO, &mut self.var_info)
};
match result {
-1 => Err(Error::from(io::Error::last_os_error())
.context("Can't set variable screen info.").into()),
_ => {
let read_rotation = self.rotation();
let mut remaining_tries = 3;

while read_rotation == self.rotation() && remaining_tries > 0 {
self.var_info.rotate = n as u32;
let result = unsafe {
libc::ioctl(self.file.as_raw_fd(), FBIOPUT_VSCREENINFO, &mut self.var_info)
};
if result == -1 {
return Err(Error::from(io::Error::last_os_error())
.context("Can't set variable screen info.").into());
} else {
self.fix_info = fix_screen_info(&self.file)?;
self.frame_size = (self.var_info.yres * self.fix_info.line_length) as libc::size_t;
Ok((self.var_info.xres, self.var_info.yres))
}
remaining_tries -= 1;
}

println!("Framebuffer rotation: {} -> {}.", n, self.rotation());

Ok((self.var_info.xres, self.var_info.yres))
}


Expand Down
13 changes: 6 additions & 7 deletions src/input.rs
Expand Up @@ -282,9 +282,7 @@ pub fn parse_device_events(rx: &Receiver<InputEvent>, ty: &Sender<DeviceEvent>,
TouchProto::MultiB => MULTI_TOUCH_CODES_B,
};

let mirroring_pivot = CURRENT_DEVICE.mirroring_pivot();
let mut mirrored_x = mirroring_pivot == rotation || mirroring_pivot + 1 == rotation;
let mut mirrored_y = mirroring_pivot == rotation || mirroring_pivot - 1 == rotation;
let (mut mirror_x, mut mirror_y) = CURRENT_DEVICE.should_mirror_axes(rotation);
if rotation % 2 == 1 {
mem::swap(&mut tc.x, &mut tc.y);
}
Expand All @@ -297,13 +295,13 @@ pub fn parse_device_events(rx: &Receiver<InputEvent>, ty: &Sender<DeviceEvent>,
packet_ids.insert(id);
}
} else if evt.code == tc.x {
position.x = if mirrored_x {
position.x = if mirror_x {
dims.0 as i32 - 1 - evt.value
} else {
evt.value
};
} else if evt.code == tc.y {
position.y = if mirrored_y {
position.y = if mirror_y {
dims.1 as i32 - 1 - evt.value
} else {
evt.value
Expand Down Expand Up @@ -370,8 +368,9 @@ pub fn parse_device_events(rx: &Receiver<InputEvent>, ty: &Sender<DeviceEvent>,
mem::swap(&mut dims.0, &mut dims.1);
}
rotation = next_rotation;
mirrored_x = mirroring_pivot == rotation || mirroring_pivot + 1 == rotation;
mirrored_y = mirroring_pivot == rotation || mirroring_pivot - 1 == rotation;
let should_mirror = CURRENT_DEVICE.should_mirror_axes(rotation);
mirror_x = should_mirror.0;
mirror_y = should_mirror.1;
}
} else {
ty.send(DeviceEvent::Button {
Expand Down
7 changes: 2 additions & 5 deletions src/view/home/mod.rs
Expand Up @@ -1070,11 +1070,8 @@ impl View for Home {
fn handle_event(&mut self, evt: &Event, hub: &Hub, _bus: &mut Bus, context: &mut Context) -> bool {
match *evt {
Event::Gesture(GestureEvent::Rotate { quarter_turns, .. }) if quarter_turns != 0 => {
let mut n = context.display.rotation - quarter_turns;
if n < 0 {
n += 4;
}
n = n % 4;
let (_, dir) = CURRENT_DEVICE.mirroring_scheme();
let n = (4 + (context.display.rotation - dir * quarter_turns)) % 4;
hub.send(Event::Select(EntryId::Rotate(n))).unwrap();
true
},
Expand Down
7 changes: 2 additions & 5 deletions src/view/reader/mod.rs
Expand Up @@ -1693,11 +1693,8 @@ impl View for Reader {
fn handle_event(&mut self, evt: &Event, hub: &Hub, _bus: &mut Bus, context: &mut Context) -> bool {
match *evt {
Event::Gesture(GestureEvent::Rotate { quarter_turns, .. }) if quarter_turns != 0 => {
let mut n = context.display.rotation - quarter_turns;
if n < 0 {
n += 4;
}
n = n % 4;
let (_, dir) = CURRENT_DEVICE.mirroring_scheme();
let n = (4 + (context.display.rotation - dir * quarter_turns)) % 4;
hub.send(Event::Select(EntryId::Rotate(n))).unwrap();
true
},
Expand Down

0 comments on commit 0588b1b

Please sign in to comment.