blob: 8818bf82e5c699cfba8553f92ad768cadcbb8568 [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::cell::RefCell;
use std::rc::Rc;
use crate::ffi;
use crate::ffi::evdev::{BTN_LEFT, KEY_ESC, KEY_F3};
use crate::shell;
// TODO:
//
// - Rotate on Ctrl-Alt-Shift-REFRESH
//
// #[derive(Listener)]
struct Rotation {
transform: ffi::weston_transform,
view_destroy_listener: ffi::wl_listener,
}
impl From<*mut ffi::wl_listener> for Box<Rotation> {
fn from(listener: *mut ffi::wl_listener) -> Box<Rotation> {
unsafe { Box::from_raw(container_of_mut!(listener, Rotation, view_destroy_listener)) }
}
}
impl<'a> From<&'a mut Box<Rotation>> for &'a mut ffi::wl_listener {
fn from(rotation: &'a mut Box<Rotation>) -> &'a mut ffi::wl_listener {
&mut rotation.view_destroy_listener
}
}
impl Drop for Rotation {
fn drop(&mut self) {
self.transform.link.remove();
}
}
fn key_rotate(shsurf: &mut shell::Surface) {
let view = unsafe { &mut *shsurf.view };
let surface = unsafe { &mut *shsurf.surface };
let compositor = unsafe { &mut *(*shsurf.surface).compositor };
let cx = surface.width as f32 * 0.5;
let cy = surface.height as f32 * 0.5;
let (s, c) = f32::sin_cos(0.1);
let mut rotation = view.destroy_signal.get().unwrap_or_else(|| {
let mut rotation = Box::new(Rotation {
transform: ffi::weston_transform::new(),
view_destroy_listener: ffi::wl_listener::zeroed(),
});
view.destroy_signal.add(&mut rotation);
unsafe {
ffi::wl_list_insert(
&mut view.geometry.transformation_list,
&mut rotation.transform.link,
);
}
rotation
});
rotation.transform.matrix = rotation
.transform
.matrix
.translate(-cx, -cy, 0.0)
.rotate(c, s)
.translate(cx, cy, 0.0);
view.geometry_dirty();
compositor.schedule_repaint();
println!("rotate {:?}", surface as *mut _)
}
fn pointer_rotate(view: &mut ffi::weston_view) {
println!("pointer rotate {:?}", view as *mut _)
}
pub fn init(shell: &Rc<RefCell<shell::Shell>>) {
let shell = shell.borrow();
let mut compositor = shell.compositor.borrow_mut();
let mods = ffi::weston_keyboard_modifier::MODIFIER_CTRL
| ffi::weston_keyboard_modifier::MODIFIER_ALT
| ffi::weston_keyboard_modifier::MODIFIER_SHIFT;
compositor.bind_key(KEY_F3, mods, move |keyboard, _, _| {
if let Some(shsurf) = shell::Surface::get(keyboard.focus) {
let mut shsurf = shsurf.borrow_mut();
key_rotate(&mut shsurf)
}
});
compositor.bind_key(KEY_ESC, mods, move |keyboard, _, _| {
if let Some(shsurf) = shell::Surface::get(keyboard.focus) {
let mut shsurf = shsurf.borrow_mut();
let view = unsafe { &mut *shsurf.view };
let compositor = unsafe { &mut *(*shsurf.surface).compositor };
let _ = view.destroy_signal.remove::<Box<Rotation>>();
view.geometry_dirty();
compositor.schedule_repaint();
}
});
compositor.bind_button(BTN_LEFT, mods, |pointer: &mut ffi::weston_pointer, _, _| {
let focus = unsafe { &mut *pointer.focus };
pointer_rotate(focus)
});
}