Skip to content
This repository has been archived by the owner on Aug 3, 2024. It is now read-only.

Commit

Permalink
Merge pull request #252 from swaywm/wlroots-0.3
Browse files Browse the repository at this point in the history
wlroots 0.3
  • Loading branch information
Timidger authored Feb 16, 2019
2 parents cdc4c19 + 1f26f6c commit f9cdf5e
Show file tree
Hide file tree
Showing 12 changed files with 283 additions and 30 deletions.
1 change: 1 addition & 0 deletions src/events/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ pub mod xdg_shell_events;
pub mod tablet_tool_events;
pub mod touch_events;
pub mod seat_events;
pub mod switch_events;
pub mod tablet_pad_events;
pub mod xwayland_events;

Expand Down
34 changes: 34 additions & 0 deletions src/events/switch_events.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
use wlroots_sys::{wlr_event_switch_toggle, wlr_switch_type, wlr_switch_state};

use input;

pub struct Toggle {
event: *mut wlr_event_switch_toggle,
device: input::Device
}

impl Toggle {
pub(crate) unsafe fn from_ptr(event: *mut wlr_event_switch_toggle) -> Self {
Toggle { event,
device: input::Device::from_ptr((*event).device) }
}

pub fn device(&self) -> &input::Device {
&self.device
}

/// Get the timestamp of this event.
pub fn time_msec(&self) -> u32 {
unsafe { (*self.event).time_msec }
}

/// Get the type of switch this is.
pub fn switch_type(&self) -> wlr_switch_type {
unsafe { (*self.event).switch_type }
}

/// Get the state the switch is in.
pub fn switch_state(&self) -> wlr_switch_state {
unsafe { (*self.event).switch_state }
}
}
28 changes: 27 additions & 1 deletion src/manager/input_manager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ use {compositor,
input::{self,
keyboard::{self, Keyboard, KeyboardWrapper},
pointer::{self, Pointer, PointerWrapper},
switch::{self, Switch, SwitchWrapper},
tablet_pad::{self, TabletPad, TabletPadWrapper},
tablet_tool::{self, TabletTool, TabletToolWrapper},
touch::{self, Touch, TouchWrapper}},
Expand Down Expand Up @@ -70,6 +71,10 @@ pub type TabletPadAdded = fn (compositor_handle: compositor::Handle,
tablet_pad_handle: tablet_pad::Handle)
-> Option<Box<tablet_pad::Handler>>;

pub type SwitchAdded = fn (compositor_handle: compositor::Handle,
switch_handle: switch::Handle)
-> Option<Box<switch::Handler>>;

wayland_listener_static! {
static mut MANAGER;
(Manager, Builder): [
Expand All @@ -83,7 +88,8 @@ wayland_listener_static! {
pointer_added: PointerAdded,
touch_added: TouchAdded,
tablet_tool_added: TabletToolAdded,
tablet_pad_added: TabletPadAdded
tablet_pad_added: TabletPadAdded,
switch_added: SwitchAdded
]
(InputAdded, add_listener, input_added) => (add_notify, input_added):
|manager: &mut Manager, data: *mut libc::c_void,| unsafe {
Expand Down Expand Up @@ -229,6 +235,26 @@ wayland_listener_static! {
(*data).data = Box::into_raw(tablet_pad) as _;
}
}
WLR_INPUT_DEVICE_SWITCH => {
let switch = match Switch::new_from_input_device(data) {
Some(dev) => dev,
None => {
wlr_log!(WLR_ERROR, "Device {:#?} was not a switch", dev);
abort();
}
};
let switch_handle = switch.weak_reference();
let res = manager.switch_added.and_then(|f| f(compositor.clone(), switch_handle));
if let Some(switch_handler) = res {
let mut switch = SwitchWrapper::new((switch, switch_handler));
let switch_ptr = &mut (*dev.dev_union().lid_switch);
wl_signal_add(&mut switch_ptr.events.toggle as *mut _ as _,
switch.on_toggle_listener() as *mut _ as _);
wl_signal_add(&mut (*dev.as_ptr()).events.destroy as *mut _ as _,
switch.on_destroy_listener() as _);
(*data).data = Box::into_raw(switch) as _;
}
}
}
manager.input_added.map(|f| f(compositor, &mut dev))
}));
Expand Down
1 change: 1 addition & 0 deletions src/manager/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ pub(crate) mod input_manager;
pub(crate) mod output_manager;
pub(crate) mod keyboard_handler;
pub(crate) mod pointer_handler;
pub(crate) mod switch_handler;
pub(crate) mod touch_handler;
pub(crate) mod output_handler;
pub(crate) mod xdg_shell_v6_manager;
Expand Down
58 changes: 58 additions & 0 deletions src/manager/switch_handler.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
//! Handler for lid switches

