2015-04-24 09:51:23 +02:00
|
|
|
#![cfg(target_os = "android")]
|
|
|
|
|
|
2020-05-06 15:27:49 +02:00
|
|
|
use crate::{
|
|
|
|
|
dpi::{PhysicalPosition, PhysicalSize, Position, Size},
|
|
|
|
|
error, event,
|
|
|
|
|
event_loop::{self, ControlFlow},
|
|
|
|
|
monitor, window,
|
|
|
|
|
};
|
|
|
|
|
use ndk::{
|
|
|
|
|
configuration::Configuration,
|
|
|
|
|
event::{InputEvent, MotionAction},
|
|
|
|
|
looper::{ForeignLooper, Poll, ThreadLooper},
|
|
|
|
|
};
|
|
|
|
|
use ndk_glue::{Event, Rect};
|
2019-06-21 11:33:15 -04:00
|
|
|
use std::{
|
|
|
|
|
collections::VecDeque,
|
2020-05-06 15:27:49 +02:00
|
|
|
sync::{Arc, Mutex, RwLock},
|
|
|
|
|
time::{Duration, Instant},
|
2019-06-21 11:33:15 -04:00
|
|
|
};
|
|
|
|
|
|
2020-05-06 15:27:49 +02:00
|
|
|
lazy_static! {
|
|
|
|
|
static ref CONFIG: RwLock<Configuration> = RwLock::new(Configuration::new());
|
2016-10-31 17:08:55 +01:00
|
|
|
}
|
|
|
|
|
|
2020-05-06 15:27:49 +02:00
|
|
|
enum EventSource {
|
|
|
|
|
Callback,
|
|
|
|
|
InputQueue,
|
|
|
|
|
User,
|
|
|
|
|
}
|
2016-10-31 17:08:55 +01:00
|
|
|
|
2020-05-06 15:27:49 +02:00
|
|
|
fn poll(poll: Poll) -> Option<EventSource> {
|
|
|
|
|
match poll {
|
|
|
|
|
Poll::Event { data, .. } => match data as usize {
|
|
|
|
|
0 => Some(EventSource::Callback),
|
|
|
|
|
1 => Some(EventSource::InputQueue),
|
|
|
|
|
_ => unreachable!(),
|
|
|
|
|
},
|
|
|
|
|
Poll::Timeout => None,
|
|
|
|
|
Poll::Wake => Some(EventSource::User),
|
|
|
|
|
Poll::Callback => unreachable!(),
|
2017-09-04 12:41:02 +02:00
|
|
|
}
|
2020-05-06 15:27:49 +02:00
|
|
|
}
|
2016-10-31 17:08:55 +01:00
|
|
|
|
2020-05-06 15:27:49 +02:00
|
|
|
pub struct EventLoop<T: 'static> {
|
|
|
|
|
window_target: event_loop::EventLoopWindowTarget<T>,
|
|
|
|
|
user_queue: Arc<Mutex<VecDeque<T>>>,
|
|
|
|
|
}
|
2016-10-31 17:08:55 +01:00
|
|
|
|
2020-05-06 15:27:49 +02:00
|
|
|
impl<T: 'static> EventLoop<T> {
|
|
|
|
|
pub fn new() -> Self {
|
|
|
|
|
Self {
|
|
|
|
|
window_target: event_loop::EventLoopWindowTarget {
|
|
|
|
|
p: EventLoopWindowTarget {
|
|
|
|
|
_marker: std::marker::PhantomData,
|
|
|
|
|
},
|
|
|
|
|
_marker: std::marker::PhantomData,
|
|
|
|
|
},
|
|
|
|
|
user_queue: Default::default(),
|
|
|
|
|
}
|
2016-10-31 17:08:55 +01:00
|
|
|
}
|
|
|
|
|
|
2020-05-06 15:27:49 +02:00
|
|
|
pub fn run<F>(self, mut event_handler: F) -> !
|
2019-06-21 11:33:15 -04:00
|
|
|
where
|
2020-05-06 15:27:49 +02:00
|
|
|
F: 'static
|
|
|
|
|
+ FnMut(event::Event<'_, T>, &event_loop::EventLoopWindowTarget<T>, &mut ControlFlow),
|
2017-09-04 12:41:02 +02:00
|
|
|
{
|
2020-05-06 15:27:49 +02:00
|
|
|
let mut cf = ControlFlow::default();
|
|
|
|
|
let mut first_event = None;
|
|
|
|
|
let mut start_cause = event::StartCause::Init;
|
|
|
|
|
let looper = ThreadLooper::for_thread().unwrap();
|
|
|
|
|
let mut running = false;
|
|
|
|
|
|
|
|
|
|
loop {
|
|
|
|
|
event_handler(
|
|
|
|
|
event::Event::NewEvents(start_cause),
|
|
|
|
|
self.window_target(),
|
|
|
|
|
&mut cf,
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
let mut redraw = false;
|
|
|
|
|
let mut resized = false;
|
|
|
|
|
|
|
|
|
|
match first_event.take() {
|
|
|
|
|
Some(EventSource::Callback) => match ndk_glue::poll_events().unwrap() {
|
|
|
|
|
Event::WindowCreated => {
|
|
|
|
|
event_handler(event::Event::Resumed, self.window_target(), &mut cf);
|
|
|
|
|
}
|
|
|
|
|
Event::WindowResized => resized = true,
|
|
|
|
|
Event::WindowRedrawNeeded => redraw = true,
|
|
|
|
|
Event::WindowDestroyed => {
|
|
|
|
|
event_handler(event::Event::Suspended, self.window_target(), &mut cf);
|
|
|
|
|
}
|
|
|
|
|
Event::Pause => running = false,
|
|
|
|
|
Event::Resume => running = true,
|
|
|
|
|
Event::ConfigChanged => {
|
|
|
|
|
let am = ndk_glue::native_activity().asset_manager();
|
|
|
|
|
let config = Configuration::from_asset_manager(&am);
|
|
|
|
|
let old_scale_factor = MonitorHandle.scale_factor();
|
|
|
|
|
*CONFIG.write().unwrap() = config;
|
|
|
|
|
let scale_factor = MonitorHandle.scale_factor();
|
|
|
|
|
if (scale_factor - old_scale_factor).abs() < f64::EPSILON {
|
|
|
|
|
let mut size = MonitorHandle.size();
|
|
|
|
|
let event = event::Event::WindowEvent {
|
|
|
|
|
window_id: window::WindowId(WindowId),
|
|
|
|
|
event: event::WindowEvent::ScaleFactorChanged {
|
|
|
|
|
new_inner_size: &mut size,
|
|
|
|
|
scale_factor,
|
|
|
|
|
},
|
|
|
|
|
};
|
|
|
|
|
event_handler(event, self.window_target(), &mut cf);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
_ => {}
|
|
|
|
|
},
|
|
|
|
|
Some(EventSource::InputQueue) => {
|
|
|
|
|
if let Some(input_queue) = ndk_glue::input_queue().as_ref() {
|
|
|
|
|
while let Some(event) = input_queue.get_event() {
|
|
|
|
|
println!("event {:?}", event);
|
|
|
|
|
if let Some(event) = input_queue.pre_dispatch(event) {
|
|
|
|
|
let window_id = window::WindowId(WindowId);
|
|
|
|
|
let device_id = event::DeviceId(DeviceId);
|
|
|
|
|
match &event {
|
|
|
|
|
InputEvent::MotionEvent(motion_event) => {
|
|
|
|
|
let phase = match motion_event.action() {
|
|
|
|
|
MotionAction::Down => Some(event::TouchPhase::Started),
|
|
|
|
|
MotionAction::Up => Some(event::TouchPhase::Ended),
|
|
|
|
|
MotionAction::Move => Some(event::TouchPhase::Moved),
|
|
|
|
|
MotionAction::Cancel => {
|
|
|
|
|
Some(event::TouchPhase::Cancelled)
|
|
|
|
|
}
|
|
|
|
|
_ => None, // TODO mouse events
|
|
|
|
|
};
|
|
|
|
|
let pointer = motion_event.pointer_at_index(0);
|
|
|
|
|
let location = PhysicalPosition {
|
|
|
|
|
x: pointer.x() as _,
|
|
|
|
|
y: pointer.y() as _,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
if let Some(phase) = phase {
|
|
|
|
|
let event = event::Event::WindowEvent {
|
|
|
|
|
window_id,
|
|
|
|
|
event: event::WindowEvent::Touch(event::Touch {
|
|
|
|
|
device_id,
|
|
|
|
|
phase,
|
|
|
|
|
location,
|
|
|
|
|
id: 0,
|
|
|
|
|
force: None,
|
|
|
|
|
}),
|
|
|
|
|
};
|
|
|
|
|
event_handler(event, self.window_target(), &mut cf);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
InputEvent::KeyEvent(_) => {} // TODO
|
|
|
|
|
};
|
|
|
|
|
input_queue.finish_event(event, true);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2019-06-24 12:14:55 -04:00
|
|
|
}
|
2020-05-06 15:27:49 +02:00
|
|
|
Some(EventSource::User) => {
|
|
|
|
|
let mut user_queue = self.user_queue.lock().unwrap();
|
|
|
|
|
while let Some(event) = user_queue.pop_front() {
|
|
|
|
|
event_handler(
|
|
|
|
|
event::Event::UserEvent(event),
|
|
|
|
|
self.window_target(),
|
|
|
|
|
&mut cf,
|
|
|
|
|
);
|
2018-02-15 14:09:14 +01:00
|
|
|
}
|
2019-06-24 12:14:55 -04:00
|
|
|
}
|
2020-05-06 15:27:49 +02:00
|
|
|
None => {}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
event_handler(
|
|
|
|
|
event::Event::MainEventsCleared,
|
|
|
|
|
self.window_target(),
|
|
|
|
|
&mut cf,
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
if resized && running {
|
|
|
|
|
let size = MonitorHandle.size();
|
|
|
|
|
let event = event::Event::WindowEvent {
|
|
|
|
|
window_id: window::WindowId(WindowId),
|
|
|
|
|
event: event::WindowEvent::Resized(size),
|
|
|
|
|
};
|
|
|
|
|
event_handler(event, self.window_target(), &mut cf);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if redraw && running {
|
|
|
|
|
let event = event::Event::RedrawRequested(window::WindowId(WindowId));
|
|
|
|
|
event_handler(event, self.window_target(), &mut cf);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
event_handler(
|
|
|
|
|
event::Event::RedrawEventsCleared,
|
|
|
|
|
self.window_target(),
|
|
|
|
|
&mut cf,
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
match cf {
|
|
|
|
|
ControlFlow::Exit => panic!(),
|
|
|
|
|
ControlFlow::Poll => {
|
|
|
|
|
start_cause = event::StartCause::Poll;
|
|
|
|
|
}
|
|
|
|
|
ControlFlow::Wait => {
|
|
|
|
|
first_event = poll(looper.poll_all().unwrap());
|
|
|
|
|
start_cause = event::StartCause::WaitCancelled {
|
|
|
|
|
start: Instant::now(),
|
|
|
|
|
requested_resume: None,
|
2018-02-15 14:09:14 +01:00
|
|
|
}
|
2019-06-24 12:14:55 -04:00
|
|
|
}
|
2020-05-06 15:27:49 +02:00
|
|
|
ControlFlow::WaitUntil(instant) => {
|
|
|
|
|
let start = Instant::now();
|
|
|
|
|
let duration = if instant <= start {
|
|
|
|
|
Duration::default()
|
2017-10-29 02:02:57 -04:00
|
|
|
} else {
|
2020-05-06 15:27:49 +02:00
|
|
|
instant - start
|
|
|
|
|
};
|
|
|
|
|
first_event = poll(looper.poll_all_timeout(duration).unwrap());
|
|
|
|
|
start_cause = if first_event.is_some() {
|
|
|
|
|
event::StartCause::WaitCancelled {
|
|
|
|
|
start,
|
|
|
|
|
requested_resume: Some(instant),
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
event::StartCause::ResumeTimeReached {
|
|
|
|
|
start,
|
|
|
|
|
requested_resume: instant,
|
|
|
|
|
}
|
2017-10-29 02:02:57 -04:00
|
|
|
}
|
2019-06-24 12:14:55 -04:00
|
|
|
}
|
2016-10-31 17:08:55 +01:00
|
|
|
}
|
2019-06-21 11:33:15 -04:00
|
|
|
}
|
2017-09-04 12:41:02 +02:00
|
|
|
}
|
|
|
|
|
|
2020-05-06 15:27:49 +02:00
|
|
|
pub fn window_target(&self) -> &event_loop::EventLoopWindowTarget<T> {
|
|
|
|
|
&self.window_target
|
2018-02-15 14:09:14 +01:00
|
|
|
}
|
|
|
|
|
|
2020-05-06 15:27:49 +02:00
|
|
|
pub fn primary_monitor(&self) -> MonitorHandle {
|
|
|
|
|
MonitorHandle
|
2016-10-31 17:08:55 +01:00
|
|
|
}
|
2017-09-04 12:41:02 +02:00
|
|
|
|
2020-05-06 15:27:49 +02:00
|
|
|
pub fn available_monitors(&self) -> VecDeque<MonitorHandle> {
|
|
|
|
|
let mut v = VecDeque::with_capacity(1);
|
|
|
|
|
v.push_back(self.primary_monitor());
|
|
|
|
|
v
|
2017-09-04 12:41:02 +02:00
|
|
|
}
|
2020-05-06 15:27:49 +02:00
|
|
|
|
|
|
|
|
pub fn create_proxy(&self) -> EventLoopProxy<T> {
|
|
|
|
|
EventLoopProxy {
|
|
|
|
|
queue: self.user_queue.clone(),
|
|
|
|
|
looper: ForeignLooper::for_thread().expect("called from event loop thread"),
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub struct EventLoopProxy<T: 'static> {
|
|
|
|
|
queue: Arc<Mutex<VecDeque<T>>>,
|
|
|
|
|
looper: ForeignLooper,
|
2017-09-04 12:41:02 +02:00
|
|
|
}
|
|
|
|
|
|
2020-05-06 15:27:49 +02:00
|
|
|
impl<T> EventLoopProxy<T> {
|
|
|
|
|
pub fn send_event(&self, event: T) -> Result<(), event_loop::EventLoopClosed<T>> {
|
|
|
|
|
self.queue.lock().unwrap().push_back(event);
|
|
|
|
|
self.looper.wake();
|
2017-09-04 12:41:02 +02:00
|
|
|
Ok(())
|
|
|
|
|
}
|
2016-10-31 17:08:55 +01:00
|
|
|
}
|
|
|
|
|
|
2020-05-06 15:27:49 +02:00
|
|
|
impl<T> Clone for EventLoopProxy<T> {
|
|
|
|
|
fn clone(&self) -> Self {
|
|
|
|
|
EventLoopProxy {
|
|
|
|
|
queue: self.queue.clone(),
|
|
|
|
|
looper: self.looper.clone(),
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub struct EventLoopWindowTarget<T: 'static> {
|
|
|
|
|
_marker: std::marker::PhantomData<T>,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
|
2017-09-04 12:41:02 +02:00
|
|
|
pub struct WindowId;
|
|
|
|
|
|
2018-12-21 09:51:48 -07:00
|
|
|
impl WindowId {
|
2020-05-06 15:27:49 +02:00
|
|
|
pub fn dummy() -> Self {
|
2018-12-21 09:51:48 -07:00
|
|
|
WindowId
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-05-06 15:27:49 +02:00
|
|
|
#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
|
2017-09-04 12:41:02 +02:00
|
|
|
pub struct DeviceId;
|
|
|
|
|
|
2018-12-21 09:51:48 -07:00
|
|
|
impl DeviceId {
|
2020-05-06 15:27:49 +02:00
|
|
|
pub fn dummy() -> Self {
|
2018-12-21 09:51:48 -07:00
|
|
|
DeviceId
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-05-06 15:27:49 +02:00
|
|
|
#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
|
|
|
|
|
pub struct PlatformSpecificWindowBuilderAttributes;
|
2017-09-04 12:41:02 +02:00
|
|
|
|
2020-05-06 15:27:49 +02:00
|
|
|
pub struct Window;
|
2018-06-14 19:42:18 -04:00
|
|
|
|
2020-05-06 15:27:49 +02:00
|
|
|
impl Window {
|
|
|
|
|
pub fn new<T: 'static>(
|
|
|
|
|
_el: &EventLoopWindowTarget<T>,
|
|
|
|
|
_window_attrs: window::WindowAttributes,
|
|
|
|
|
_: PlatformSpecificWindowBuilderAttributes,
|
|
|
|
|
) -> Result<Self, error::OsError> {
|
|
|
|
|
// FIXME this ignores requested window attributes
|
|
|
|
|
Ok(Self)
|
|
|
|
|
}
|
2018-06-14 19:42:18 -04:00
|
|
|
|
2020-05-06 15:27:49 +02:00
|
|
|
pub fn id(&self) -> WindowId {
|
|
|
|
|
WindowId
|
2018-06-14 19:42:18 -04:00
|
|
|
}
|
2016-10-31 17:08:55 +01:00
|
|
|
|
2020-05-06 15:27:49 +02:00
|
|
|
pub fn primary_monitor(&self) -> MonitorHandle {
|
|
|
|
|
MonitorHandle
|
2017-09-04 12:41:02 +02:00
|
|
|
}
|
2016-10-31 17:08:55 +01:00
|
|
|
|
2020-05-06 15:27:49 +02:00
|
|
|
pub fn available_monitors(&self) -> VecDeque<MonitorHandle> {
|
|
|
|
|
let mut v = VecDeque::with_capacity(1);
|
|
|
|
|
v.push_back(MonitorHandle);
|
|
|
|
|
v
|
2016-10-31 17:08:55 +01:00
|
|
|
}
|
2017-09-07 09:33:46 +01:00
|
|
|
|
2020-05-06 15:27:49 +02:00
|
|
|
pub fn current_monitor(&self) -> monitor::MonitorHandle {
|
|
|
|
|
monitor::MonitorHandle {
|
|
|
|
|
inner: MonitorHandle,
|
|
|
|
|
}
|
2017-09-07 09:33:46 +01:00
|
|
|
}
|
2017-10-17 14:56:38 +03:00
|
|
|
|
2020-01-03 14:52:27 -05:00
|
|
|
pub fn scale_factor(&self) -> f64 {
|
2020-05-06 15:27:49 +02:00
|
|
|
MonitorHandle.scale_factor()
|
2017-10-17 14:56:38 +03:00
|
|
|
}
|
2016-10-31 17:08:55 +01:00
|
|
|
|
2020-05-06 15:27:49 +02:00
|
|
|
pub fn request_redraw(&self) {
|
|
|
|
|
// TODO
|
2016-10-31 17:08:55 +01:00
|
|
|
}
|
|
|
|
|
|
2020-05-06 15:27:49 +02:00
|
|
|
pub fn inner_position(&self) -> Result<PhysicalPosition<i32>, error::NotSupportedError> {
|
|
|
|
|
Err(error::NotSupportedError::new())
|
2016-10-31 17:08:55 +01:00
|
|
|
}
|
|
|
|
|
|
2020-05-06 15:27:49 +02:00
|
|
|
pub fn outer_position(&self) -> Result<PhysicalPosition<i32>, error::NotSupportedError> {
|
|
|
|
|
Err(error::NotSupportedError::new())
|
2016-10-31 17:08:55 +01:00
|
|
|
}
|
|
|
|
|
|
2020-05-06 15:27:49 +02:00
|
|
|
pub fn set_outer_position(&self, _position: Position) {
|
|
|
|
|
// no effect
|
2016-10-31 17:08:55 +01:00
|
|
|
}
|
|
|
|
|
|
2020-05-06 15:27:49 +02:00
|
|
|
pub fn inner_size(&self) -> PhysicalSize<u32> {
|
|
|
|
|
self.outer_size()
|
2016-10-31 17:08:55 +01:00
|
|
|
}
|
|
|
|
|
|
2020-05-06 15:27:49 +02:00
|
|
|
pub fn set_inner_size(&self, _size: Size) {
|
|
|
|
|
panic!("Cannot set window size on Android");
|
2016-10-31 17:08:55 +01:00
|
|
|
}
|
|
|
|
|
|
2020-05-06 15:27:49 +02:00
|
|
|
pub fn outer_size(&self) -> PhysicalSize<u32> {
|
|
|
|
|
MonitorHandle.size()
|
2018-04-16 21:40:30 -04:00
|
|
|
}
|
|
|
|
|
|
2020-05-06 15:27:49 +02:00
|
|
|
pub fn set_min_inner_size(&self, _: Option<Size>) {}
|
2016-10-31 17:08:55 +01:00
|
|
|
|
2020-05-06 15:27:49 +02:00
|
|
|
pub fn set_max_inner_size(&self, _: Option<Size>) {}
|
2018-03-23 05:35:35 -04:00
|
|
|
|
2020-05-06 15:27:49 +02:00
|
|
|
pub fn set_title(&self, _title: &str) {}
|
2018-03-23 05:35:35 -04:00
|
|
|
|
2020-05-06 15:27:49 +02:00
|
|
|
pub fn set_visible(&self, _visibility: bool) {}
|
2018-06-14 19:42:18 -04:00
|
|
|
|
2020-05-06 15:27:49 +02:00
|
|
|
pub fn set_resizable(&self, _resizeable: bool) {}
|
2016-10-31 17:08:55 +01:00
|
|
|
|
2020-05-06 15:27:49 +02:00
|
|
|
pub fn set_minimized(&self, _minimized: bool) {}
|
2016-10-31 17:08:55 +01:00
|
|
|
|
2020-05-06 15:27:49 +02:00
|
|
|
pub fn set_maximized(&self, _maximized: bool) {}
|
2016-10-31 17:08:55 +01:00
|
|
|
|
2020-05-06 15:27:49 +02:00
|
|
|
pub fn set_fullscreen(&self, _monitor: Option<window::Fullscreen>) {
|
|
|
|
|
panic!("Cannot set fullscreen on Android");
|
2016-10-31 17:08:55 +01:00
|
|
|
}
|
|
|
|
|
|
2020-05-06 15:27:49 +02:00
|
|
|
pub fn fullscreen(&self) -> Option<window::Fullscreen> {
|
|
|
|
|
None
|
2016-10-31 17:08:55 +01:00
|
|
|
}
|
|
|
|
|
|
2020-05-06 15:27:49 +02:00
|
|
|
pub fn set_decorations(&self, _decorations: bool) {}
|
2018-06-18 12:32:18 -04:00
|
|
|
|
2020-05-06 15:27:49 +02:00
|
|
|
pub fn set_always_on_top(&self, _always_on_top: bool) {}
|
2016-10-31 17:08:55 +01:00
|
|
|
|
2020-05-06 15:27:49 +02:00
|
|
|
pub fn set_window_icon(&self, _window_icon: Option<crate::icon::Icon>) {}
|
2017-08-28 00:22:26 +01:00
|
|
|
|
2020-05-06 15:27:49 +02:00
|
|
|
pub fn set_ime_position(&self, _position: Position) {}
|
|
|
|
|
|
|
|
|
|
pub fn set_cursor_icon(&self, _: window::CursorIcon) {}
|
2019-12-22 01:04:11 -05:00
|
|
|
|
2020-05-06 15:27:49 +02:00
|
|
|
pub fn set_cursor_position(&self, _: Position) -> Result<(), error::ExternalError> {
|
|
|
|
|
Err(error::ExternalError::NotSupported(
|
|
|
|
|
error::NotSupportedError::new(),
|
|
|
|
|
))
|
2017-09-07 09:33:46 +01:00
|
|
|
}
|
|
|
|
|
|
2020-05-06 15:27:49 +02:00
|
|
|
pub fn set_cursor_grab(&self, _: bool) -> Result<(), error::ExternalError> {
|
|
|
|
|
Err(error::ExternalError::NotSupported(
|
|
|
|
|
error::NotSupportedError::new(),
|
|
|
|
|
))
|
2019-04-26 03:09:32 +10:00
|
|
|
}
|
|
|
|
|
|
2020-05-06 15:27:49 +02:00
|
|
|
pub fn set_cursor_visible(&self, _: bool) {}
|
|
|
|
|
|
|
|
|
|
pub fn raw_window_handle(&self) -> raw_window_handle::RawWindowHandle {
|
|
|
|
|
let a_native_window = if let Some(native_window) = ndk_glue::native_window().as_ref() {
|
|
|
|
|
unsafe { native_window.ptr().as_mut() as *mut _ as *mut _ }
|
|
|
|
|
} else {
|
|
|
|
|
panic!("native window null");
|
|
|
|
|
};
|
|
|
|
|
let mut handle = raw_window_handle::android::AndroidHandle::empty();
|
|
|
|
|
handle.a_native_window = a_native_window;
|
|
|
|
|
raw_window_handle::RawWindowHandle::Android(handle)
|
2017-08-28 01:43:34 +01:00
|
|
|
}
|
|
|
|
|
|
2020-05-06 15:27:49 +02:00
|
|
|
pub fn config(&self) -> Configuration {
|
|
|
|
|
CONFIG.read().unwrap().clone()
|
2017-12-22 07:50:46 -05:00
|
|
|
}
|
|
|
|
|
|
2020-05-06 15:27:49 +02:00
|
|
|
pub fn content_rect(&self) -> Rect {
|
|
|
|
|
ndk_glue::content_rect()
|
2018-05-20 10:24:05 -04:00
|
|
|
}
|
2020-05-06 15:27:49 +02:00
|
|
|
}
|
2018-05-20 10:24:05 -04:00
|
|
|
|
2020-05-06 15:27:49 +02:00
|
|
|
#[derive(Default, Clone, Debug)]
|
|
|
|
|
pub struct OsError;
|
|
|
|
|
|
|
|
|
|
use std::fmt::{self, Display, Formatter};
|
|
|
|
|
impl Display for OsError {
|
|
|
|
|
fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), fmt::Error> {
|
|
|
|
|
write!(fmt, "Android OS Error")
|
2018-05-07 17:36:21 -04:00
|
|
|
}
|
2020-05-06 15:27:49 +02:00
|
|
|
}
|
2018-05-07 17:36:21 -04:00
|
|
|
|
2020-05-06 15:27:49 +02:00
|
|
|
pub(crate) use crate::icon::NoIcon as PlatformIcon;
|
|
|
|
|
|
|
|
|
|
#[derive(Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
|
|
|
|
|
pub struct MonitorHandle;
|
|
|
|
|
|
|
|
|
|
impl MonitorHandle {
|
|
|
|
|
pub fn name(&self) -> Option<String> {
|
|
|
|
|
Some("Android Device".to_owned())
|
2018-05-17 21:28:30 -04:00
|
|
|
}
|
|
|
|
|
|
2020-05-06 15:27:49 +02:00
|
|
|
pub fn size(&self) -> PhysicalSize<u32> {
|
|
|
|
|
if let Some(native_window) = ndk_glue::native_window().as_ref() {
|
|
|
|
|
let width = native_window.width() as _;
|
|
|
|
|
let height = native_window.height() as _;
|
|
|
|
|
PhysicalSize::new(width, height)
|
|
|
|
|
} else {
|
|
|
|
|
PhysicalSize::new(0, 0)
|
2019-06-21 11:33:15 -04:00
|
|
|
}
|
2017-08-28 00:22:26 +01:00
|
|
|
}
|
2016-10-31 17:08:55 +01:00
|
|
|
|
2020-05-06 15:27:49 +02:00
|
|
|
pub fn position(&self) -> PhysicalPosition<i32> {
|
|
|
|
|
(0, 0).into()
|
2018-06-16 10:14:12 -04:00
|
|
|
}
|
|
|
|
|
|
2020-05-06 15:27:49 +02:00
|
|
|
pub fn scale_factor(&self) -> f64 {
|
|
|
|
|
let config = CONFIG.read().unwrap();
|
|
|
|
|
config
|
|
|
|
|
.density()
|
|
|
|
|
.map(|dpi| dpi as f64 / 160.0)
|
|
|
|
|
.unwrap_or(1.0)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub fn video_modes(&self) -> impl Iterator<Item = monitor::VideoMode> {
|
|
|
|
|
let size = self.size().into();
|
|
|
|
|
let mut v = Vec::new();
|
|
|
|
|
// FIXME this is not the real refresh rate
|
|
|
|
|
// (it is guarunteed to support 32 bit color though)
|
|
|
|
|
v.push(monitor::VideoMode {
|
|
|
|
|
video_mode: VideoMode {
|
|
|
|
|
size,
|
|
|
|
|
bit_depth: 32,
|
|
|
|
|
refresh_rate: 60,
|
|
|
|
|
monitor: self.clone(),
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
v.into_iter()
|
2018-06-16 10:14:12 -04:00
|
|
|
}
|
2020-05-06 15:27:49 +02:00
|
|
|
}
|
2018-06-16 10:14:12 -04:00
|
|
|
|
2020-05-06 15:27:49 +02:00
|
|
|
#[derive(Clone, Debug, Eq, Hash, PartialEq)]
|
|
|
|
|
pub struct VideoMode {
|
|
|
|
|
size: (u32, u32),
|
|
|
|
|
bit_depth: u16,
|
|
|
|
|
refresh_rate: u16,
|
|
|
|
|
monitor: MonitorHandle,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl VideoMode {
|
|
|
|
|
pub fn size(&self) -> PhysicalSize<u32> {
|
|
|
|
|
self.size.into()
|
2016-10-31 17:08:55 +01:00
|
|
|
}
|
2019-09-30 17:17:01 +02:00
|
|
|
|
2020-05-06 15:27:49 +02:00
|
|
|
pub fn bit_depth(&self) -> u16 {
|
|
|
|
|
self.bit_depth
|
2019-09-30 17:17:01 +02:00
|
|
|
}
|
2017-07-06 23:33:42 +02:00
|
|
|
|
2020-05-06 15:27:49 +02:00
|
|
|
pub fn refresh_rate(&self) -> u16 {
|
|
|
|
|
self.refresh_rate
|
|
|
|
|
}
|
2017-09-04 12:41:02 +02:00
|
|
|
|
2020-05-06 15:27:49 +02:00
|
|
|
pub fn monitor(&self) -> monitor::MonitorHandle {
|
|
|
|
|
monitor::MonitorHandle {
|
|
|
|
|
inner: self.monitor.clone(),
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|