druid_win_shell/
win_main.rs1use std::mem;
18use std::ptr::null_mut;
19use std::sync::{Arc, Mutex};
20use winapi::shared::windef::*;
21use winapi::ctypes::c_int;
22use winapi::um::winbase::*;
23use winapi::um::winnt::*;
24use winapi::um::winuser::*;
25
26#[derive(Clone, Default)]
27pub struct RunLoopHandle(Arc<Mutex<RunLoopState>>);
28
29#[derive(Default)]
30struct RunLoopState {
31 listeners: Vec<Listener>,
32}
33
34unsafe impl Send for Listener {}
36struct Listener {
37 h: HANDLE,
38 callback: Box<FnMut()>,
39}
40
41pub struct RunLoop {
42 handle: RunLoopHandle,
43 accel: HACCEL,
44}
45
46impl RunLoop {
47 pub fn new() -> RunLoop {
48 RunLoop {
49 handle: Default::default(),
50 accel: null_mut(),
51 }
52 }
53
54 pub fn get_handle(&self) -> RunLoopHandle {
57 self.handle.clone()
58 }
59
60 pub fn set_accel(&mut self, accel: &[ACCEL]) {
62 unsafe {
63 self.accel = CreateAcceleratorTableW(accel as *const _ as *mut _,
64 accel.len() as c_int);
65 }
66 }
67
68 pub fn run(&mut self) {
69
70 unsafe {
71 loop {
72 let mut handles = Vec::new();
73 for listener in &self.handle.0.lock().unwrap().listeners {
74 handles.push(listener.h);
75 }
76 let len = handles.len() as u32;
77 let res = MsgWaitForMultipleObjectsEx(
78 len,
79 handles.as_ptr(),
80 INFINITE,
81 QS_ALLEVENTS,
82 0
83 );
84
85 if res >= WAIT_OBJECT_0 && res < WAIT_OBJECT_0 + len {
87 let ix = (res - WAIT_OBJECT_0) as usize;
88 (&mut self.handle.0.lock().unwrap().listeners[ix].callback)();
89 }
90
91 loop {
93 let mut msg = mem::uninitialized();
94 let res = PeekMessageW(&mut msg, null_mut(), 0, 0, PM_NOREMOVE);
96 if res == 0 {
97 break;
98 }
99 let res = GetMessageW(&mut msg, null_mut(), 0, 0);
100 if res <= 0 {
101 return;
102 }
103 if self.accel.is_null() ||
104 TranslateAcceleratorW(msg.hwnd, self.accel, &mut msg) == 0
105 {
106 TranslateMessage(&mut msg);
107 DispatchMessageW(&mut msg);
108 }
109 }
110 }
111 }
112 }
113}
114
115pub fn request_quit() {
117 unsafe {
118 PostQuitMessage(0);
119 }
120}
121
122impl RunLoopHandle {
123 pub unsafe fn add_handler<F>(&self, h: HANDLE, callback: F)
126 where F: FnMut() + 'static
127 {
128 let listener = Listener {
129 h,
130 callback: Box::new(callback),
131 };
132 self.0.lock().unwrap().listeners.push(listener);
133 }
134}