use std::ops::Deref;
use wayland_client::protocol::{wl_compositor, wl_pointer, wl_seat, wl_shm};
use wayland_client::{NewProxy, Proxy, QueueToken};
use wayland_client::protocol::wl_seat::RequestsTrait as SeatRequests;
mod theme;
pub use self::theme::{ThemeManager, ThemedPointer};
pub enum AutoThemer {
Themed(ThemeManager),
UnThemed,
}
impl AutoThemer {
pub fn init(
name: Option<&str>,
compositor: Proxy<wl_compositor::WlCompositor>,
shm: &Proxy<wl_shm::WlShm>,
) -> AutoThemer {
match ThemeManager::init(name, compositor, &shm) {
Ok(mgr) => AutoThemer::Themed(mgr),
Err(()) => AutoThemer::UnThemed,
}
}
pub fn theme_pointer(&self, pointer: Proxy<wl_pointer::WlPointer>) -> AutoPointer {
match *self {
AutoThemer::Themed(ref mgr) => AutoPointer::Themed(mgr.theme_pointer(pointer)),
AutoThemer::UnThemed => AutoPointer::UnThemed(pointer),
}
}
pub fn theme_pointer_with_impl<Impl, UD>(
&self,
seat: &Proxy<wl_seat::WlSeat>,
mut implementation: Impl,
user_data: UD,
) -> AutoPointer
where
Impl: FnMut(wl_pointer::Event, AutoPointer) + Send + 'static,
UD: Send + Sync + 'static,
{
match *self {
AutoThemer::Themed(ref mgr) => {
let pointer = mgr.theme_pointer_with_impl(
seat,
move |event, seat| implementation(event, AutoPointer::Themed(seat)),
user_data,
);
AutoPointer::Themed(pointer)
}
AutoThemer::UnThemed => {
let pointer = seat
.get_pointer(|pointer| {
pointer.implement(
move |event, seat| implementation(event, AutoPointer::UnThemed(seat)),
user_data,
)
})
.unwrap();
AutoPointer::UnThemed(pointer)
}
}
}
pub unsafe fn theme_pointer_with_nonsend_impl<Impl, UD>(
&self,
pointer: NewProxy<wl_pointer::WlPointer>,
mut implementation: Impl,
user_data: UD,
token: &QueueToken,
) -> AutoPointer
where
Impl: FnMut(wl_pointer::Event, AutoPointer) + Send + 'static,
UD: Send + Sync + 'static,
{
match *self {
AutoThemer::Themed(ref mgr) => {
let pointer = mgr.theme_pointer_with_nonsend_impl(
pointer,
move |event, pointer| implementation(event, AutoPointer::Themed(pointer)),
user_data,
token,
);
AutoPointer::Themed(pointer)
}
AutoThemer::UnThemed => {
let pointer = pointer.implement_nonsend(
move |event, pointer| implementation(event, AutoPointer::UnThemed(pointer)),
user_data,
token,
);
AutoPointer::UnThemed(pointer)
}
}
}
}
pub enum AutoPointer {
Themed(ThemedPointer),
UnThemed(Proxy<wl_pointer::WlPointer>),
}
impl AutoPointer {
pub fn set_cursor(&self, name: &str, serial: Option<u32>) -> Result<(), ()> {
match *self {
AutoPointer::Themed(ref themed) => themed.set_cursor(name, serial),
AutoPointer::UnThemed(_) => Ok(()),
}
}
}
impl Deref for AutoPointer {
type Target = Proxy<wl_pointer::WlPointer>;
fn deref(&self) -> &Proxy<wl_pointer::WlPointer> {
match *self {
AutoPointer::Themed(ref themed) => &**themed,
AutoPointer::UnThemed(ref ptr) => ptr,
}
}
}
impl Clone for AutoPointer {
fn clone(&self) -> AutoPointer {
match *self {
AutoPointer::Themed(ref themed) => AutoPointer::Themed(themed.clone()),
AutoPointer::UnThemed(ref ptr) => AutoPointer::UnThemed(ptr.clone()),
}
}
}