1use ::{_API};
12use capi::scdef::{GFX_LAYER};
13use capi::scdom::HELEMENT;
14use capi::sctypes::{HWINDOW, POINT, UINT, BOOL, RECT, LPCBYTE, LPVOID, INT};
15use capi::scmsg::*;
16
17pub use capi::scmsg::key_codes;
18pub use capi::scbehavior::{MOUSE_BUTTONS, MOUSE_EVENTS, KEYBOARD_STATES, KEY_EVENTS};
19
20
21#[derive(Debug)]
23pub enum Message {
24 Create {
26 backend: GFX_LAYER,
28 transparent: bool,
30 },
31
32 Destroy,
34
35 Size {
37 width: u32,
39 height: u32,
41 },
42
43 Resolution {
45 ppi: u32,
47 },
48
49 Focus {
51 enter: bool,
53 },
54
55 Heartbit {
57 milliseconds: u32,
59 },
60
61 Redraw,
63
64 Paint(PaintLayer),
66
67 RenderTo(RenderEvent),
69
70 #[cfg(any(windows, doc))]
71 RenderToDxgiSurface(DxgiRenderEvent),
73
74 Mouse(MouseEvent),
76
77 Keyboard(KeyboardEvent),
79}
80
81#[derive(Debug)]
83pub struct MouseEvent {
84 pub event: MOUSE_EVENTS,
86 pub button: MOUSE_BUTTONS,
88 pub modifiers: KEYBOARD_STATES,
90 pub pos: POINT,
92}
93
94#[derive(Debug)]
96pub struct KeyboardEvent {
97 pub event: KEY_EVENTS,
99 pub code: UINT,
106 pub modifiers: KEYBOARD_STATES,
108}
109
110#[derive(Debug)]
112pub struct PaintLayer {
113 pub element: HELEMENT,
115
116 pub is_foreground: bool,
118}
119
120pub struct RenderEvent
122{
123 pub layer: Option<PaintLayer>,
125
126 pub callback: Box<dyn Fn(&RECT, &[u8])>,
132}
133
134impl std::fmt::Debug for RenderEvent {
135 fn fmt(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result {
136 fmt
137 .debug_struct("RenderEvent")
138 .field("layer", &self.layer)
139 .field("callback", &"Box<dyn Fn>")
140 .finish()
141 }
142}
143
144#[cfg(any(windows, doc))]
145#[derive(Debug)]
146pub struct DxgiRenderEvent {
150 pub layer: Option<PaintLayer>,
152
153 pub surface: LPVOID,
155}
156
157
158pub fn handle_message(wnd: HWINDOW, event: Message) -> bool
162{
163 let ok = match event {
164 Message::Create { backend, transparent } => {
165 let msg = SCITER_X_MSG_CREATE {
166 header: SCITER_X_MSG_CODE::SXM_CREATE.into(),
167 backend,
168 transparent: transparent as BOOL,
169 };
170 (_API.SciterProcX)(wnd, &msg.header as *const _)
171 },
172
173 Message::Destroy => {
174 let msg = SCITER_X_MSG_DESTROY {
175 header: SCITER_X_MSG_CODE::SXM_DESTROY.into(),
176 };
177 (_API.SciterProcX)(wnd, &msg.header as *const _)
178 },
179
180 Message::Size { width, height} => {
181 let msg = SCITER_X_MSG_SIZE {
182 header: SCITER_X_MSG_CODE::SXM_SIZE.into(),
183 width,
184 height,
185 };
186 (_API.SciterProcX)(wnd, &msg.header as *const _)
187 },
188
189 Message::Resolution { ppi } => {
190 let msg = SCITER_X_MSG_RESOLUTION {
191 header: SCITER_X_MSG_CODE::SXM_RESOLUTION.into(),
192 ppi,
193 };
194 (_API.SciterProcX)(wnd, &msg.header as *const _)
195 },
196
197 Message::Focus { enter } => {
198 let msg = SCITER_X_MSG_FOCUS {
199 header: SCITER_X_MSG_CODE::SXM_FOCUS.into(),
200 enter: enter as BOOL,
201 };
202 (_API.SciterProcX)(wnd, &msg.header as *const _)
203 },
204
205 Message::Heartbit { milliseconds } => {
206 let msg = SCITER_X_MSG_HEARTBIT {
207 header: SCITER_X_MSG_CODE::SXM_HEARTBIT.into(),
208 time: milliseconds,
209 };
210 (_API.SciterProcX)(wnd, &msg.header as *const _)
211 },
212
213 Message::Mouse(params) => {
214 let msg = SCITER_X_MSG_MOUSE {
215 header: SCITER_X_MSG_CODE::SXM_MOUSE.into(),
216
217 event: params.event,
218 button: params.button,
219 modifiers: params.modifiers,
220 pos: params.pos,
221 };
222 (_API.SciterProcX)(wnd, &msg.header as *const _)
223 },
224
225 Message::Keyboard(params) => {
226 let msg = SCITER_X_MSG_KEY {
227 header: SCITER_X_MSG_CODE::SXM_KEY.into(),
228
229 event: params.event,
230 code: params.code,
231 modifiers: params.modifiers,
232 };
233 (_API.SciterProcX)(wnd, &msg.header as *const _)
234 },
235
236 Message::Redraw => {
237 use std::ptr;
238 let msg = SCITER_X_MSG_PAINT {
239 header: SCITER_X_MSG_CODE::SXM_PAINT.into(),
240 element: ptr::null_mut(),
241 isFore: true as BOOL,
242 targetType: SCITER_PAINT_TARGET_TYPE::SPT_DEFAULT,
243 context: ptr::null_mut(),
244 callback: None,
245 };
246 (_API.SciterProcX)(wnd, &msg.header as *const _)
247 },
248
249 Message::Paint(paint) => {
250 let msg = SCITER_X_MSG_PAINT {
251 header: SCITER_X_MSG_CODE::SXM_PAINT.into(),
252 element: paint.element,
253 isFore: paint.is_foreground as BOOL,
254 targetType: SCITER_PAINT_TARGET_TYPE::SPT_DEFAULT,
255 context: std::ptr::null_mut(),
256 callback: None,
257 };
258 (_API.SciterProcX)(wnd, &msg.header as *const _)
259 },
260
261 #[cfg(windows)]
262 Message::RenderToDxgiSurface(paint) => {
263 let layer = paint.layer.unwrap_or(PaintLayer {
264 element: std::ptr::null_mut(),
265 is_foreground: false,
266 });
267
268 let msg = SCITER_X_MSG_PAINT {
269 header: SCITER_X_MSG_CODE::SXM_PAINT.into(),
270 element: layer.element,
271 isFore: layer.is_foreground as BOOL,
272 targetType: SCITER_PAINT_TARGET_TYPE::SPT_SURFACE,
273 context: paint.surface,
274 callback: None,
275 };
276 (_API.SciterProcX)(wnd, &msg.header as *const _)
277 },
278
279 Message::RenderTo(paint) => {
280
281 struct Callback {
282 callback: Box<dyn Fn(&RECT, &[u8])>,
283 }
284
285 extern "system" fn inner(rgba: LPCBYTE, x: INT, y: INT, width: UINT, height: UINT, param: LPVOID)
286 {
287 assert!(!param.is_null());
288 assert!(!rgba.is_null());
289 if param.is_null() || rgba.is_null() { return; }
290
291 let bitmap_area = RECT {
292 left: x,
293 top: y,
294 right: x + width as INT,
295 bottom: y + height as INT,
296 };
297
298 let bitmap_size = width * height * 4;
299 let bitmap_data = unsafe { std::slice::from_raw_parts(rgba, bitmap_size as usize) };
300
301 let param = param as *const Callback;
302 let wrapper = unsafe { &*param };
303 (wrapper.callback)(&bitmap_area, bitmap_data);
304 }
305
306 let wrapper = Callback {
307 callback: paint.callback,
308 };
309 let param = &wrapper as *const _ as LPVOID;
310
311 let layer = paint.layer.unwrap_or(PaintLayer {
312 element: std::ptr::null_mut(),
313 is_foreground: false,
314 });
315
316 let msg = SCITER_X_MSG_PAINT {
317 header: SCITER_X_MSG_CODE::SXM_PAINT.into(),
318 element: layer.element,
319 isFore: layer.is_foreground as BOOL,
320 targetType: SCITER_PAINT_TARGET_TYPE::SPT_RECEIVER,
321 context: param,
322 callback: Some(inner),
323 };
324 (_API.SciterProcX)(wnd, &msg.header as *const _)
325 },
326
327 };
328
329 ok != 0
330}