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 ,
2021-02-23 18:35:38 -03:00
event ::{ InputEvent , KeyAction , MotionAction } ,
2020-05-06 15:27:49 +02:00
looper ::{ ForeignLooper , Poll , ThreadLooper } ,
} ;
use ndk_glue ::{ Event , Rect } ;
2021-11-30 17:50:23 +01:00
use raw_window_handle ::{ AndroidNdkHandle , RawWindowHandle } ;
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! {
2021-10-26 14:28:28 -07:00
static ref CONFIG : RwLock < Configuration > = RwLock ::new ( Configuration ::from_asset_manager (
& ndk_glue ::native_activity ( ) . asset_manager ( )
) ) ;
2021-06-05 12:47:08 +02:00
// If this is `Some()` a `Poll::Wake` is considered an `EventSource::Internal` with the event
// contained in the `Option`. The event is moved outside of the `Option` replacing it with a
// `None`.
//
// This allows us to inject event into the event loop without going through `ndk-glue` and
// calling unsafe function that should only be called by Android.
static ref INTERNAL_EVENT : RwLock < Option < InternalEvent > > = RwLock ::new ( None ) ;
}
enum InternalEvent {
RedrawRequested ,
2016-10-31 17:08:55 +01:00
}
2020-05-06 15:27:49 +02:00
enum EventSource {
Callback ,
InputQueue ,
User ,
2021-06-05 12:47:08 +02:00
Internal ( InternalEvent ) ,
2020-05-06 15:27:49 +02:00
}
2016-10-31 17:08:55 +01:00
2020-05-06 15:27:49 +02:00
fn poll ( poll : Poll ) -> Option < EventSource > {
match poll {
2021-01-13 23:02:55 +01:00
Poll ::Event { ident , .. } = > match ident {
2021-01-30 19:43:26 +01:00
ndk_glue ::NDK_GLUE_LOOPER_EVENT_PIPE_IDENT = > Some ( EventSource ::Callback ) ,
ndk_glue ::NDK_GLUE_LOOPER_INPUT_QUEUE_IDENT = > Some ( EventSource ::InputQueue ) ,
2020-05-06 15:27:49 +02:00
_ = > unreachable! ( ) ,
} ,
Poll ::Timeout = > None ,
2021-06-05 12:47:08 +02:00
Poll ::Wake = > Some (
INTERNAL_EVENT
. write ( )
. unwrap ( )
. take ( )
. map_or ( EventSource ::User , EventSource ::Internal ) ,
) ,
2020-05-06 15:27:49 +02:00
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 > > > ,
2020-06-17 15:55:52 +02:00
first_event : Option < EventSource > ,
start_cause : event ::StartCause ,
looper : ThreadLooper ,
running : bool ,
}
2022-02-16 22:09:03 +01:00
#[ derive(Default, Debug, Copy, Clone, PartialEq, Hash) ]
pub ( crate ) struct PlatformSpecificEventLoopAttributes { }
2020-06-17 15:55:52 +02:00
macro_rules ! call_event_handler {
( $event_handler :expr , $window_target :expr , $cf :expr , $event :expr ) = > { {
2022-01-11 01:23:20 +01:00
if let ControlFlow ::ExitWithCode ( code ) = $cf {
$event_handler ( $event , $window_target , & mut ControlFlow ::ExitWithCode ( code ) ) ;
2020-06-17 15:55:52 +02:00
} else {
2022-01-11 01:23:20 +01:00
$event_handler ( $event , $window_target , & mut $cf ) ;
2020-06-17 15:55:52 +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
impl < T : 'static > EventLoop < T > {
2022-02-16 22:09:03 +01:00
pub ( crate ) fn new ( _ : & PlatformSpecificEventLoopAttributes ) -> Self {
2020-05-06 15:27:49 +02:00
Self {
window_target : event_loop ::EventLoopWindowTarget {
p : EventLoopWindowTarget {
_marker : std ::marker ::PhantomData ,
} ,
_marker : std ::marker ::PhantomData ,
} ,
user_queue : Default ::default ( ) ,
2020-06-17 15:55:52 +02:00
first_event : None ,
start_cause : event ::StartCause ::Init ,
looper : ThreadLooper ::for_thread ( ) . unwrap ( ) ,
running : false ,
2020-05-06 15:27:49 +02:00
}
2016-10-31 17:08:55 +01:00
}
2020-06-17 15:55:52 +02:00
pub fn run < F > ( mut self , 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
{
2022-01-11 01:23:20 +01:00
let exit_code = self . run_return ( event_handler ) ;
::std ::process ::exit ( exit_code ) ;
2020-06-17 15:55:52 +02:00
}
2022-01-11 01:23:20 +01:00
pub fn run_return < F > ( & mut self , mut event_handler : F ) -> i32
2020-06-17 15:55:52 +02:00
where
F : FnMut ( event ::Event < '_ , T > , & event_loop ::EventLoopWindowTarget < T > , & mut ControlFlow ) ,
{
let mut control_flow = ControlFlow ::default ( ) ;
' event_loop : loop {
call_event_handler! (
event_handler ,
2020-05-06 15:27:49 +02:00
self . window_target ( ) ,
2020-06-17 15:55:52 +02:00
control_flow ,
event ::Event ::NewEvents ( self . start_cause )
2020-05-06 15:27:49 +02:00
) ;
let mut redraw = false ;
let mut resized = false ;
2020-06-17 15:55:52 +02:00
match self . first_event . take ( ) {
2020-05-06 15:27:49 +02:00
Some ( EventSource ::Callback ) = > match ndk_glue ::poll_events ( ) . unwrap ( ) {
Event ::WindowCreated = > {
2020-06-17 15:55:52 +02:00
call_event_handler! (
event_handler ,
self . window_target ( ) ,
control_flow ,
event ::Event ::Resumed
) ;
2020-05-06 15:27:49 +02:00
}
Event ::WindowResized = > resized = true ,
Event ::WindowRedrawNeeded = > redraw = true ,
Event ::WindowDestroyed = > {
2020-06-17 15:55:52 +02:00
call_event_handler! (
event_handler ,
self . window_target ( ) ,
control_flow ,
event ::Event ::Suspended
) ;
2020-05-06 15:27:49 +02:00
}
2020-06-17 15:55:52 +02:00
Event ::Pause = > self . running = false ,
Event ::Resume = > self . running = true ,
2020-05-06 15:27:49 +02:00
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 ,
} ,
} ;
2020-06-17 15:55:52 +02:00
call_event_handler! (
event_handler ,
self . window_target ( ) ,
control_flow ,
event
) ;
2020-05-06 15:27:49 +02:00
}
}
2020-10-08 19:44:41 +02:00
Event ::WindowHasFocus = > {
call_event_handler! (
event_handler ,
self . window_target ( ) ,
control_flow ,
event ::Event ::WindowEvent {
window_id : window ::WindowId ( WindowId ) ,
event : event ::WindowEvent ::Focused ( true ) ,
}
) ;
}
Event ::WindowLostFocus = > {
call_event_handler! (
event_handler ,
self . window_target ( ) ,
control_flow ,
event ::Event ::WindowEvent {
window_id : window ::WindowId ( WindowId ) ,
event : event ::WindowEvent ::Focused ( false ) ,
}
) ;
}
2020-05-06 15:27:49 +02:00
_ = > { }
} ,
Some ( EventSource ::InputQueue ) = > {
if let Some ( input_queue ) = ndk_glue ::input_queue ( ) . as_ref ( ) {
while let Some ( event ) = input_queue . get_event ( ) {
if let Some ( event ) = input_queue . pre_dispatch ( event ) {
2021-01-12 08:25:56 +01:00
let mut handled = true ;
2020-05-06 15:27:49 +02:00
let window_id = window ::WindowId ( WindowId ) ;
let device_id = event ::DeviceId ( DeviceId ) ;
match & event {
InputEvent ::MotionEvent ( motion_event ) = > {
let phase = match motion_event . action ( ) {
2020-11-28 17:41:11 +01:00
MotionAction ::Down | MotionAction ::PointerDown = > {
Some ( event ::TouchPhase ::Started )
}
MotionAction ::Up | MotionAction ::PointerUp = > {
Some ( event ::TouchPhase ::Ended )
}
2020-05-06 15:27:49 +02:00
MotionAction ::Move = > Some ( event ::TouchPhase ::Moved ) ,
MotionAction ::Cancel = > {
Some ( event ::TouchPhase ::Cancelled )
}
2021-01-12 08:25:56 +01:00
_ = > {
handled = false ;
None // TODO mouse events
}
2020-05-06 15:27:49 +02:00
} ;
if let Some ( phase ) = phase {
2020-12-02 21:13:42 +01:00
let pointers : Box <
dyn Iterator < Item = ndk ::event ::Pointer < '_ > > ,
> = match phase {
event ::TouchPhase ::Started
| event ::TouchPhase ::Ended = > Box ::new (
std ::iter ::once ( motion_event . pointer_at_index (
motion_event . pointer_index ( ) ,
) ) ,
) ,
event ::TouchPhase ::Moved
| event ::TouchPhase ::Cancelled = > {
Box ::new ( motion_event . pointers ( ) )
}
} ;
for pointer in pointers {
2020-11-28 17:41:11 +01:00
let location = PhysicalPosition {
x : pointer . x ( ) as _ ,
y : pointer . y ( ) as _ ,
} ;
let event = event ::Event ::WindowEvent {
window_id ,
event : event ::WindowEvent ::Touch (
event ::Touch {
device_id ,
phase ,
location ,
id : pointer . pointer_id ( ) as u64 ,
force : None ,
} ,
) ,
} ;
call_event_handler! (
event_handler ,
self . window_target ( ) ,
control_flow ,
event
) ;
}
2020-05-06 15:27:49 +02:00
}
}
2021-02-23 18:35:38 -03:00
InputEvent ::KeyEvent ( key ) = > {
let state = match key . action ( ) {
KeyAction ::Down = > event ::ElementState ::Pressed ,
KeyAction ::Up = > event ::ElementState ::Released ,
_ = > event ::ElementState ::Released ,
} ;
2021-03-30 21:27:32 +02:00
#[ allow(deprecated) ]
2021-02-23 18:35:38 -03:00
let event = event ::Event ::WindowEvent {
window_id ,
event : event ::WindowEvent ::KeyboardInput {
device_id ,
input : event ::KeyboardInput {
scancode : key . scan_code ( ) as u32 ,
state ,
virtual_keycode : None ,
modifiers : event ::ModifiersState ::default ( ) ,
} ,
is_synthetic : false ,
} ,
} ;
call_event_handler! (
event_handler ,
self . window_target ( ) ,
control_flow ,
event
) ;
2021-01-12 08:25:56 +01:00
}
2020-05-06 15:27:49 +02:00
} ;
2021-01-12 08:25:56 +01:00
input_queue . finish_event ( event , handled ) ;
2020-05-06 15:27:49 +02:00
}
}
}
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 ( ) {
2020-06-17 15:55:52 +02:00
call_event_handler! (
event_handler ,
2020-05-06 15:27:49 +02:00
self . window_target ( ) ,
2020-06-17 15:55:52 +02:00
control_flow ,
event ::Event ::UserEvent ( event )
2020-05-06 15:27:49 +02:00
) ;
2018-02-15 14:09:14 +01:00
}
2019-06-24 12:14:55 -04:00
}
2021-06-05 12:47:08 +02:00
Some ( EventSource ::Internal ( internal ) ) = > match internal {
InternalEvent ::RedrawRequested = > redraw = true ,
} ,
2020-08-12 20:56:28 +02:00
None = > { }
2020-05-06 15:27:49 +02:00
}
2020-06-17 15:55:52 +02:00
call_event_handler! (
event_handler ,
2020-05-06 15:27:49 +02:00
self . window_target ( ) ,
2020-06-17 15:55:52 +02:00
control_flow ,
event ::Event ::MainEventsCleared
2020-05-06 15:27:49 +02:00
) ;
2020-06-17 15:55:52 +02:00
if resized & & self . running {
2020-05-06 15:27:49 +02:00
let size = MonitorHandle . size ( ) ;
let event = event ::Event ::WindowEvent {
window_id : window ::WindowId ( WindowId ) ,
event : event ::WindowEvent ::Resized ( size ) ,
} ;
2020-06-17 15:55:52 +02:00
call_event_handler! ( event_handler , self . window_target ( ) , control_flow , event ) ;
2020-05-06 15:27:49 +02:00
}
2020-06-17 15:55:52 +02:00
if redraw & & self . running {
2020-05-06 15:27:49 +02:00
let event = event ::Event ::RedrawRequested ( window ::WindowId ( WindowId ) ) ;
2020-06-17 15:55:52 +02:00
call_event_handler! ( event_handler , self . window_target ( ) , control_flow , event ) ;
2020-05-06 15:27:49 +02:00
}
2020-06-17 15:55:52 +02:00
call_event_handler! (
event_handler ,
2020-05-06 15:27:49 +02:00
self . window_target ( ) ,
2020-06-17 15:55:52 +02:00
control_flow ,
event ::Event ::RedrawEventsCleared
2020-05-06 15:27:49 +02:00
) ;
2020-06-17 15:55:52 +02:00
match control_flow {
2022-01-11 01:23:20 +01:00
ControlFlow ::ExitWithCode ( code ) = > {
2020-06-17 15:55:52 +02:00
self . first_event = poll (
self . looper
. poll_once_timeout ( Duration ::from_millis ( 0 ) )
. unwrap ( ) ,
) ;
self . start_cause = event ::StartCause ::WaitCancelled {
start : Instant ::now ( ) ,
requested_resume : None ,
} ;
2022-01-11 01:23:20 +01:00
break 'event_loop code ;
2020-06-17 15:55:52 +02:00
}
2020-05-06 15:27:49 +02:00
ControlFlow ::Poll = > {
2020-08-12 20:56:28 +02:00
self . first_event = poll (
self . looper
. poll_all_timeout ( Duration ::from_millis ( 0 ) )
. unwrap ( ) ,
) ;
2020-06-17 15:55:52 +02:00
self . start_cause = event ::StartCause ::Poll ;
2020-05-06 15:27:49 +02:00
}
ControlFlow ::Wait = > {
2020-06-17 15:55:52 +02:00
self . first_event = poll ( self . looper . poll_all ( ) . unwrap ( ) ) ;
self . start_cause = event ::StartCause ::WaitCancelled {
2020-05-06 15:27:49 +02:00
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
} ;
2020-06-17 15:55:52 +02:00
self . first_event = poll ( self . looper . poll_all_timeout ( duration ) . unwrap ( ) ) ;
self . start_cause = if self . first_event . is_some ( ) {
2020-05-06 15:27:49 +02:00
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 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 > ,
}
2020-07-04 15:46:41 -04:00
impl < T : 'static > EventLoopWindowTarget < T > {
2020-09-07 20:20:47 +03:00
pub fn primary_monitor ( & self ) -> Option < monitor ::MonitorHandle > {
Some ( monitor ::MonitorHandle {
inner : MonitorHandle ,
} )
2020-07-04 15:46:41 -04:00
}
pub fn available_monitors ( & self ) -> VecDeque < MonitorHandle > {
let mut v = VecDeque ::with_capacity ( 1 ) ;
2020-09-07 20:20:47 +03:00
v . push_back ( MonitorHandle ) ;
2020-07-04 15:46:41 -04:00
v
}
}
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 WindowId ;
2018-12-21 09:51:48 -07:00
impl WindowId {
2021-08-30 19:40:02 +02:00
pub const 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 {
2021-08-30 19:40:02 +02:00
pub const 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-09-07 20:20:47 +03:00
pub fn primary_monitor ( & self ) -> Option < monitor ::MonitorHandle > {
Some ( monitor ::MonitorHandle {
inner : 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-09-07 20:09:24 +03:00
pub fn current_monitor ( & self ) -> Option < monitor ::MonitorHandle > {
Some ( monitor ::MonitorHandle {
2020-05-06 15:27:49 +02:00
inner : MonitorHandle ,
2020-09-07 20:09:24 +03:00
} )
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 ) {
2021-06-05 12:47:08 +02:00
* INTERNAL_EVENT . write ( ) . unwrap ( ) = Some ( InternalEvent ::RedrawRequested ) ;
ForeignLooper ::for_thread ( ) . unwrap ( ) . wake ( ) ;
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 ) {
2020-07-26 21:13:17 +00:00
warn! ( " 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
2021-01-27 20:01:17 +02:00
pub fn is_maximized ( & self ) -> bool {
false
}
2020-05-06 15:27:49 +02:00
pub fn set_fullscreen ( & self , _monitor : Option < window ::Fullscreen > ) {
2020-07-26 21:13:17 +00:00
warn! ( " 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 ) { }
2021-05-19 18:39:53 +02:00
pub fn focus_window ( & self ) { }
2020-11-27 03:03:08 +01:00
pub fn request_user_attention ( & self , _request_type : Option < window ::UserAttentionType > ) { }
2020-05-06 15:27:49 +02:00
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 ) { }
2021-03-07 10:43:23 +01:00
pub fn drag_window ( & self ) -> Result < ( ) , error ::ExternalError > {
Err ( error ::ExternalError ::NotSupported (
error ::NotSupportedError ::new ( ) ,
) )
}
2021-11-30 17:50:23 +01:00
pub fn raw_window_handle ( & self ) -> RawWindowHandle {
let mut handle = AndroidNdkHandle ::empty ( ) ;
if let Some ( native_window ) = ndk_glue ::native_window ( ) . as_ref ( ) {
handle . a_native_window = unsafe { native_window . ptr ( ) . as_mut ( ) as * mut _ as * mut _ }
2020-05-06 15:27:49 +02:00
} else {
2020-10-29 16:23:46 -05:00
panic! ( " Cannot get the native window, it's null and will always be null before Event::Resumed and after Event::Suspended. Make sure you only call this function between those events. " ) ;
2020-05-06 15:27:49 +02:00
} ;
2021-11-30 17:50:23 +01:00
RawWindowHandle ::AndroidNdk ( 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 ( ) ,
}
}
}