use libc;
use wayland_sys::server::WAYLAND_SERVER_HANDLE;
use wlroots_sys::{wlr_input_device, wlr_event_switch_toggle};

use {compositor,
input::switch::{self, Switch},
utils::Handleable};


#[allow(unused_variables)]
pub trait Handler {
/// Callback that is triggered when the switch moves.
fn on_toggle(&mut self,
compositor_handle: compositor::Handle,
switch_handle: switch::Handle,
event: &switch::event::Toggle) {}

/// Callback that is triggered when the switch is destroyed.
fn destroyed(&mut self,
compositor_handle: compositor::Handle,
switch_handle: switch::Handle) {}
}

wayland_listener!(pub(crate) SwitchWrapper, (Switch, Box<Handler>), [
on_destroy_listener => on_destroy_notify: |this: &mut SwitchWrapper, data: *mut libc::c_void,|
unsafe {
let input_device_ptr = data as *mut wlr_input_device;
{
let (ref mut switch, ref mut switch_handler) = this.data;
let compositor = match compositor::handle() {
Some(handle) => handle,
None => return
};
switch_handler.destroyed(compositor, switch.weak_reference());
}
ffi_dispatch!(WAYLAND_SERVER_HANDLE,
wl_list_remove,
&mut (*this.on_toggle_listener()).link as *mut _ as _);
ffi_dispatch!(WAYLAND_SERVER_HANDLE,
wl_list_remove,
&mut (*this.on_destroy_listener()).link as *mut _ as _);
Box::from_raw((*input_device_ptr).data as *mut SwitchWrapper);
};
on_toggle_listener => on_toggle_notify: |this: &mut SwitchWrapper, data: *mut libc::c_void,|
unsafe {
let (ref mut switch, ref mut switch_handler) = this.data;
let event = switch::event::Toggle::from_ptr(data as *mut wlr_event_switch_toggle);
let compositor = match compositor::handle() {
Some(handle) => handle,
None => return
};
switch_handler.on_toggle(compositor, switch.weak_reference(), &event);
};
]);

