#[macro_export]
macro_rules! wayland_env {
($structname: ident, $($name: ident : $interface: ty),*) => (
struct $structname {
pub display: $crate::wayland::WlDisplay,
pub registry: $crate::wayland::WlRegistry,
pub globals: Vec<(u32, String, u32)>,
$(
pub $name : Option<($interface, u32)>,
)*
}
impl $structname {
pub fn init(mut display: $crate::wayland::WlDisplay) -> ($structname, $crate::EventIterator) {
use $crate::{Proxy, Event};
use $crate::wayland::{WaylandProtocolEvent, WlRegistryEvent};
let mut iter = $crate::EventIterator::new();
display.set_evt_iterator(&iter);
let registry = display.get_registry();
match display.sync_roundtrip() {
Ok(_) => {},
Err(e) => panic!("Roundtrip with wayland server failed: {:?}", e)
}
let mut env = $structname {
display: display,
registry: registry,
globals: Vec::new(),
$(
$name: None,
)*
};
for evt in &mut iter {
match evt {
Event::Wayland(WaylandProtocolEvent::WlRegistry(
_, WlRegistryEvent::Global(name, interface, version)
)) => {
env.handle_global(name, interface, version)
}
_ => {}
}
}
(env, iter)
}
#[allow(dead_code)]
pub fn rebind<T: $crate::Proxy>(&self) -> Option<(T, u32)> {
use $crate::Proxy;
let t_interface = <T as Proxy>::interface_name();
for &(name, ref interface, version) in &self.globals {
if interface == t_interface {
let chosen_version = ::std::cmp::min(version, <T as Proxy>::version());
let proxy = unsafe { self.registry.bind::<T>(name, chosen_version) };
return Some((proxy, chosen_version))
}
}
return None
}
#[allow(dead_code)]
pub fn rebind_id<T: $crate::Proxy>(&self, id: u32) -> Option<(T, u32)> {
use $crate::Proxy;
let t_interface = <T as Proxy>::interface_name();
for &(name, ref interface, version) in &self.globals {
if name == id && interface == t_interface {
let chosen_version = ::std::cmp::min(version, <T as Proxy>::version());
let proxy = unsafe { self.registry.bind::<T>(name, chosen_version) };
return Some((proxy, chosen_version))
}
}
return None
}
fn handle_global(&mut self, name: u32, interface: String, version: u32) {
use $crate::Proxy;
match interface {
$(
ref s if &s[..] == <$interface as Proxy>::interface_name() => {
let chosen_version = ::std::cmp::min(version, <$interface as Proxy>::version());
if self.$name.is_none() {
let proxy = unsafe { self.registry.bind::<$interface>(name, chosen_version) };
self.$name = Some((proxy, chosen_version));
}
}
)*
_ => {}
}
self.globals.push((name, interface, version));
}
}
)
}