use std::cell::Cell;
use std::collections::VecDeque;
use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::{Arc, Mutex, mpsc};
use std::time::Instant;
use std::{iter, mem, slice};
use bitflags::bitflags;
use orbclient::{
ButtonEvent, EventOption, FocusEvent, HoverEvent, KeyEvent, MouseEvent, MouseRelativeEvent,
MoveEvent, QuitEvent, ResizeEvent, ScrollEvent, TextInputEvent,
};
use smol_str::SmolStr;
use winit_core::application::ApplicationHandler;
use winit_core::cursor::{CustomCursor, CustomCursorSource};
use winit_core::error::{EventLoopError, NotSupportedError, RequestError};
use winit_core::event::{self, Ime, Modifiers, StartCause};
use winit_core::event_loop::{
ActiveEventLoop as RootActiveEventLoop, ControlFlow, DeviceEvents,
EventLoopProxy as CoreEventLoopProxy, EventLoopProxyProvider,
OwnedDisplayHandle as CoreOwnedDisplayHandle,
};
use winit_core::keyboard::{
Key, KeyCode, KeyLocation, ModifiersKeys, ModifiersState, NamedKey, NativeKey, NativeKeyCode,
PhysicalKey,
};
use winit_core::window::{Theme, Window as CoreWindow, WindowId};
use crate::window::Window;
use crate::{RedoxSocket, TimeSocket, WindowProperties};
fn convert_scancode(scancode: u8) -> (PhysicalKey, Option<NamedKey>) {
let (key_code, named_key_opt) = match scancode {
orbclient::K_A => (KeyCode::KeyA, None),
orbclient::K_B => (KeyCode::KeyB, None),
orbclient::K_C => (KeyCode::KeyC, None),
orbclient::K_D => (KeyCode::KeyD, None),
orbclient::K_E => (KeyCode::KeyE, None),
orbclient::K_F => (KeyCode::KeyF, None),
orbclient::K_G => (KeyCode::KeyG, None),
orbclient::K_H => (KeyCode::KeyH, None),
orbclient::K_I => (KeyCode::KeyI, None),
orbclient::K_J => (KeyCode::KeyJ, None),
orbclient::K_K => (KeyCode::KeyK, None),
orbclient::K_L => (KeyCode::KeyL, None),
orbclient::K_M => (KeyCode::KeyM, None),
orbclient::K_N => (KeyCode::KeyN, None),
orbclient::K_O => (KeyCode::KeyO, None),
orbclient::K_P => (KeyCode::KeyP, None),
orbclient::K_Q => (KeyCode::KeyQ, None),
orbclient::K_R => (KeyCode::KeyR, None),
orbclient::K_S => (KeyCode::KeyS, None),
orbclient::K_T => (KeyCode::KeyT, None),
orbclient::K_U => (KeyCode::KeyU, None),
orbclient::K_V => (KeyCode::KeyV, None),
orbclient::K_W => (KeyCode::KeyW, None),
orbclient::K_X => (KeyCode::KeyX, None),
orbclient::K_Y => (KeyCode::KeyY, None),
orbclient::K_Z => (KeyCode::KeyZ, None),
orbclient::K_0 => (KeyCode::Digit0, None),
orbclient::K_1 => (KeyCode::Digit1, None),
orbclient::K_2 => (KeyCode::Digit2, None),
orbclient::K_3 => (KeyCode::Digit3, None),
orbclient::K_4 => (KeyCode::Digit4, None),
orbclient::K_5 => (KeyCode::Digit5, None),
orbclient::K_6 => (KeyCode::Digit6, None),
orbclient::K_7 => (KeyCode::Digit7, None),
orbclient::K_8 => (KeyCode::Digit8, None),
orbclient::K_9 => (KeyCode::Digit9, None),
orbclient::K_ALT => (KeyCode::AltLeft, Some(NamedKey::Alt)),
orbclient::K_ALT_GR => (KeyCode::AltRight, Some(NamedKey::AltGraph)),
orbclient::K_BACKSLASH => (KeyCode::Backslash, None),
orbclient::K_BKSP => (KeyCode::Backspace, Some(NamedKey::Backspace)),
orbclient::K_BRACE_CLOSE => (KeyCode::BracketRight, None),
orbclient::K_BRACE_OPEN => (KeyCode::BracketLeft, None),
orbclient::K_CAPS => (KeyCode::CapsLock, Some(NamedKey::CapsLock)),
orbclient::K_COMMA => (KeyCode::Comma, None),
orbclient::K_CTRL => (KeyCode::ControlLeft, Some(NamedKey::Control)),
orbclient::K_DEL => (KeyCode::Delete, Some(NamedKey::Delete)),
orbclient::K_DOWN => (KeyCode::ArrowDown, Some(NamedKey::ArrowDown)),
orbclient::K_END => (KeyCode::End, Some(NamedKey::End)),
orbclient::K_ENTER => (KeyCode::Enter, Some(NamedKey::Enter)),
orbclient::K_EQUALS => (KeyCode::Equal, None),
orbclient::K_ESC => (KeyCode::Escape, Some(NamedKey::Escape)),
orbclient::K_F1 => (KeyCode::F1, Some(NamedKey::F1)),
orbclient::K_F2 => (KeyCode::F2, Some(NamedKey::F2)),
orbclient::K_F3 => (KeyCode::F3, Some(NamedKey::F3)),
orbclient::K_F4 => (KeyCode::F4, Some(NamedKey::F4)),
orbclient::K_F5 => (KeyCode::F5, Some(NamedKey::F5)),
orbclient::K_F6 => (KeyCode::F6, Some(NamedKey::F6)),
orbclient::K_F7 => (KeyCode::F7, Some(NamedKey::F7)),
orbclient::K_F8 => (KeyCode::F8, Some(NamedKey::F8)),
orbclient::K_F9 => (KeyCode::F9, Some(NamedKey::F9)),
orbclient::K_F10 => (KeyCode::F10, Some(NamedKey::F10)),
orbclient::K_F11 => (KeyCode::F11, Some(NamedKey::F11)),
orbclient::K_F12 => (KeyCode::F12, Some(NamedKey::F12)),
orbclient::K_HOME => (KeyCode::Home, Some(NamedKey::Home)),
orbclient::K_LEFT => (KeyCode::ArrowLeft, Some(NamedKey::ArrowLeft)),
orbclient::K_LEFT_SHIFT => (KeyCode::ShiftLeft, Some(NamedKey::Shift)),
orbclient::K_MINUS => (KeyCode::Minus, None),
orbclient::K_NUM_0 => (KeyCode::Numpad0, None),
orbclient::K_NUM_1 => (KeyCode::Numpad1, None),
orbclient::K_NUM_2 => (KeyCode::Numpad2, None),
orbclient::K_NUM_3 => (KeyCode::Numpad3, None),
orbclient::K_NUM_4 => (KeyCode::Numpad4, None),
orbclient::K_NUM_5 => (KeyCode::Numpad5, None),
orbclient::K_NUM_6 => (KeyCode::Numpad6, None),
orbclient::K_NUM_7 => (KeyCode::Numpad7, None),
orbclient::K_NUM_8 => (KeyCode::Numpad8, None),
orbclient::K_NUM_9 => (KeyCode::Numpad9, None),
orbclient::K_PERIOD => (KeyCode::Period, None),
orbclient::K_PGDN => (KeyCode::PageDown, Some(NamedKey::PageDown)),
orbclient::K_PGUP => (KeyCode::PageUp, Some(NamedKey::PageUp)),
orbclient::K_QUOTE => (KeyCode::Quote, None),
orbclient::K_RIGHT => (KeyCode::ArrowRight, Some(NamedKey::ArrowRight)),
orbclient::K_RIGHT_SHIFT => (KeyCode::ShiftRight, Some(NamedKey::Shift)),
orbclient::K_SEMICOLON => (KeyCode::Semicolon, None),
orbclient::K_SLASH => (KeyCode::Slash, None),
orbclient::K_SPACE => (KeyCode::Space, None),
orbclient::K_SUPER => (KeyCode::MetaLeft, Some(NamedKey::Meta)),
orbclient::K_TAB => (KeyCode::Tab, Some(NamedKey::Tab)),
orbclient::K_TICK => (KeyCode::Backquote, None),
orbclient::K_UP => (KeyCode::ArrowUp, Some(NamedKey::ArrowUp)),
orbclient::K_VOLUME_DOWN => (KeyCode::AudioVolumeDown, Some(NamedKey::AudioVolumeDown)),
orbclient::K_VOLUME_TOGGLE => (KeyCode::AudioVolumeMute, Some(NamedKey::AudioVolumeMute)),
orbclient::K_VOLUME_UP => (KeyCode::AudioVolumeUp, Some(NamedKey::AudioVolumeUp)),
_ => return (PhysicalKey::Unidentified(NativeKeyCode::Unidentified), None),
};
(PhysicalKey::Code(key_code), named_key_opt)
}
fn element_state(pressed: bool) -> event::ElementState {
if pressed { event::ElementState::Pressed } else { event::ElementState::Released }
}
bitflags! {
#[derive(Default, Debug, Clone, Copy, PartialEq, Eq, Hash)]
struct KeyboardModifierState: u8 {
const LSHIFT = 1 << 0;
const RSHIFT = 1 << 1;
const LCTRL = 1 << 2;
const RCTRL = 1 << 3;
const LALT = 1 << 4;
const RALT = 1 << 5;
const LMETA = 1 << 6;
const RMETA = 1 << 7;
}
}
bitflags! {
#[derive(Default, Debug, Clone, Copy, PartialEq, Eq, Hash)]
struct MouseButtonState: u8 {
const LEFT = 1 << 0;
const MIDDLE = 1 << 1;
const RIGHT = 1 << 2;
}
}
#[derive(Default, Debug)]
struct EventState {
keyboard: KeyboardModifierState,
mouse: MouseButtonState,
resize_opt: Option<(u32, u32)>,
}
impl EventState {
fn character_all_modifiers(&self, character: char) -> char {
#[allow(clippy::collapsible_if)]
if self.keyboard.contains(KeyboardModifierState::LCTRL)
|| self.keyboard.contains(KeyboardModifierState::RCTRL)
{
if character.is_ascii_lowercase() {
return ((character as u8 - b'a') + 1) as char;
}
}
character
}
fn key(&mut self, key: PhysicalKey, pressed: bool) {
let code = match key {
PhysicalKey::Code(code) => code,
_ => return,
};
match code {
KeyCode::ShiftLeft => self.keyboard.set(KeyboardModifierState::LSHIFT, pressed),
KeyCode::ShiftRight => self.keyboard.set(KeyboardModifierState::RSHIFT, pressed),
KeyCode::ControlLeft => self.keyboard.set(KeyboardModifierState::LCTRL, pressed),
KeyCode::ControlRight => self.keyboard.set(KeyboardModifierState::RCTRL, pressed),
KeyCode::AltLeft => self.keyboard.set(KeyboardModifierState::LALT, pressed),
KeyCode::AltRight => self.keyboard.set(KeyboardModifierState::RALT, pressed),
KeyCode::MetaLeft => self.keyboard.set(KeyboardModifierState::LMETA, pressed),
KeyCode::MetaRight => self.keyboard.set(KeyboardModifierState::RMETA, pressed),
_ => (),
}
}
fn mouse(
&mut self,
left: bool,
middle: bool,
right: bool,
) -> Option<(event::MouseButton, event::ElementState)> {
if self.mouse.contains(MouseButtonState::LEFT) != left {
self.mouse.set(MouseButtonState::LEFT, left);
return Some((event::MouseButton::Left, element_state(left)));
}
if self.mouse.contains(MouseButtonState::MIDDLE) != middle {
self.mouse.set(MouseButtonState::MIDDLE, middle);
return Some((event::MouseButton::Middle, element_state(middle)));
}
if self.mouse.contains(MouseButtonState::RIGHT) != right {
self.mouse.set(MouseButtonState::RIGHT, right);
return Some((event::MouseButton::Right, element_state(right)));
}
None
}
fn modifiers(&self) -> Modifiers {
let mut state = ModifiersState::empty();
let mut pressed_mods = ModifiersKeys::empty();
if self.keyboard.intersects(KeyboardModifierState::LSHIFT | KeyboardModifierState::RSHIFT) {
state |= ModifiersState::SHIFT;
}
pressed_mods
.set(ModifiersKeys::LSHIFT, self.keyboard.contains(KeyboardModifierState::LSHIFT));
pressed_mods
.set(ModifiersKeys::RSHIFT, self.keyboard.contains(KeyboardModifierState::RSHIFT));
if self.keyboard.intersects(KeyboardModifierState::LCTRL | KeyboardModifierState::RCTRL) {
state |= ModifiersState::CONTROL;
}
pressed_mods
.set(ModifiersKeys::LCONTROL, self.keyboard.contains(KeyboardModifierState::LCTRL));
pressed_mods
.set(ModifiersKeys::RCONTROL, self.keyboard.contains(KeyboardModifierState::RCTRL));
if self.keyboard.intersects(KeyboardModifierState::LALT | KeyboardModifierState::RALT) {
state |= ModifiersState::ALT;
}
pressed_mods.set(ModifiersKeys::LALT, self.keyboard.contains(KeyboardModifierState::LALT));
pressed_mods.set(ModifiersKeys::RALT, self.keyboard.contains(KeyboardModifierState::RALT));
if self.keyboard.intersects(KeyboardModifierState::LMETA | KeyboardModifierState::RMETA) {
state |= ModifiersState::META
}
pressed_mods
.set(ModifiersKeys::LMETA, self.keyboard.contains(KeyboardModifierState::LMETA));
pressed_mods
.set(ModifiersKeys::RMETA, self.keyboard.contains(KeyboardModifierState::RMETA));
Modifiers::new(state, pressed_mods)
}
}
#[derive(Debug)]
pub struct EventLoop {
windows: Vec<(Arc<RedoxSocket>, EventState)>,
window_target: ActiveEventLoop,
user_events_receiver: mpsc::Receiver<()>,
}
impl EventLoop {
pub fn new(_: &PlatformSpecificEventLoopAttributes) -> Result<Self, EventLoopError> {
static EVENT_LOOP_CREATED: AtomicBool = AtomicBool::new(false);
if EVENT_LOOP_CREATED.swap(true, Ordering::Relaxed) {
return Err(EventLoopError::RecreationAttempt);
}
let (user_events_sender, user_events_receiver) = mpsc::sync_channel(1);
let event_socket =
Arc::new(RedoxSocket::event().map_err(|error| os_error!(format!("{error}")))?);
let wake_socket = TimeSocket::open().map_err(|error| os_error!(format!("{error}")))?;
event_socket
.write(&syscall::Event {
id: wake_socket.0.fd,
flags: syscall::EventFlags::EVENT_READ,
data: wake_socket.0.fd,
})
.map_err(|error| os_error!(format!("{error}")))?;
Ok(Self {
windows: Vec::new(),
window_target: ActiveEventLoop {
control_flow: Cell::new(ControlFlow::default()),
exit: Cell::new(false),
creates: Mutex::new(VecDeque::new()),
redraws: Arc::new(Mutex::new(VecDeque::new())),
destroys: Arc::new(Mutex::new(VecDeque::new())),
event_socket,
event_loop_proxy: Arc::new(EventLoopProxy { wake_socket, user_events_sender }),
},
user_events_receiver,
})
}
fn process_event<A: ApplicationHandler>(
window_id: WindowId,
event_option: EventOption,
event_state: &mut EventState,
window_target: &ActiveEventLoop,
app: &mut A,
) {
match event_option {
EventOption::Key(KeyEvent { character, scancode, pressed }) => {
let (physical_key, named_key_opt) = convert_scancode(scancode);
let modifiers_before = event_state.keyboard;
event_state.key(physical_key, pressed);
let mut logical_key = Key::Unidentified(NativeKey::Unidentified);
let mut key_without_modifiers = logical_key.clone();
let mut text = None;
let mut text_with_all_modifiers = None;
if character != '\0' {
let mut tmp = [0u8; 4];
let character_str = character.encode_utf8(&mut tmp);
logical_key = Key::Character(character_str.into());
key_without_modifiers =
Key::Character(SmolStr::from_iter(character.to_lowercase()));
if pressed {
text = Some(character_str.into());
let character_all_modifiers =
event_state.character_all_modifiers(character);
text_with_all_modifiers =
Some(character_all_modifiers.encode_utf8(&mut tmp).into())
}
};
if let Some(named_key) = named_key_opt {
logical_key = Key::Named(named_key);
key_without_modifiers = logical_key.clone();
}
let event = event::WindowEvent::KeyboardInput {
device_id: None,
event: event::KeyEvent {
logical_key,
physical_key,
location: KeyLocation::Standard,
state: element_state(pressed),
repeat: false,
text,
key_without_modifiers,
text_with_all_modifiers,
},
is_synthetic: false,
};
app.window_event(window_target, window_id, event);
if modifiers_before != event_state.keyboard {
app.window_event(
window_target,
window_id,
event::WindowEvent::ModifiersChanged(event_state.modifiers()),
);
}
},
EventOption::TextInput(TextInputEvent { character }) => {
app.window_event(
window_target,
window_id,
event::WindowEvent::Ime(Ime::Preedit("".into(), None)),
);
app.window_event(
window_target,
window_id,
event::WindowEvent::Ime(Ime::Commit(character.into())),
);
},
EventOption::Mouse(MouseEvent { x, y }) => {
app.window_event(window_target, window_id, event::WindowEvent::PointerMoved {
device_id: None,
primary: true,
position: (x, y).into(),
source: event::PointerSource::Mouse,
});
},
EventOption::MouseRelative(MouseRelativeEvent { dx, dy }) => {
app.device_event(window_target, None, event::DeviceEvent::PointerMotion {
delta: (dx as f64, dy as f64),
});
},
EventOption::Button(ButtonEvent { left, middle, right }) => {
while let Some((button, state)) = event_state.mouse(left, middle, right) {
app.window_event(window_target, window_id, event::WindowEvent::PointerButton {
device_id: None,
primary: true,
state,
position: dpi::PhysicalPosition::default(),
button: button.into(),
});
}
},
EventOption::Scroll(ScrollEvent { x, y }) => {
app.window_event(window_target, window_id, event::WindowEvent::MouseWheel {
device_id: None,
delta: event::MouseScrollDelta::LineDelta(x as f32, y as f32),
phase: event::TouchPhase::Moved,
});
},
EventOption::Quit(QuitEvent {}) => {
app.window_event(window_target, window_id, event::WindowEvent::CloseRequested);
},
EventOption::Focus(FocusEvent { focused }) => {
app.window_event(window_target, window_id, event::WindowEvent::Focused(focused));
},
EventOption::Move(MoveEvent { x, y }) => {
app.window_event(
window_target,
window_id,
event::WindowEvent::Moved((x, y).into()),
);
},
EventOption::Resize(ResizeEvent { width, height }) => {
app.window_event(
window_target,
window_id,
event::WindowEvent::SurfaceResized((width, height).into()),
);
event_state.resize_opt = Some((width, height));
},
EventOption::Hover(HoverEvent { entered }) => {
let event = if entered {
event::WindowEvent::PointerEntered {
device_id: None,
primary: true,
position: dpi::PhysicalPosition::default(),
kind: event::PointerKind::Mouse,
}
} else {
event::WindowEvent::PointerLeft {
device_id: None,
primary: true,
position: None,
kind: event::PointerKind::Mouse,
}
};
app.window_event(window_target, window_id, event);
},
other => {
tracing::warn!("unhandled event: {:?}", other);
},
}
}
pub fn run_app<A: ApplicationHandler>(mut self, mut app: A) -> Result<(), EventLoopError> {
let mut start_cause = StartCause::Init;
loop {
app.new_events(&self.window_target, start_cause);
if start_cause == StartCause::Init {
app.can_create_surfaces(&self.window_target);
}
while let Some(window) = {
let mut creates = self.window_target.creates.lock().unwrap();
creates.pop_front()
} {
let window_id = WindowId::from_raw(window.fd);
let mut buf: [u8; 4096] = [0; 4096];
let path = window.fpath(&mut buf).expect("failed to read properties");
let properties = WindowProperties::new(path);
self.windows.push((window, EventState::default()));
let event = event::WindowEvent::SurfaceResized((properties.w, properties.h).into());
app.window_event(&self.window_target, window_id, event);
let event = event::WindowEvent::Moved((properties.x, properties.y).into());
app.window_event(&self.window_target, window_id, event);
}
while let Some(destroy_id) = {
let mut destroys = self.window_target.destroys.lock().unwrap();
destroys.pop_front()
} {
app.window_event(&self.window_target, destroy_id, event::WindowEvent::Destroyed);
self.windows
.retain(|(window, _event_state)| WindowId::from_raw(window.fd) != destroy_id);
}
let mut i = 0;
while let Some((window, event_state)) = self.windows.get_mut(i) {
let window_id = WindowId::from_raw(window.fd);
let mut event_buf = [0u8; 16 * mem::size_of::<orbclient::Event>()];
let count =
syscall::read(window.fd, &mut event_buf).expect("failed to read window events");
let events = unsafe {
slice::from_raw_parts(
event_buf.as_ptr() as *const orbclient::Event,
count / mem::size_of::<orbclient::Event>(),
)
};
for orbital_event in events {
Self::process_event(
window_id,
orbital_event.to_option(),
event_state,
&self.window_target,
&mut app,
);
}
if count == event_buf.len() {
continue;
}
if let Some((w, h)) = event_state.resize_opt.take() {
window
.write(format!("S,{w},{h}").as_bytes())
.expect("failed to acknowledge resize");
let mut redraws = self.window_target.redraws.lock().unwrap();
if !redraws.contains(&window_id) {
redraws.push_back(window_id);
}
}
i += 1;
}
while self.user_events_receiver.try_recv().is_ok() {
app.proxy_wake_up(&self.window_target);
}
while let Some(window_id) = {
let mut redraws = self.window_target.redraws.lock().unwrap();
redraws.pop_front()
} {
app.window_event(
&self.window_target,
window_id,
event::WindowEvent::RedrawRequested,
);
}
app.about_to_wait(&self.window_target);
if self.window_target.exiting() {
break;
}
let requested_resume = match self.window_target.control_flow() {
ControlFlow::Poll => {
start_cause = StartCause::Poll;
continue;
},
ControlFlow::Wait => None,
ControlFlow::WaitUntil(instant) => Some(instant),
};
let timeout_socket = TimeSocket::open().unwrap();
self.window_target
.event_socket
.write(&syscall::Event {
id: timeout_socket.0.fd,
flags: syscall::EventFlags::EVENT_READ,
data: 0,
})
.unwrap();
let start = Instant::now();
if let Some(instant) = requested_resume {
let mut time = timeout_socket.current_time().unwrap();
if let Some(duration) = instant.checked_duration_since(start) {
time.tv_sec += duration.as_secs() as i64;
time.tv_nsec += duration.subsec_nanos() as i32;
while time.tv_nsec >= 1_000_000_000 {
time.tv_sec += 1;
time.tv_nsec -= 1_000_000_000;
}
}
timeout_socket.timeout(&time).unwrap();
}
let mut event = syscall::Event::default();
self.window_target.event_socket.read(&mut event).unwrap();
match requested_resume {
Some(requested_resume) if event.id == timeout_socket.0.fd => {
start_cause = StartCause::ResumeTimeReached { start, requested_resume };
},
_ => {
start_cause = StartCause::WaitCancelled { start, requested_resume };
},
}
}
Ok(())
}
pub fn window_target(&self) -> &dyn RootActiveEventLoop {
&self.window_target
}
}
#[derive(Debug)]
pub struct EventLoopProxy {
user_events_sender: mpsc::SyncSender<()>,
pub(super) wake_socket: TimeSocket,
}
impl EventLoopProxyProvider for EventLoopProxy {
fn wake_up(&self) {
if self.user_events_sender.try_send(()).is_ok() {
self.wake_socket.wake().unwrap();
}
}
}
impl Unpin for EventLoopProxy {}
#[derive(Debug)]
pub struct ActiveEventLoop {
control_flow: Cell<ControlFlow>,
exit: Cell<bool>,
pub(super) creates: Mutex<VecDeque<Arc<RedoxSocket>>>,
pub(super) redraws: Arc<Mutex<VecDeque<WindowId>>>,
pub(super) destroys: Arc<Mutex<VecDeque<WindowId>>>,
pub(super) event_socket: Arc<RedoxSocket>,
pub(super) event_loop_proxy: Arc<EventLoopProxy>,
}
impl RootActiveEventLoop for ActiveEventLoop {
fn create_proxy(&self) -> CoreEventLoopProxy {
CoreEventLoopProxy::new(self.event_loop_proxy.clone())
}
fn create_window(
&self,
window_attributes: winit_core::window::WindowAttributes,
) -> Result<Box<dyn CoreWindow>, RequestError> {
Ok(Box::new(Window::new(self, window_attributes)?))
}
fn create_custom_cursor(&self, _: CustomCursorSource) -> Result<CustomCursor, RequestError> {
Err(NotSupportedError::new("create_custom_cursor is not supported").into())
}
fn available_monitors(&self) -> Box<dyn Iterator<Item = winit_core::monitor::MonitorHandle>> {
Box::new(iter::empty())
}
fn system_theme(&self) -> Option<Theme> {
None
}
fn primary_monitor(&self) -> Option<winit_core::monitor::MonitorHandle> {
None
}
fn listen_device_events(&self, _allowed: DeviceEvents) {}
fn set_control_flow(&self, control_flow: ControlFlow) {
self.control_flow.set(control_flow)
}
fn control_flow(&self) -> ControlFlow {
self.control_flow.get()
}
fn exit(&self) {
self.exit.set(true);
}
fn exiting(&self) -> bool {
self.exit.get()
}
fn owned_display_handle(&self) -> CoreOwnedDisplayHandle {
CoreOwnedDisplayHandle::new(Arc::new(OwnedDisplayHandle))
}
fn rwh_06_handle(&self) -> &dyn rwh_06::HasDisplayHandle {
self
}
}
impl rwh_06::HasDisplayHandle for ActiveEventLoop {
fn display_handle(&self) -> Result<rwh_06::DisplayHandle<'_>, rwh_06::HandleError> {
let raw = rwh_06::RawDisplayHandle::Orbital(rwh_06::OrbitalDisplayHandle::new());
unsafe { Ok(rwh_06::DisplayHandle::borrow_raw(raw)) }
}
}
#[derive(Clone)]
pub(crate) struct OwnedDisplayHandle;
impl rwh_06::HasDisplayHandle for OwnedDisplayHandle {
fn display_handle(&self) -> Result<rwh_06::DisplayHandle<'_>, rwh_06::HandleError> {
let raw = rwh_06::RawDisplayHandle::Orbital(rwh_06::OrbitalDisplayHandle::new());
unsafe { Ok(rwh_06::DisplayHandle::borrow_raw(raw)) }
}
}
#[derive(Default, Debug, Copy, Clone, PartialEq, Eq, Hash)]
pub struct PlatformSpecificEventLoopAttributes {}