blob: c9eea5d790e530fff978352528fcfe7245cc5934 [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 crate::shell;
use crate::Shell;
use std::cell::RefCell;
use std::rc::Rc;
use crate::ffi;
use crate::ffi::evdev::{KEY_F1, KEY_F2};
struct Terminal {
client_surface: Option<*mut ffi::weston_surface>,
shell: Rc<RefCell<crate::Shell>>,
client: Option<*const ffi::wl_client>,
surface_create_listener: ffi::wl_listener,
client_destroy_listener: ffi::wl_listener,
}
extern "C" fn client_destroy_notify(
listener: *mut ffi::wl_listener,
_data: *mut ::std::os::raw::c_void,
) {
let mut t = unsafe { &mut *container_of_mut!(listener, Terminal, client_destroy_listener) };
t.client = None;
t.client_surface = None;
}
impl Terminal {
fn hide(&mut self) {
if let Some(rc) = shell::Surface::get(self.client_surface.unwrap_or(0 as *mut _)) {
let mut shsurf = rc.borrow_mut();
shsurf.set_fullscreen(false, 0 as *mut _);
shsurf.set_minimized();
}
}
fn show(&mut self, keyboard: &mut ffi::weston_keyboard) {
let shell = self.shell.borrow_mut();
match (self.client_surface, self.client) {
(Some(surface), _) => unsafe {
if let Some(rc) = shell::Surface::get(self.client_surface.unwrap_or(0 as *mut _)) {
let mut shsurf = rc.borrow_mut();
let view = &mut *shsurf.view;
view.activate(
keyboard.seat,
ffi::weston_activate_flag::WESTON_ACTIVATE_FLAG_CONFIGURE.0,
);
shsurf.set_fullscreen(true, (*surface).output);
}
},
(None, None) => {
let terminal_client_path = "/usr/bin/croscomp-terminal\0";
let mut compositor = shell.compositor.borrow_mut();
let client = compositor.launch_client(terminal_client_path).unwrap();
unsafe {
ffi::wl_client_add_destroy_listener(
client,
&mut self.client_destroy_listener as *mut ffi::wl_listener,
)
};
self.client = Some(client);
}
_ => {}
}
}
}
extern "C" fn surface_create_notify(
listener: *mut ffi::wl_listener,
data: *mut ::std::os::raw::c_void,
) {
let mut t = unsafe { &mut *container_of_mut!(listener, Terminal, surface_create_listener) };
let surface = data as *mut ffi::weston_surface;
let client = unsafe { ffi::wl_resource_get_client((*surface).resource) };
if t.client == Some(client) {
t.client_surface = Some(surface);
}
}
pub fn init(shell: &Rc<RefCell<Shell>>) {
let t = Rc::new(RefCell::new(Terminal {
client_surface: None,
shell: Rc::clone(shell),
client: None,
surface_create_listener: ffi::wl_listener::new(surface_create_notify),
client_destroy_listener: ffi::wl_listener::new(client_destroy_notify),
}));
let s = shell.borrow();
let mut compositor = s.compositor.borrow_mut();
// signal add
unsafe {
ffi::wl_list_insert(
&mut compositor.native.create_surface_signal.listener_list,
&mut t.borrow_mut().surface_create_listener.link,
);
}
let rc = Rc::clone(&t);
compositor.bind_key(
KEY_F1,
ffi::weston_keyboard_modifier::MODIFIER_CTRL | ffi::weston_keyboard_modifier::MODIFIER_ALT,
move |_, _, _| rc.borrow_mut().hide(),
);
let rc = Rc::clone(&t);
compositor.bind_key(
KEY_F2,
ffi::weston_keyboard_modifier::MODIFIER_CTRL | ffi::weston_keyboard_modifier::MODIFIER_ALT,
move |keyboard, _, _| rc.borrow_mut().show(keyboard),
);
}