blob: be7d426692de07b89d4a98e91c53c3a554aa1958 [file] [log] [blame] [edit]
// Copyright 2021 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
use std::ptr::NonNull;
use crate::ffi;
use crate::protocol::wl_keyboard::KeyState;
use crate::protocol::wl_pointer::ButtonState;
pub trait PointerGrabHandler {
fn focus(&mut self, _pointer: &mut ffi::weston_pointer) {}
fn motion(
&mut self,
_pointer: &mut ffi::weston_pointer,
_time: &ffi::timespec,
_event: *mut ffi::weston_pointer_motion_event,
) {
}
fn button(
&mut self,
_pointer: &mut ffi::weston_pointer,
_time: &ffi::timespec,
_button: u32,
_state: ButtonState,
) {
}
fn axis(
&mut self,
_pointer: &mut ffi::weston_pointer,
_time: *const ffi::timespec,
_event: *mut ffi::weston_pointer_axis_event,
) {
}
fn axis_source(&mut self, _pointer: &mut ffi::weston_pointer, _source: u32) {}
fn frame(&mut self, _pointer: &mut ffi::weston_pointer) {}
fn cancel(&mut self, _pointer: &mut ffi::weston_pointer) {}
}
pub struct PointerGrab {
grab: ffi::weston_pointer_grab,
handler: Option<NonNull<dyn PointerGrabHandler>>,
}
impl PointerGrab {
fn cast(
grab: *mut ffi::weston_pointer_grab,
) -> (
&'static mut ffi::weston_pointer,
&'static mut dyn PointerGrabHandler,
) {
let grab = unsafe { &mut *container_of_mut!(grab, PointerGrab, grab) };
unsafe {
(
&mut *grab.grab.pointer,
&mut *grab.handler.unwrap().as_ptr(),
)
}
}
extern "C" fn focus(grab: *mut ffi::weston_pointer_grab) {
let (pointer, handler) = Self::cast(grab);
handler.focus(pointer);
}
extern "C" fn motion(
grab: *mut ffi::weston_pointer_grab,
time: *const ffi::timespec,
event: *mut ffi::weston_pointer_motion_event,
) {
let (pointer, handler) = Self::cast(grab);
let time = unsafe { &*time };
handler.motion(pointer, time, event);
}
extern "C" fn button(
grab: *mut ffi::weston_pointer_grab,
time: *const ffi::timespec,
button: u32,
state: u32,
) {
let (pointer, handler) = Self::cast(grab);
let time = unsafe { &*time };
handler.button(pointer, time, button, ButtonState::from_raw(state).unwrap())
}
extern "C" fn axis(
grab: *mut ffi::weston_pointer_grab,
time: *const ffi::timespec,
event: *mut ffi::weston_pointer_axis_event,
) {
let (pointer, handler) = Self::cast(grab);
let time = unsafe { &*time };
let event = unsafe { &mut *event };
handler.axis(pointer, time, event)
}
extern "C" fn axis_source(grab: *mut ffi::weston_pointer_grab, source: u32) {
let (pointer, handler) = Self::cast(grab);
handler.axis_source(pointer, source)
}
extern "C" fn frame(grab: *mut ffi::weston_pointer_grab) {
let (pointer, handler) = Self::cast(grab);
handler.frame(pointer)
}
extern "C" fn cancel(grab: *mut ffi::weston_pointer_grab) {
let (pointer, handler) = Self::cast(grab);
handler.cancel(pointer);
}
pub fn new(pointer: *mut ffi::weston_pointer) -> PointerGrab {
static INTERFACE: ffi::weston_pointer_grab_interface = ffi::weston_pointer_grab_interface {
focus: Some(PointerGrab::focus),
motion: Some(PointerGrab::motion),
button: Some(PointerGrab::button),
axis: Some(PointerGrab::axis),
axis_source: Some(PointerGrab::axis_source),
frame: Some(PointerGrab::frame),
cancel: Some(PointerGrab::cancel),
};
PointerGrab {
grab: ffi::weston_pointer_grab { interface: &INTERFACE, pointer: pointer },
handler: None,
}
}
pub fn start(&mut self, handler: *mut dyn PointerGrabHandler) {
// This is a separate function since it needs a stable address for self
self.handler = NonNull::new(handler);
unsafe { ffi::weston_pointer_start_grab(self.grab.pointer, &mut self.grab) };
}
}
impl Drop for PointerGrab {
fn drop(&mut self) {
unsafe { ffi::weston_pointer_end_grab(self.grab.pointer) }
}
}
pub trait KeyboardGrabHandler {
fn key(
&mut self,
_keyboard: &mut ffi::weston_keyboard,
_time: &ffi::timespec,
_key: u32,
_state: KeyState,
) {
}
fn modifiers(
&mut self,
_keyboard: &mut ffi::weston_keyboard,
_serial: u32,
_mods_depressed: u32,
_mods_latched: u32,
_mods_locked: u32,
_group: u32,
) {
}
fn cancel(&mut self, _keyboard: &mut ffi::weston_keyboard) {}
}
pub struct KeyboardGrab {
pub grab: ffi::weston_keyboard_grab,
handler: Option<NonNull<dyn KeyboardGrabHandler>>,
}
impl KeyboardGrab {
fn cast(
grab: *mut ffi::weston_keyboard_grab,
) -> (
&'static mut ffi::weston_keyboard,
&'static mut dyn KeyboardGrabHandler,
) {
let grab = unsafe { &mut *container_of_mut!(grab, KeyboardGrab, grab) };
unsafe {
(
&mut *grab.grab.keyboard,
&mut *grab.handler.unwrap().as_ptr(),
)
}
}
extern "C" fn key(
grab: *mut ffi::weston_keyboard_grab,
time: *const ffi::timespec,
key: u32,
state: u32,
) {
let (keyboard, handler) = Self::cast(grab);
let time = unsafe { &*time };
handler.key(keyboard, time, key, KeyState::from_raw(state).unwrap());
}
extern "C" fn modifiers(
grab: *mut ffi::weston_keyboard_grab,
serial: u32,
mods_depressed: u32,
mods_latched: u32,
mods_locked: u32,
group: u32,
) {
let (keyboard, handler) = Self::cast(grab);
handler.modifiers(
keyboard,
serial,
mods_depressed,
mods_latched,
mods_locked,
group,
)
}
extern "C" fn cancel(grab: *mut ffi::weston_keyboard_grab) {
let (keyboard, handler) = Self::cast(grab);
handler.cancel(keyboard)
}
pub fn new(keyboard: *mut ffi::weston_keyboard) -> KeyboardGrab {
static INTERFACE: ffi::weston_keyboard_grab_interface =
ffi::weston_keyboard_grab_interface {
key: Some(KeyboardGrab::key),
modifiers: Some(KeyboardGrab::modifiers),
cancel: Some(KeyboardGrab::cancel),
};
KeyboardGrab {
grab: ffi::weston_keyboard_grab {
interface: &INTERFACE,
keyboard: keyboard,
},
handler: None,
}
}
pub fn start(&mut self, handler: *mut dyn KeyboardGrabHandler) {
self.handler = NonNull::new(handler);
unsafe { ffi::weston_keyboard_start_grab(self.grab.keyboard, &mut self.grab) };
}
}
impl Drop for KeyboardGrab {
fn drop(&mut self) {
unsafe { ffi::weston_keyboard_end_grab(self.grab.keyboard) }
}
}