6 changes: 3 additions & 3 deletions src/types/area.rs
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ impl Area {
pub fn intersection(self, other_box: Area) -> IntersectionResult {
unsafe {
let res = Area::default();
let is_empty = wlr_box_intersection(&self.into(), &other_box.into(), &mut res.into());
let is_empty = wlr_box_intersection(&mut res.into(), &self.into(), &other_box.into());
if is_empty {
IntersectionResult::NoIntersection
} else {
Expand All @@ -135,7 +135,7 @@ impl Area {
pub fn transform(self, transform: wl_output_transform, width: c_int, height: c_int) -> Area {
unsafe {
let res = Area::default();
wlr_box_transform(&mut self.into(), transform, width, height, &mut res.into());
wlr_box_transform(&mut res.into(), &mut self.into(), transform, width, height);
res
}
}
Expand All @@ -144,7 +144,7 @@ impl Area {
pub fn rotated_bounds(self, rotation: c_float) -> Area {
unsafe {
let dest = Area::default();
wlr_box_rotated_bounds(&self.into(), rotation, &mut dest.into());
wlr_box_rotated_bounds(&mut dest.into(), &self.into(), rotation);
dest
}
}
Expand Down
9 changes: 7 additions & 2 deletions src/types/input/input_device.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use libc::{c_double, c_uint};
use wlroots_sys::{wlr_input_device, wlr_input_device_pointer, wlr_input_device_type,
wlr_input_device_type::*};

use {input::{keyboard, pointer, touch, tablet_pad, tablet_tool},
use {input::{keyboard, pointer, switch, touch, tablet_pad, tablet_tool},
utils::c_to_rust_string};
pub(crate) use manager::input_manager::Manager;

Expand All @@ -14,7 +14,8 @@ pub enum Handle {
Pointer(pointer::Handle),
Touch(touch::Handle),
TabletPad(tablet_pad::Handle),
TabletTool(tablet_tool::Handle)
TabletTool(tablet_tool::Handle),
Switch(switch::Handle)
}

pub(crate) struct InputState {
Expand Down Expand Up @@ -94,6 +95,10 @@ impl Device {
let tablet_pad_ptr = (*self.device).__bindgen_anon_1.tablet_pad;
Handle::TabletPad(tablet_pad::Handle::from_ptr(tablet_pad_ptr))
},
WLR_INPUT_DEVICE_SWITCH => {
let switch_ptr = (*self.device).__bindgen_anon_1.lid_switch;
Handle::Switch(switch::Handle::from_ptr(switch_ptr))
}
}
}
}
Expand Down
1 change: 1 addition & 0 deletions src/types/input/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
mod input_device;
pub mod keyboard;
pub mod pointer;
pub mod switch;
pub mod touch;
pub mod tablet_tool;
pub mod tablet_pad;
Expand Down
122 changes: 122 additions & 0 deletions src/types/input/switch.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
//! TODO Documentation
use std::{cell::Cell, rc::Rc};

use {
input::{self, InputState},
utils::{self, Handleable, HandleErr, HandleResult}};
use wlroots_sys::{wlr_input_device, wlr_switch};
pub use manager::switch_handler::*;
pub use events::switch_events as event;

pub type Handle = utils::Handle<*mut wlr_input_device, wlr_switch, Switch>;

#[derive(Debug)]
pub struct Switch {
/// The structure that ensures weak handles to this structure are still alive.
///
/// They contain weak handles, and will safely not use dead memory when this
/// is freed by wlroots.
///
/// If this is `None`, then this is from an upgraded `pointer::Handle`, and
/// the operations are **unchecked**.
/// This is means safe operations might fail, but only if you use the unsafe
/// marked function `upgrade` on a `pointer::Handle`.
liveliness: Rc<Cell<bool>>,
/// The device that refers to this pointer.
device: input::Device,
/// The underlying switch data.
switch: *mut wlr_switch
}

impl Switch {
/// Tries to convert an input device to a Switch
///
/// Returns none if it is of a different input variant.
///
/// # Safety
/// This creates a totally new Switch (e.g with its own reference count)
/// so only do this once per `wlr_input_device`!
pub(crate) unsafe fn new_from_input_device(device: *mut wlr_input_device) -> Option<Self> {
use wlroots_sys::wlr_input_device_type::*;
match (*device).type_ {
WLR_INPUT_DEVICE_SWITCH => {
let switch = (*device).__bindgen_anon_1.lid_switch;
let liveliness = Rc::new(Cell::new(false));
let handle = Rc::downgrade(&liveliness);
let state = Box::new(InputState { handle,
device: input::Device::from_ptr(device) });
(*switch).data = Box::into_raw(state) as *mut _;
Some(Switch { liveliness,
device: input::Device::from_ptr(device),
switch })
}
_ => None
}
}

/// Gets the wlr_input_device associated with this switch.
pub fn input_device(&self) -> &input::Device {
&self.device
}
}

impl Drop for Switch {
fn drop(&mut self) {
if Rc::strong_count(&self.liveliness) == 1 {
wlr_log!(WLR_DEBUG, "Dropped Switch {:p}", self.switch);
unsafe {
let _ = Box::from_raw((*self.switch).data as *mut InputState);
}
let weak_count = Rc::weak_count(&self.liveliness);
if weak_count > 0 {
wlr_log!(WLR_DEBUG,
"Still {} weak pointers to Switch {:p}",
weak_count,
self.switch);
}
}
}
}

impl Handleable<*mut wlr_input_device, wlr_switch> for Switch {
#[doc(hidden)]
unsafe fn from_ptr(switch: *mut wlr_switch) -> Self {
let data = Box::from_raw((*switch).data as *mut InputState);
let handle = data.handle.clone();
let device = data.device.clone();
(*switch).data = Box::into_raw(data) as *mut _;
Switch { liveliness: handle.upgrade().unwrap(),
device,
switch }
}

#[doc(hidden)]
unsafe fn as_ptr(&self) -> *mut wlr_switch {
self.switch
}

#[doc(hidden)]
unsafe fn from_handle(handle: &Handle) -> HandleResult<Self> {
let liveliness = handle.handle
.upgrade()
.ok_or(HandleErr::AlreadyDropped)?;
Ok(Switch { liveliness,
// NOTE Rationale for cloning:
// If we already dropped we don't reach this point.
device: input::Device { device: handle.data },
switch: handle.as_ptr()
})
}

fn weak_reference(&self) -> Handle {
Handle { ptr: self.switch,
handle: Rc::downgrade(&self.liveliness),
// NOTE Rationale for cloning:
// Since we have a strong reference already,
// the input must still be alive.
data: unsafe { self.device.as_ptr() },
_marker: std::marker::PhantomData
}
}
}
Loading

0 comments on commit f9cdf5e

Please sign in to comment.