1#![allow(non_snake_case, clippy::missing_safety_doc)]
8
9mod backend;
10pub mod evdev;
11mod ffi_types;
12mod quirks;
13mod udev;
14#[doc(hidden)]
15pub mod udev_callout;
16
17use crate::ffi_types::{
18 BackendKind, EventPayload, LibinputContext, LibinputDevice, LibinputDeviceGroup, LibinputEvent,
19 LibinputEventType, LibinputInterface, LibinputSeat, LibinputTabletPadModeGroup,
20 LibinputTabletTool,
21};
22
23use std::ffi::CStr;
24use std::os::unix::io::RawFd;
25
26extern "C" {
27 fn input_emit_log(
28 handler: *mut libc::c_void,
29 context: *mut libc::c_void,
30 priority: u32,
31 format: *const libc::c_char,
32 ...
33 );
34}
35
36#[repr(C)]
37pub struct LibinputConfigAreaRectangle {
38 pub x1: f64,
39 pub y1: f64,
40 pub x2: f64,
41 pub y2: f64,
42}
43
44unsafe fn populate_events(ctx: *mut LibinputContext) {
49 if ctx.is_null() {
50 return;
51 }
52 let ctx_ref = &mut *ctx;
53 let mut tmp: std::collections::VecDeque<LibinputEvent> = std::collections::VecDeque::new();
54 if let Ok(mut backend) = ctx_ref.backend.lock() {
55 backend.drain_into_queue(ctx, &mut tmp);
56 }
57 ctx_ref.event_queue.extend(tmp);
58}
59
60pub(crate) unsafe fn emit_debug_log(ctx: *mut LibinputContext, message: &str) {
61 if ctx.is_null() || (*ctx).log_priority > 10 {
62 return;
63 }
64 let Some(handler) = (*ctx).log_handler else {
65 return;
66 };
67 let Ok(message) = std::ffi::CString::new(format!("{}\n", message.replace('%', "%%"))) else {
68 return;
69 };
70 input_emit_log(
71 handler as *mut libc::c_void,
72 ctx.cast(),
73 10,
74 message.as_ptr(),
75 );
76}
77
78pub(crate) unsafe fn emit_error_log(ctx: *mut LibinputContext, message: &str) {
79 if ctx.is_null() || (*ctx).log_priority > 30 {
80 return;
81 }
82 let Some(handler) = (*ctx).log_handler else {
83 return;
84 };
85 let Ok(message) = std::ffi::CString::new(format!("{}\n", message.replace('%', "%%"))) else {
86 return;
87 };
88 input_emit_log(
89 handler as *mut libc::c_void,
90 ctx.cast(),
91 30,
92 message.as_ptr(),
93 );
94}
95
96pub(crate) unsafe fn emit_info_log(ctx: *mut LibinputContext, message: &str) {
97 if ctx.is_null() || (*ctx).log_priority > 20 {
98 return;
99 }
100 let Some(handler) = (*ctx).log_handler else {
101 return;
102 };
103 let Ok(message) = std::ffi::CString::new(format!("{}\n", message.replace('%', "%%"))) else {
104 return;
105 };
106 input_emit_log(
107 handler as *mut libc::c_void,
108 ctx.cast(),
109 20,
110 message.as_ptr(),
111 );
112}
113
114#[no_mangle]
119pub unsafe extern "C" fn libinput_udev_create_context(
120 interface: *const LibinputInterface,
121 user_data: *mut libc::c_void,
122 udev: *mut libc::c_void,
123) -> *mut LibinputContext {
124 if interface.is_null() || udev.is_null() {
125 return std::ptr::null_mut();
126 }
127 let ctx = Box::into_raw(Box::new(LibinputContext::new(
128 interface,
129 user_data,
130 BackendKind::Udev,
131 )));
132 (*(*ctx).seat).context = ctx;
133 ctx
134}
135
136#[no_mangle]
137pub unsafe extern "C" fn libinput_path_create_context(
138 interface: *const LibinputInterface,
139 user_data: *mut libc::c_void,
140) -> *mut LibinputContext {
141 if interface.is_null() {
142 return std::ptr::null_mut();
143 }
144 let ctx = Box::into_raw(Box::new(LibinputContext::new(
145 interface,
146 user_data,
147 BackendKind::Path,
148 )));
149 (*(*ctx).seat).context = ctx;
150 ctx
151}
152
153#[no_mangle]
154pub unsafe extern "C" fn libinput_ref(ctx: *mut LibinputContext) -> *mut LibinputContext {
155 if ctx.is_null() {
156 return std::ptr::null_mut();
157 }
158 (*ctx).inc_ref();
159 ctx
160}
161
162#[no_mangle]
163pub unsafe extern "C" fn libinput_unref(ctx: *mut LibinputContext) -> *mut LibinputContext {
164 if ctx.is_null() {
165 return std::ptr::null_mut();
166 }
167 if (*ctx).dec_ref() == 0 {
168 drop(Box::from_raw(ctx));
169 return std::ptr::null_mut();
170 }
171 ctx
172}
173
174#[no_mangle]
175pub unsafe extern "C" fn libinput_udev_assign_seat(
176 ctx: *mut LibinputContext,
177 seat_name: *const libc::c_char,
178) -> libc::c_int {
179 if ctx.is_null()
180 || seat_name.is_null()
181 || (*ctx).backend_kind != BackendKind::Udev
182 || (*ctx).seat_assigned
183 {
184 return -1;
185 }
186 let seat_name = CStr::from_ptr(seat_name);
187 if seat_name.to_bytes().len() > 255 {
188 return -1;
189 }
190 let name = seat_name.to_string_lossy().into_owned();
191 if let Ok(cname) = std::ffi::CString::new(name) {
192 (*(*ctx).seat).physical_name = cname;
193 }
194 (*ctx).seat_assigned = true;
195 let mut tmp: Vec<LibinputEvent> = Vec::new();
196 if let Ok(mut backend) = (*ctx).backend.lock() {
197 backend.scan_and_open(ctx, &mut tmp);
198 }
199 for ev in tmp {
200 (*ctx).event_queue.push_back(ev);
201 }
202 0
203}
204
205#[no_mangle]
206pub unsafe extern "C" fn libinput_path_add_device(
207 ctx: *mut LibinputContext,
208 path: *const libc::c_char,
209) -> *mut LibinputDevice {
210 if ctx.is_null() || path.is_null() || (*ctx).backend_kind != BackendKind::Path {
211 return std::ptr::null_mut();
212 }
213 let path = CStr::from_ptr(path);
214 if path.to_bytes().len() > libc::PATH_MAX as usize {
215 emit_error_log(
216 ctx,
217 &format!(
218 "client bug: Unexpected path, limited to {} characters.",
219 libc::PATH_MAX
220 ),
221 );
222 return std::ptr::null_mut();
223 }
224 let devnode = path.to_string_lossy().into_owned();
225 let p = std::path::PathBuf::from(&devnode);
226 use std::os::unix::fs::FileTypeExt;
227 if !p
228 .metadata()
229 .is_ok_and(|metadata| metadata.file_type().is_char_device())
230 {
231 emit_error_log(ctx, "failed to add device");
232 return std::ptr::null_mut();
233 }
234 let mut tmp: Vec<LibinputEvent> = Vec::new();
235 let old_len = (*ctx).devices.len();
236 if let Ok(mut backend) = (*ctx).backend.lock() {
237 backend.try_open(ctx, &p, &mut tmp);
238 }
239 for ev in tmp {
240 (*ctx).event_queue.push_back(ev);
241 }
242 if (*ctx).devices.len() == old_len + 1 {
243 if let Ok(mut backend) = (*ctx).backend.lock() {
244 backend.remember_path(&p);
245 }
246 emit_info_log(ctx, "device added");
247 (&(*ctx).devices)[old_len]
248 } else {
249 emit_error_log(ctx, "failed to add device");
250 std::ptr::null_mut()
251 }
252}
253
254#[no_mangle]
255pub unsafe extern "C" fn libinput_path_remove_device(dev: *mut LibinputDevice) {
256 if dev.is_null() {
257 return;
258 }
259 let ctx = (*dev).context;
260 if ctx.is_null() || (*ctx).backend_kind != BackendKind::Path {
261 return;
262 }
263 let path = std::path::PathBuf::from((*dev).devnode.to_string_lossy().into_owned());
264 let mut events = std::collections::VecDeque::new();
265 let removed = if let Ok(mut backend) = (*ctx).backend.lock() {
266 backend.forget_path(&path);
267 backend.remove_device(ctx, dev, &mut events)
268 } else {
269 false
270 };
271 if removed {
272 (*ctx).devices.retain(|candidate| *candidate != dev);
273 (*ctx).event_queue.extend(events);
274 libinput_device_unref(dev);
275 }
276}
277
278#[no_mangle]
283pub unsafe extern "C" fn libinput_get_fd(ctx: *mut LibinputContext) -> RawFd {
284 if ctx.is_null() {
285 return -1;
286 }
287 (*ctx).epoll_fd
288}
289
290#[no_mangle]
291pub unsafe extern "C" fn libinput_dispatch(ctx: *mut LibinputContext) -> libc::c_int {
292 if ctx.is_null() {
293 return -1;
294 }
295 let mut events: [libc::epoll_event; 16] = std::mem::zeroed();
296 libc::epoll_wait((*ctx).epoll_fd, events.as_mut_ptr(), 16, 0);
297 (*ctx).drain_fd();
298 populate_events(ctx);
299 0
300}
301
302#[no_mangle]
307pub unsafe extern "C" fn libinput_get_event(ctx: *mut LibinputContext) -> *mut LibinputEvent {
308 if ctx.is_null() {
309 return std::ptr::null_mut();
310 }
311 match (*ctx).event_queue.pop_front() {
312 Some(ev) => Box::into_raw(Box::new(ev)),
313 None => std::ptr::null_mut(),
314 }
315}
316
317#[no_mangle]
318pub unsafe extern "C" fn libinput_next_event_type(ctx: *mut LibinputContext) -> LibinputEventType {
319 if ctx.is_null() {
320 return LibinputEventType::LIBINPUT_EVENT_NONE;
321 }
322 (*ctx)
323 .event_queue
324 .front()
325 .map(|e| e.event_type)
326 .unwrap_or(LibinputEventType::LIBINPUT_EVENT_NONE)
327}
328
329#[no_mangle]
330pub unsafe extern "C" fn libinput_event_destroy(event: *mut LibinputEvent) {
331 if !event.is_null() {
332 drop(Box::from_raw(event));
333 }
334}
335
336#[no_mangle]
337pub unsafe extern "C" fn libinput_event_get_type(event: *const LibinputEvent) -> LibinputEventType {
338 if event.is_null() {
339 return LibinputEventType::LIBINPUT_EVENT_NONE;
340 }
341 (*event).event_type
342}
343
344#[no_mangle]
345pub unsafe extern "C" fn libinput_event_get_context(
346 event: *const LibinputEvent,
347) -> *mut LibinputContext {
348 if event.is_null() {
349 return std::ptr::null_mut();
350 }
351 (*event).context
352}
353
354#[no_mangle]
355pub unsafe extern "C" fn libinput_event_get_device(
356 event: *const LibinputEvent,
357) -> *mut LibinputDevice {
358 if event.is_null() {
359 return std::ptr::null_mut();
360 }
361 (*event).device
362}
363
364#[no_mangle]
365pub unsafe extern "C" fn libinput_event_get_device_notify_event(
366 event: *mut LibinputEvent,
367) -> *mut LibinputEvent {
368 if event.is_null() {
369 return std::ptr::null_mut();
370 }
371 match (*event).event_type {
372 LibinputEventType::LIBINPUT_EVENT_DEVICE_ADDED
373 | LibinputEventType::LIBINPUT_EVENT_DEVICE_REMOVED => event,
374 _ => std::ptr::null_mut(),
375 }
376}
377
378#[no_mangle]
379pub unsafe extern "C" fn libinput_event_device_notify_get_base_event(
380 event: *mut LibinputEvent,
381) -> *mut LibinputEvent {
382 event
383}
384
385#[no_mangle]
390pub unsafe extern "C" fn libinput_event_get_pointer_event(
391 event: *mut LibinputEvent,
392) -> *mut LibinputEvent {
393 if event.is_null() {
394 return std::ptr::null_mut();
395 }
396 match (*event).event_type {
397 LibinputEventType::LIBINPUT_EVENT_POINTER_MOTION
398 | LibinputEventType::LIBINPUT_EVENT_POINTER_MOTION_ABSOLUTE
399 | LibinputEventType::LIBINPUT_EVENT_POINTER_BUTTON
400 | LibinputEventType::LIBINPUT_EVENT_POINTER_AXIS
401 | LibinputEventType::LIBINPUT_EVENT_POINTER_SCROLL_WHEEL
402 | LibinputEventType::LIBINPUT_EVENT_POINTER_SCROLL_FINGER
403 | LibinputEventType::LIBINPUT_EVENT_POINTER_SCROLL_CONTINUOUS => event,
404 _ => std::ptr::null_mut(),
405 }
406}
407
408#[no_mangle]
409pub unsafe extern "C" fn libinput_event_pointer_get_base_event(
410 event: *mut LibinputEvent,
411) -> *mut LibinputEvent {
412 event
413}
414
415#[no_mangle]
416pub unsafe extern "C" fn libinput_event_pointer_get_time(event: *const LibinputEvent) -> u32 {
417 if event.is_null() {
418 return 0;
419 }
420 match &(*event).payload {
421 EventPayload::PointerMotion(e) => (e.time_usec / 1000) as u32,
422 EventPayload::PointerMotionAbsolute(e) => (e.time_usec / 1000) as u32,
423 EventPayload::PointerButton(e) => (e.time_usec / 1000) as u32,
424 EventPayload::PointerAxis(e) => (e.time_usec / 1000) as u32,
425 _ => 0,
426 }
427}
428
429#[no_mangle]
430pub unsafe extern "C" fn libinput_event_pointer_get_time_usec(event: *const LibinputEvent) -> u64 {
431 if event.is_null() {
432 return 0;
433 }
434 match &(*event).payload {
435 EventPayload::PointerMotion(e) => e.time_usec,
436 EventPayload::PointerMotionAbsolute(e) => e.time_usec,
437 EventPayload::PointerButton(e) => e.time_usec,
438 EventPayload::PointerAxis(e) => e.time_usec,
439 _ => 0,
440 }
441}
442
443#[no_mangle]
444pub unsafe extern "C" fn libinput_event_pointer_get_dx(event: *const LibinputEvent) -> f64 {
445 if event.is_null() {
446 return 0.0;
447 }
448 if let EventPayload::PointerMotion(e) = &(*event).payload {
449 e.dx
450 } else {
451 0.0
452 }
453}
454
455#[no_mangle]
456pub unsafe extern "C" fn libinput_event_pointer_get_dy(event: *const LibinputEvent) -> f64 {
457 if event.is_null() {
458 return 0.0;
459 }
460 if let EventPayload::PointerMotion(e) = &(*event).payload {
461 e.dy
462 } else {
463 0.0
464 }
465}
466
467#[no_mangle]
468pub unsafe extern "C" fn libinput_event_pointer_get_dx_unaccelerated(
469 event: *const LibinputEvent,
470) -> f64 {
471 if event.is_null() {
472 return 0.0;
473 }
474 if let EventPayload::PointerMotion(e) = &(*event).payload {
475 e.dx_unaccel
476 } else {
477 0.0
478 }
479}
480
481#[no_mangle]
482pub unsafe extern "C" fn libinput_event_pointer_get_dy_unaccelerated(
483 event: *const LibinputEvent,
484) -> f64 {
485 if event.is_null() {
486 return 0.0;
487 }
488 if let EventPayload::PointerMotion(e) = &(*event).payload {
489 e.dy_unaccel
490 } else {
491 0.0
492 }
493}
494
495#[no_mangle]
496pub unsafe extern "C" fn libinput_event_pointer_get_absolute_x(event: *const LibinputEvent) -> f64 {
497 if event.is_null() {
498 return 0.0;
499 }
500 if let EventPayload::PointerMotionAbsolute(e) = &(*event).payload {
501 e.abs_x
502 } else {
503 0.0
504 }
505}
506
507#[no_mangle]
508pub unsafe extern "C" fn libinput_event_pointer_get_absolute_y(event: *const LibinputEvent) -> f64 {
509 if event.is_null() {
510 return 0.0;
511 }
512 if let EventPayload::PointerMotionAbsolute(e) = &(*event).payload {
513 e.abs_y
514 } else {
515 0.0
516 }
517}
518
519#[no_mangle]
520pub unsafe extern "C" fn libinput_event_pointer_get_button(event: *const LibinputEvent) -> u32 {
521 if event.is_null() {
522 return 0;
523 }
524 if let EventPayload::PointerButton(e) = &(*event).payload {
525 e.button
526 } else {
527 0
528 }
529}
530
531#[no_mangle]
532pub unsafe extern "C" fn libinput_event_pointer_get_button_state(
533 event: *const LibinputEvent,
534) -> u32 {
535 if event.is_null() {
536 return 0;
537 }
538 if let EventPayload::PointerButton(e) = &(*event).payload {
539 e.state
540 } else {
541 0
542 }
543}
544
545#[no_mangle]
546pub unsafe extern "C" fn libinput_event_pointer_get_seat_button_count(
547 event: *const LibinputEvent,
548) -> u32 {
549 if event.is_null() {
550 return 0;
551 }
552 if let EventPayload::PointerButton(e) = &(*event).payload {
553 e.seat_button_count
554 } else {
555 0
556 }
557}
558
559#[no_mangle]
560pub unsafe extern "C" fn libinput_event_pointer_get_axis_value(
561 event: *const LibinputEvent,
562 axis: u32,
563) -> f64 {
564 if event.is_null() {
565 return 0.0;
566 }
567 if let EventPayload::PointerAxis(e) = &(*event).payload {
568 e.value(axis)
569 } else {
570 0.0
571 }
572}
573
574#[no_mangle]
575pub unsafe extern "C" fn libinput_event_pointer_get_axis_value_discrete(
576 event: *const LibinputEvent,
577 axis: u32,
578) -> f64 {
579 if event.is_null() {
580 return 0.0;
581 }
582 if let EventPayload::PointerAxis(e) = &(*event).payload {
583 e.value_discrete(axis) as f64
584 } else {
585 0.0
586 }
587}
588
589#[no_mangle]
590pub unsafe extern "C" fn libinput_event_pointer_get_axis_source(
591 event: *const LibinputEvent,
592) -> u32 {
593 if event.is_null() {
594 return 0;
595 }
596 if let EventPayload::PointerAxis(e) = &(*event).payload {
597 e.source
598 } else {
599 0
600 }
601}
602
603#[no_mangle]
604pub unsafe extern "C" fn libinput_event_pointer_has_axis(
605 event: *const LibinputEvent,
606 axis: u32,
607) -> libc::c_int {
608 if event.is_null() {
609 return 0;
610 }
611 matches!(&(*event).payload, EventPayload::PointerAxis(e) if e.has_axis(axis)) as libc::c_int
612}
613
614#[no_mangle]
619pub unsafe extern "C" fn libinput_event_get_keyboard_event(
620 event: *mut LibinputEvent,
621) -> *mut LibinputEvent {
622 if event.is_null() {
623 return std::ptr::null_mut();
624 }
625 if (*event).event_type == LibinputEventType::LIBINPUT_EVENT_KEYBOARD_KEY {
626 event
627 } else {
628 std::ptr::null_mut()
629 }
630}
631
632#[no_mangle]
633pub unsafe extern "C" fn libinput_event_keyboard_get_base_event(
634 event: *mut LibinputEvent,
635) -> *mut LibinputEvent {
636 event
637}
638
639#[no_mangle]
640pub unsafe extern "C" fn libinput_event_keyboard_get_time(event: *const LibinputEvent) -> u32 {
641 if event.is_null() {
642 return 0;
643 }
644 if let EventPayload::KeyboardKey(e) = &(*event).payload {
645 (e.time_usec / 1000) as u32
646 } else {
647 0
648 }
649}
650
651#[no_mangle]
652pub unsafe extern "C" fn libinput_event_keyboard_get_time_usec(event: *const LibinputEvent) -> u64 {
653 if event.is_null() {
654 return 0;
655 }
656 if let EventPayload::KeyboardKey(e) = &(*event).payload {
657 e.time_usec
658 } else {
659 0
660 }
661}
662
663#[no_mangle]
664pub unsafe extern "C" fn libinput_event_keyboard_get_key(event: *const LibinputEvent) -> u32 {
665 if event.is_null() {
666 return 0;
667 }
668 if let EventPayload::KeyboardKey(e) = &(*event).payload {
669 e.key
670 } else {
671 0
672 }
673}
674
675#[no_mangle]
676pub unsafe extern "C" fn libinput_event_keyboard_get_key_state(event: *const LibinputEvent) -> u32 {
677 if event.is_null() {
678 return 0;
679 }
680 if let EventPayload::KeyboardKey(e) = &(*event).payload {
681 e.state
682 } else {
683 0
684 }
685}
686
687#[no_mangle]
688pub unsafe extern "C" fn libinput_event_keyboard_get_seat_key_count(
689 event: *const LibinputEvent,
690) -> u32 {
691 if event.is_null() {
692 return 0;
693 }
694 if let EventPayload::KeyboardKey(e) = &(*event).payload {
695 e.seat_key_count
696 } else {
697 0
698 }
699}
700
701#[no_mangle]
706pub unsafe extern "C" fn libinput_event_get_touch_event(
707 event: *mut LibinputEvent,
708) -> *mut LibinputEvent {
709 if event.is_null() {
710 return std::ptr::null_mut();
711 }
712 match (*event).event_type {
713 LibinputEventType::LIBINPUT_EVENT_TOUCH_DOWN
714 | LibinputEventType::LIBINPUT_EVENT_TOUCH_UP
715 | LibinputEventType::LIBINPUT_EVENT_TOUCH_MOTION
716 | LibinputEventType::LIBINPUT_EVENT_TOUCH_CANCEL
717 | LibinputEventType::LIBINPUT_EVENT_TOUCH_FRAME => event,
718 _ => std::ptr::null_mut(),
719 }
720}
721
722#[no_mangle]
723pub unsafe extern "C" fn libinput_event_touch_get_base_event(
724 event: *mut LibinputEvent,
725) -> *mut LibinputEvent {
726 event
727}
728
729#[no_mangle]
730pub unsafe extern "C" fn libinput_event_touch_get_time(event: *const LibinputEvent) -> u32 {
731 if event.is_null() {
732 return 0;
733 }
734 match &(*event).payload {
735 EventPayload::TouchDown(e)
736 | EventPayload::TouchUp(e)
737 | EventPayload::TouchMotion(e)
738 | EventPayload::TouchCancel(e) => (e.time_usec / 1000) as u32,
739 EventPayload::TouchFrame { time_usec } => (*time_usec / 1000) as u32,
740 _ => 0,
741 }
742}
743
744#[no_mangle]
745pub unsafe extern "C" fn libinput_event_touch_get_time_usec(event: *const LibinputEvent) -> u64 {
746 if event.is_null() {
747 return 0;
748 }
749 match &(*event).payload {
750 EventPayload::TouchDown(e)
751 | EventPayload::TouchUp(e)
752 | EventPayload::TouchMotion(e)
753 | EventPayload::TouchCancel(e) => e.time_usec,
754 EventPayload::TouchFrame { time_usec } => *time_usec,
755 _ => 0,
756 }
757}
758
759#[no_mangle]
760pub unsafe extern "C" fn libinput_event_touch_get_slot(event: *const LibinputEvent) -> i32 {
761 if event.is_null() {
762 return -1;
763 }
764 match &(*event).payload {
765 EventPayload::TouchDown(e) | EventPayload::TouchMotion(e) | EventPayload::TouchUp(e) => {
766 e.slot
767 }
768 _ => -1,
769 }
770}
771
772#[no_mangle]
773pub unsafe extern "C" fn libinput_event_touch_get_seat_slot(event: *const LibinputEvent) -> i32 {
774 if event.is_null() {
775 return -1;
776 }
777 match &(*event).payload {
778 EventPayload::TouchDown(e) | EventPayload::TouchMotion(e) | EventPayload::TouchUp(e) => {
779 e.seat_slot
780 }
781 _ => -1,
782 }
783}
784
785#[no_mangle]
786pub unsafe extern "C" fn libinput_event_touch_get_x(event: *const LibinputEvent) -> f64 {
787 if event.is_null() {
788 return 0.0;
789 }
790 match &(*event).payload {
791 EventPayload::TouchDown(e) | EventPayload::TouchMotion(e) => {
792 let device = (*event).device;
793 if !device.is_null() {
794 if let (Some((minimum, _)), Some(resolution)) =
795 ((*device).abs_x_range, (*device).abs_x_resolution)
796 {
797 return (e.x - minimum as f64) / resolution as f64;
798 }
799 }
800 e.x
801 }
802 _ => 0.0,
803 }
804}
805
806#[no_mangle]
807pub unsafe extern "C" fn libinput_event_touch_get_y(event: *const LibinputEvent) -> f64 {
808 if event.is_null() {
809 return 0.0;
810 }
811 match &(*event).payload {
812 EventPayload::TouchDown(e) | EventPayload::TouchMotion(e) => {
813 let device = (*event).device;
814 if !device.is_null() {
815 if let (Some((minimum, _)), Some(resolution)) =
816 ((*device).abs_y_range, (*device).abs_y_resolution)
817 {
818 return (e.y - minimum as f64) / resolution as f64;
819 }
820 }
821 e.y
822 }
823 _ => 0.0,
824 }
825}
826
827unsafe fn transformed_touch_coordinates(event: *const LibinputEvent) -> Option<(f64, f64)> {
828 let touch = match &(*event).payload {
829 EventPayload::TouchDown(e) | EventPayload::TouchMotion(e) => e,
830 _ => return None,
831 };
832 let device = (*event).device;
833 if device.is_null() {
834 return None;
835 }
836 let ((xmin, xmax), (ymin, ymax)) = ((*device).abs_x_range?, (*device).abs_y_range?);
837 let x_span = (xmax as i64 - xmin as i64 + 1).max(1) as f64;
838 let y_span = (ymax as i64 - ymin as i64 + 1).max(1) as f64;
839 let x = (touch.x - xmin as f64) / x_span;
840 let y = (touch.y - ymin as f64) / y_span;
841 let matrix = (*device).calibration;
842 Some((
843 matrix[0] as f64 * x + matrix[1] as f64 * y + matrix[2] as f64,
844 matrix[3] as f64 * x + matrix[4] as f64 * y + matrix[5] as f64,
845 ))
846}
847
848#[no_mangle]
849pub unsafe extern "C" fn libinput_event_touch_get_x_transformed(
850 event: *const LibinputEvent,
851 width: u32,
852) -> f64 {
853 if event.is_null() {
854 return 0.0;
855 }
856 transformed_touch_coordinates(event)
857 .map(|(x, _)| x * width as f64)
858 .unwrap_or(0.0)
859}
860
861#[no_mangle]
862pub unsafe extern "C" fn libinput_event_touch_get_y_transformed(
863 event: *const LibinputEvent,
864 height: u32,
865) -> f64 {
866 if event.is_null() {
867 return 0.0;
868 }
869 transformed_touch_coordinates(event)
870 .map(|(_, y)| y * height as f64)
871 .unwrap_or(0.0)
872}
873
874#[no_mangle]
879pub unsafe extern "C" fn libinput_event_get_gesture_event(
880 event: *mut LibinputEvent,
881) -> *mut LibinputEvent {
882 if event.is_null() {
883 return std::ptr::null_mut();
884 }
885 match (*event).event_type {
886 LibinputEventType::LIBINPUT_EVENT_GESTURE_SWIPE_BEGIN
887 | LibinputEventType::LIBINPUT_EVENT_GESTURE_SWIPE_UPDATE
888 | LibinputEventType::LIBINPUT_EVENT_GESTURE_SWIPE_END
889 | LibinputEventType::LIBINPUT_EVENT_GESTURE_PINCH_BEGIN
890 | LibinputEventType::LIBINPUT_EVENT_GESTURE_PINCH_UPDATE
891 | LibinputEventType::LIBINPUT_EVENT_GESTURE_PINCH_END
892 | LibinputEventType::LIBINPUT_EVENT_GESTURE_HOLD_BEGIN
893 | LibinputEventType::LIBINPUT_EVENT_GESTURE_HOLD_END => event,
894 _ => std::ptr::null_mut(),
895 }
896}
897
898#[no_mangle]
899pub unsafe extern "C" fn libinput_event_gesture_get_base_event(
900 event: *mut LibinputEvent,
901) -> *mut LibinputEvent {
902 event
903}
904
905#[no_mangle]
906pub unsafe extern "C" fn libinput_event_gesture_get_time(event: *const LibinputEvent) -> u32 {
907 if event.is_null() {
908 return 0;
909 }
910 match &(*event).payload {
911 EventPayload::GestureSwipeBegin(e)
912 | EventPayload::GestureSwipeUpdate(e)
913 | EventPayload::GestureSwipeEnd(e)
914 | EventPayload::GesturePinchBegin(e)
915 | EventPayload::GesturePinchUpdate(e)
916 | EventPayload::GesturePinchEnd(e)
917 | EventPayload::GestureHoldBegin(e)
918 | EventPayload::GestureHoldEnd(e) => (e.time_usec / 1000) as u32,
919 _ => 0,
920 }
921}
922
923#[no_mangle]
924pub unsafe extern "C" fn libinput_event_gesture_get_time_usec(event: *const LibinputEvent) -> u64 {
925 if event.is_null() {
926 return 0;
927 }
928 match &(*event).payload {
929 EventPayload::GestureSwipeBegin(e)
930 | EventPayload::GestureSwipeUpdate(e)
931 | EventPayload::GestureSwipeEnd(e)
932 | EventPayload::GesturePinchBegin(e)
933 | EventPayload::GesturePinchUpdate(e)
934 | EventPayload::GesturePinchEnd(e)
935 | EventPayload::GestureHoldBegin(e)
936 | EventPayload::GestureHoldEnd(e) => e.time_usec,
937 _ => 0,
938 }
939}
940
941#[no_mangle]
942pub unsafe extern "C" fn libinput_event_gesture_get_finger_count(
943 event: *const LibinputEvent,
944) -> libc::c_int {
945 if event.is_null() {
946 return 0;
947 }
948 match &(*event).payload {
949 EventPayload::GestureSwipeBegin(e)
950 | EventPayload::GestureSwipeUpdate(e)
951 | EventPayload::GestureSwipeEnd(e)
952 | EventPayload::GesturePinchBegin(e)
953 | EventPayload::GesturePinchUpdate(e)
954 | EventPayload::GesturePinchEnd(e)
955 | EventPayload::GestureHoldBegin(e)
956 | EventPayload::GestureHoldEnd(e) => e.finger_count,
957 _ => 0,
958 }
959}
960
961#[no_mangle]
962pub unsafe extern "C" fn libinput_event_gesture_get_dx(event: *const LibinputEvent) -> f64 {
963 if event.is_null() {
964 return 0.0;
965 }
966 match &(*event).payload {
967 EventPayload::GestureSwipeUpdate(e) | EventPayload::GesturePinchUpdate(e) => e.dx,
968 _ => 0.0,
969 }
970}
971
972#[no_mangle]
973pub unsafe extern "C" fn libinput_event_gesture_get_dy(event: *const LibinputEvent) -> f64 {
974 if event.is_null() {
975 return 0.0;
976 }
977 match &(*event).payload {
978 EventPayload::GestureSwipeUpdate(e) | EventPayload::GesturePinchUpdate(e) => e.dy,
979 _ => 0.0,
980 }
981}
982
983#[no_mangle]
984pub unsafe extern "C" fn libinput_event_gesture_get_dx_unaccelerated(
985 event: *const LibinputEvent,
986) -> f64 {
987 if event.is_null() {
988 return 0.0;
989 }
990 match &(*event).payload {
991 EventPayload::GestureSwipeUpdate(e) | EventPayload::GesturePinchUpdate(e) => e.dx / 1.2,
992 _ => 0.0,
993 }
994}
995
996#[no_mangle]
997pub unsafe extern "C" fn libinput_event_gesture_get_dy_unaccelerated(
998 event: *const LibinputEvent,
999) -> f64 {
1000 if event.is_null() {
1001 return 0.0;
1002 }
1003 match &(*event).payload {
1004 EventPayload::GestureSwipeUpdate(e) | EventPayload::GesturePinchUpdate(e) => e.dy / 1.2,
1005 _ => 0.0,
1006 }
1007}
1008
1009#[no_mangle]
1010pub unsafe extern "C" fn libinput_event_gesture_get_scale(event: *const LibinputEvent) -> f64 {
1011 if event.is_null() {
1012 return 1.0;
1013 }
1014 match &(*event).payload {
1015 EventPayload::GesturePinchUpdate(e) | EventPayload::GesturePinchEnd(e) => e.scale,
1016 _ => 1.0,
1017 }
1018}
1019
1020#[no_mangle]
1021pub unsafe extern "C" fn libinput_event_gesture_get_angle_delta(
1022 event: *const LibinputEvent,
1023) -> f64 {
1024 if event.is_null() {
1025 return 0.0;
1026 }
1027 match &(*event).payload {
1028 EventPayload::GesturePinchUpdate(e) => e.angle,
1029 _ => 0.0,
1030 }
1031}
1032
1033#[no_mangle]
1034pub unsafe extern "C" fn libinput_event_gesture_get_cancelled(
1035 event: *const LibinputEvent,
1036) -> libc::c_int {
1037 if event.is_null() {
1038 return 0;
1039 }
1040 match &(*event).payload {
1041 EventPayload::GestureSwipeEnd(e)
1042 | EventPayload::GesturePinchEnd(e)
1043 | EventPayload::GestureHoldEnd(e) => e.cancelled as libc::c_int,
1044 _ => 0,
1045 }
1046}
1047
1048#[no_mangle]
1053pub unsafe extern "C" fn libinput_event_get_switch_event(
1054 event: *mut LibinputEvent,
1055) -> *mut LibinputEvent {
1056 if event.is_null() {
1057 return std::ptr::null_mut();
1058 }
1059 if (*event).event_type == LibinputEventType::LIBINPUT_EVENT_SWITCH_TOGGLE {
1060 event
1061 } else {
1062 std::ptr::null_mut()
1063 }
1064}
1065
1066#[no_mangle]
1067pub unsafe extern "C" fn libinput_event_switch_get_base_event(
1068 event: *mut LibinputEvent,
1069) -> *mut LibinputEvent {
1070 event
1071}
1072
1073#[no_mangle]
1074pub unsafe extern "C" fn libinput_event_switch_get_switch(event: *const LibinputEvent) -> u32 {
1075 if event.is_null() {
1076 return 0;
1077 }
1078 if let EventPayload::SwitchToggle(e) = &(*event).payload {
1079 e.switch
1080 } else {
1081 0
1082 }
1083}
1084
1085#[no_mangle]
1086pub unsafe extern "C" fn libinput_event_switch_get_switch_state(
1087 event: *const LibinputEvent,
1088) -> u32 {
1089 if event.is_null() {
1090 return 0;
1091 }
1092 if let EventPayload::SwitchToggle(e) = &(*event).payload {
1093 e.state
1094 } else {
1095 0
1096 }
1097}
1098
1099#[no_mangle]
1104pub unsafe extern "C" fn libinput_device_ref(dev: *mut LibinputDevice) -> *mut LibinputDevice {
1105 if dev.is_null() {
1106 return std::ptr::null_mut();
1107 }
1108 let current = (*dev)
1109 .refcount
1110 .fetch_add(1, std::sync::atomic::Ordering::SeqCst);
1111 (*dev).abi.refcount = current + 1;
1112 dev
1113}
1114
1115#[no_mangle]
1116pub unsafe extern "C" fn libinput_device_unref(dev: *mut LibinputDevice) -> *mut LibinputDevice {
1117 if dev.is_null() {
1118 return std::ptr::null_mut();
1119 }
1120 let remaining = (*dev)
1121 .refcount
1122 .fetch_sub(1, std::sync::atomic::Ordering::SeqCst)
1123 - 1;
1124 (*dev).abi.refcount = remaining;
1125 if remaining <= 0 {
1126 drop(Box::from_raw(dev));
1127 std::ptr::null_mut()
1128 } else {
1129 dev
1130 }
1131}
1132
1133#[no_mangle]
1134pub unsafe extern "C" fn libinput_device_get_name(
1135 dev: *const LibinputDevice,
1136) -> *const libc::c_char {
1137 if dev.is_null() {
1138 return std::ptr::null();
1139 }
1140 (*dev).name.as_ptr()
1141}
1142
1143#[no_mangle]
1144pub unsafe extern "C" fn libinput_device_get_sysname(
1145 dev: *const LibinputDevice,
1146) -> *const libc::c_char {
1147 if dev.is_null() {
1148 return std::ptr::null();
1149 }
1150 (*dev).sysname.as_ptr()
1151}
1152
1153#[no_mangle]
1154pub unsafe extern "C" fn libinput_device_get_output_name(
1155 dev: *const LibinputDevice,
1156) -> *const libc::c_char {
1157 if dev.is_null() {
1158 return std::ptr::null();
1159 }
1160 (*dev)
1161 .output_name
1162 .as_ref()
1163 .map_or(std::ptr::null(), |name| name.as_ptr())
1164}
1165
1166#[no_mangle]
1167pub unsafe extern "C" fn libinput_device_get_id_vendor(dev: *const LibinputDevice) -> libc::c_uint {
1168 if dev.is_null() {
1169 return 0;
1170 }
1171 (*dev).vendor_id
1172}
1173
1174#[no_mangle]
1175pub unsafe extern "C" fn libinput_device_get_id_product(
1176 dev: *const LibinputDevice,
1177) -> libc::c_uint {
1178 if dev.is_null() {
1179 return 0;
1180 }
1181 (*dev).product_id
1182}
1183
1184#[no_mangle]
1185pub unsafe extern "C" fn libinput_device_get_context(
1186 dev: *const LibinputDevice,
1187) -> *mut LibinputContext {
1188 if dev.is_null() {
1189 return std::ptr::null_mut();
1190 }
1191 (*dev).context
1192}
1193
1194#[no_mangle]
1195pub unsafe extern "C" fn libinput_device_get_devnode(
1196 dev: *const LibinputDevice,
1197) -> *const libc::c_char {
1198 if dev.is_null() {
1199 return std::ptr::null();
1200 }
1201 (*dev).devnode.as_ptr()
1202}
1203
1204#[no_mangle]
1205pub unsafe extern "C" fn libinput_device_touch_get_touch_count(
1206 dev: *const LibinputDevice,
1207) -> libc::c_int {
1208 if dev.is_null() || !(*dev).has_touch {
1209 return -1;
1210 }
1211 (*dev).touch_count
1212}
1213
1214#[no_mangle]
1215pub unsafe extern "C" fn libinput_device_has_capability(
1216 dev: *const LibinputDevice,
1217 capability: u32,
1218) -> libc::c_int {
1219 if dev.is_null() {
1220 return 0;
1221 }
1222 let has = match capability {
1223 0 => (*dev).has_keyboard,
1224 1 => (*dev).has_pointer,
1225 2 => (*dev).has_touch,
1226 3 => (*dev).has_tablet,
1227 4 => (*dev).has_tablet_pad,
1228 5 => (*dev).has_gesture,
1229 6 => (*dev).has_switch,
1230 _ => false,
1231 };
1232 has as libc::c_int
1233}
1234
1235#[no_mangle]
1240pub unsafe extern "C" fn libinput_device_config_tap_get_finger_count(
1241 dev: *const LibinputDevice,
1242) -> libc::c_int {
1243 if dev.is_null() {
1244 return 0;
1245 }
1246 (*dev).tap_finger_count
1247}
1248
1249#[no_mangle]
1250pub unsafe extern "C" fn libinput_device_config_tap_set_enabled(
1251 dev: *mut LibinputDevice,
1252 enabled: u32,
1253) -> u32 {
1254 if dev.is_null() {
1255 return 1;
1256 }
1257 if enabled > 1 {
1258 return 2;
1259 }
1260 if (*dev).tap_finger_count == 0 {
1261 return if enabled == 0 { 0 } else { 1 };
1262 }
1263 (*dev).tap_enabled = enabled != 0;
1264 0
1265}
1266
1267#[no_mangle]
1268pub unsafe extern "C" fn libinput_device_config_tap_get_enabled(dev: *const LibinputDevice) -> u32 {
1269 if dev.is_null() {
1270 return 0;
1271 }
1272 (*dev).tap_enabled as u32
1273}
1274
1275#[no_mangle]
1276pub unsafe extern "C" fn libinput_device_config_tap_get_default_enabled(
1277 dev: *const LibinputDevice,
1278) -> u32 {
1279 if dev.is_null() {
1280 return 0;
1281 }
1282 (*dev).tap_default_enabled as u32
1283}
1284
1285#[no_mangle]
1286pub unsafe extern "C" fn libinput_device_config_tap_set_drag_enabled(
1287 dev: *mut LibinputDevice,
1288 enabled: u32,
1289) -> u32 {
1290 if dev.is_null() {
1291 return 1;
1292 }
1293 if enabled > 1 {
1294 return 2;
1295 }
1296 if (*dev).tap_finger_count == 0 {
1297 return if enabled == 0 { 0 } else { 1 };
1298 }
1299 (*dev).tap_drag_enabled = enabled != 0;
1300 0
1301}
1302
1303#[no_mangle]
1304pub unsafe extern "C" fn libinput_device_config_tap_get_drag_enabled(
1305 dev: *const LibinputDevice,
1306) -> u32 {
1307 if dev.is_null() {
1308 return 0;
1309 }
1310 (*dev).tap_drag_enabled as u32
1311}
1312
1313#[no_mangle]
1314pub unsafe extern "C" fn libinput_device_config_tap_get_default_drag_enabled(
1315 dev: *const LibinputDevice,
1316) -> u32 {
1317 if dev.is_null() {
1318 return 0;
1319 }
1320 ((*dev).tap_finger_count != 0) as u32
1321}
1322
1323#[no_mangle]
1324pub unsafe extern "C" fn libinput_device_config_tap_set_drag_lock_enabled(
1325 dev: *mut LibinputDevice,
1326 enabled: u32,
1327) -> u32 {
1328 if dev.is_null() {
1329 return 1;
1330 }
1331 if enabled > 2 {
1332 return 2;
1333 }
1334 if (*dev).tap_finger_count == 0 {
1335 return if enabled == 0 { 0 } else { 1 };
1336 }
1337 (*dev).tap_drag_lock_enabled = if enabled == 1 { 1 } else { enabled };
1338 0
1339}
1340
1341#[no_mangle]
1342pub unsafe extern "C" fn libinput_device_config_tap_get_drag_lock_enabled(
1343 dev: *const LibinputDevice,
1344) -> u32 {
1345 if dev.is_null() {
1346 return 0;
1347 }
1348 (*dev).tap_drag_lock_enabled
1349}
1350
1351#[no_mangle]
1353pub unsafe extern "C" fn libinput_device_config_tap_set_button_map(
1354 dev: *mut LibinputDevice,
1355 map: u32,
1356) -> u32 {
1357 if dev.is_null() {
1358 return 1;
1359 }
1360 if map > 1 {
1361 return 2;
1362 }
1363 if (*dev).tap_finger_count == 0 {
1364 return 1;
1365 }
1366 (*dev).tap_button_map = map;
1367 0
1368}
1369
1370#[no_mangle]
1371pub unsafe extern "C" fn libinput_device_config_tap_get_button_map(
1372 dev: *const LibinputDevice,
1373) -> u32 {
1374 if dev.is_null() {
1375 return 0;
1376 }
1377 (*dev).tap_button_map
1378}
1379
1380#[no_mangle]
1381pub unsafe extern "C" fn libinput_device_config_tap_get_default_button_map(
1382 _dev: *const LibinputDevice,
1383) -> u32 {
1384 0
1385} #[no_mangle]
1388pub unsafe extern "C" fn libinput_device_config_3fg_drag_get_finger_count(
1389 dev: *const LibinputDevice,
1390) -> libc::c_int {
1391 if dev.is_null() || !(*dev).has_gesture {
1392 return 0;
1393 }
1394 (*dev).mt_slot_count
1395}
1396
1397#[no_mangle]
1398pub unsafe extern "C" fn libinput_device_config_3fg_drag_set_enabled(
1399 dev: *mut LibinputDevice,
1400 enable: u32,
1401) -> u32 {
1402 if dev.is_null() {
1403 return 1;
1404 }
1405 if !matches!(enable, 0..=2) {
1406 return 2;
1407 }
1408 if libinput_device_config_3fg_drag_get_finger_count(dev) < 3 {
1409 return 1;
1410 }
1411 (*dev).drag_3fg_enabled = enable;
1412 0
1413}
1414
1415#[no_mangle]
1416pub unsafe extern "C" fn libinput_device_config_3fg_drag_get_enabled(
1417 dev: *const LibinputDevice,
1418) -> u32 {
1419 if dev.is_null() {
1420 return 0;
1421 }
1422 (*dev).drag_3fg_enabled
1423}
1424
1425#[no_mangle]
1426pub unsafe extern "C" fn libinput_device_config_3fg_drag_get_default_enabled(
1427 _dev: *const LibinputDevice,
1428) -> u32 {
1429 0
1430}
1431
1432#[no_mangle]
1437pub unsafe extern "C" fn libinput_config_accel_create(profile: u32) -> *mut libc::c_void {
1438 if !matches!(profile, 1 | 2 | 4) {
1439 return std::ptr::null_mut();
1440 }
1441 Box::into_raw(Box::new(profile)) as *mut libc::c_void
1442}
1443
1444#[no_mangle]
1445pub unsafe extern "C" fn libinput_config_accel_destroy(accel_config: *mut libc::c_void) {
1446 if !accel_config.is_null() {
1447 drop(Box::from_raw(accel_config as *mut u32));
1448 }
1449}
1450
1451#[no_mangle]
1452pub unsafe extern "C" fn libinput_config_accel_set_points(
1453 accel_config: *mut libc::c_void,
1454 _accel_type: u32,
1455 step: f64,
1456 npoints: libc::size_t,
1457 points: *const f64,
1458) -> u32 {
1459 if accel_config.is_null()
1460 || points.is_null()
1461 || !step.is_finite()
1462 || step <= 0.0
1463 || step >= 1e10
1464 || npoints == 0
1465 {
1466 return 2;
1467 }
1468 let points = std::slice::from_raw_parts(points, npoints);
1469 if points
1470 .iter()
1471 .any(|point| !point.is_finite() || *point < 0.0 || *point >= 1e10)
1472 {
1473 return 2;
1474 }
1475 0
1476}
1477
1478#[no_mangle]
1479pub unsafe extern "C" fn libinput_device_config_accel_apply(
1480 dev: *mut LibinputDevice,
1481 accel_config: *mut libc::c_void,
1482) -> u32 {
1483 if dev.is_null() || accel_config.is_null() {
1484 return 2;
1485 }
1486 if !(*dev).accel_available {
1487 return 1;
1488 }
1489 let profile = *(accel_config as *const u32);
1490 if profile & libinput_device_config_accel_get_profiles(dev) == 0 {
1491 return 1;
1492 }
1493 (*dev).accel_profile = profile;
1494 (*dev).accel_speed = 0.0;
1495 0
1496}
1497
1498#[no_mangle]
1499pub unsafe extern "C" fn libinput_device_config_accel_is_available(
1500 dev: *const LibinputDevice,
1501) -> libc::c_int {
1502 if dev.is_null() {
1503 return 0;
1504 }
1505 (*dev).accel_available as libc::c_int
1506}
1507
1508#[no_mangle]
1509pub unsafe extern "C" fn libinput_device_config_accel_set_speed(
1510 dev: *mut LibinputDevice,
1511 speed: f64,
1512) -> u32 {
1513 if dev.is_null() {
1514 return 1;
1515 }
1516 if !speed.is_finite() || !(-1.0..=1.0).contains(&speed) {
1517 return 2;
1518 }
1519 if !(*dev).accel_available {
1520 return 1;
1521 }
1522 (*dev).accel_speed = speed;
1523 0
1524}
1525
1526#[no_mangle]
1527pub unsafe extern "C" fn libinput_device_config_accel_get_speed(dev: *const LibinputDevice) -> f64 {
1528 if dev.is_null() {
1529 return 0.0;
1530 }
1531 (*dev).accel_speed
1532}
1533
1534#[no_mangle]
1535pub unsafe extern "C" fn libinput_device_config_accel_get_default_speed(
1536 _dev: *const LibinputDevice,
1537) -> f64 {
1538 0.0
1539}
1540
1541#[no_mangle]
1542pub unsafe extern "C" fn libinput_device_config_accel_get_profiles(
1543 dev: *const LibinputDevice,
1544) -> u32 {
1545 if dev.is_null() {
1546 return 0;
1547 }
1548 if (*dev).accel_available
1549 && !((*dev).has_tablet && !(*dev).has_gesture && !(*dev).has_tablet_pad)
1550 {
1551 0b111
1552 } else {
1553 0
1554 }
1555}
1556
1557#[no_mangle]
1558pub unsafe extern "C" fn libinput_device_config_accel_set_profile(
1559 dev: *mut LibinputDevice,
1560 profile: u32,
1561) -> u32 {
1562 if dev.is_null() {
1563 return 1;
1564 }
1565 if profile == 0 || profile & !0b111 != 0 || profile.count_ones() != 1 {
1566 return 2;
1567 }
1568 if profile & libinput_device_config_accel_get_profiles(dev) == 0 {
1569 return 1;
1570 }
1571 (*dev).accel_profile = profile;
1572 0
1573}
1574
1575#[no_mangle]
1576pub unsafe extern "C" fn libinput_device_config_accel_get_profile(
1577 dev: *const LibinputDevice,
1578) -> u32 {
1579 if dev.is_null() {
1580 return 0;
1581 }
1582 if (*dev).accel_available
1583 && !((*dev).has_tablet && !(*dev).has_gesture && !(*dev).has_tablet_pad)
1584 {
1585 (*dev).accel_profile
1586 } else {
1587 0
1588 }
1589}
1590
1591#[no_mangle]
1592pub unsafe extern "C" fn libinput_device_config_accel_get_default_profile(
1593 dev: *const LibinputDevice,
1594) -> u32 {
1595 if dev.is_null()
1596 || !(*dev).accel_available
1597 || ((*dev).has_tablet && !(*dev).has_gesture && !(*dev).has_tablet_pad)
1598 {
1599 0
1600 } else {
1601 2
1602 }
1603}
1604
1605#[no_mangle]
1610pub unsafe extern "C" fn libinput_device_config_scroll_has_natural_scroll(
1611 dev: *const LibinputDevice,
1612) -> libc::c_int {
1613 if dev.is_null() {
1614 return 0;
1615 }
1616 (*dev).has_pointer as libc::c_int
1617}
1618
1619#[no_mangle]
1620pub unsafe extern "C" fn libinput_device_config_scroll_set_natural_scroll_enabled(
1621 dev: *mut LibinputDevice,
1622 enabled: libc::c_int,
1623) -> u32 {
1624 if dev.is_null() || !(*dev).has_pointer {
1625 return 1;
1626 }
1627 (*dev).natural_scroll = enabled != 0;
1628 0
1629}
1630
1631#[no_mangle]
1632pub unsafe extern "C" fn libinput_device_config_scroll_get_natural_scroll_enabled(
1633 dev: *const LibinputDevice,
1634) -> libc::c_int {
1635 if dev.is_null() {
1636 return 0;
1637 }
1638 (*dev).natural_scroll as libc::c_int
1639}
1640
1641#[no_mangle]
1642pub unsafe extern "C" fn libinput_device_config_scroll_get_default_natural_scroll_enabled(
1643 dev: *const LibinputDevice,
1644) -> libc::c_int {
1645 if dev.is_null() {
1646 return 0;
1647 }
1648 ((*dev).scroll_methods & 2 != 0 && (*dev).vendor_id == 0x05ac) as libc::c_int
1649}
1650
1651#[no_mangle]
1656pub unsafe extern "C" fn libinput_device_config_left_handed_is_available(
1657 dev: *const LibinputDevice,
1658) -> libc::c_int {
1659 if dev.is_null() {
1660 return 0;
1661 }
1662 (*dev).left_handed_available as libc::c_int
1663}
1664
1665#[no_mangle]
1666pub unsafe extern "C" fn libinput_device_config_left_handed_set(
1667 dev: *mut LibinputDevice,
1668 enabled: libc::c_int,
1669) -> u32 {
1670 if dev.is_null() || !(*dev).left_handed_available {
1671 return 1;
1672 }
1673 (*dev).left_handed = enabled != 0;
1674 0
1675}
1676
1677#[no_mangle]
1678pub unsafe extern "C" fn libinput_device_config_left_handed_get(
1679 dev: *const LibinputDevice,
1680) -> libc::c_int {
1681 if dev.is_null() {
1682 return 0;
1683 }
1684 (*dev).left_handed as libc::c_int
1685}
1686
1687#[no_mangle]
1688pub unsafe extern "C" fn libinput_device_config_left_handed_get_default(
1689 _dev: *const LibinputDevice,
1690) -> libc::c_int {
1691 0
1692}
1693
1694#[no_mangle]
1699pub unsafe extern "C" fn libinput_device_config_scroll_get_methods(
1700 dev: *const LibinputDevice,
1701) -> u32 {
1702 if dev.is_null() {
1703 return 0;
1704 }
1705 (*dev).scroll_methods
1706}
1707
1708#[no_mangle]
1709pub unsafe extern "C" fn libinput_device_config_scroll_set_method(
1710 dev: *mut LibinputDevice,
1711 method: u32,
1712) -> u32 {
1713 if dev.is_null() {
1714 return 1;
1715 }
1716 if !matches!(method, 0 | 1 | 2 | 4) {
1717 return 2;
1718 }
1719 if method != 0 && method & (*dev).scroll_methods == 0 {
1720 return 1;
1721 }
1722 if (*dev).scroll_method == method {
1723 return 0;
1724 }
1725 let ctx = (*dev).context;
1726 if !ctx.is_null() {
1727 let mut events = std::collections::VecDeque::new();
1728 if let Ok(mut backend) = (*ctx).backend.try_lock() {
1729 backend.stop_scroll_for_device(ctx, dev, &mut events);
1730 }
1731 (*ctx).event_queue.extend(events);
1732 }
1733 (*dev).scroll_method = method;
1734 0
1735}
1736
1737#[no_mangle]
1738pub unsafe extern "C" fn libinput_device_config_scroll_get_method(
1739 dev: *const LibinputDevice,
1740) -> u32 {
1741 if dev.is_null() {
1742 return 0;
1743 }
1744 (*dev).scroll_method
1745}
1746
1747#[no_mangle]
1748pub unsafe extern "C" fn libinput_device_config_scroll_get_default_method(
1749 dev: *const LibinputDevice,
1750) -> u32 {
1751 if dev.is_null() {
1752 0
1753 } else {
1754 (*dev).scroll_default_method
1755 }
1756}
1757
1758#[no_mangle]
1759pub unsafe extern "C" fn libinput_device_config_scroll_set_button(
1760 dev: *mut LibinputDevice,
1761 button: u32,
1762) -> u32 {
1763 if dev.is_null() || !(*dev).supports_button_scroll {
1764 return 1;
1765 }
1766 if button != 0
1767 && match u16::try_from(button) {
1768 Ok(button) => !(*dev).event_codes.contains(&button),
1769 Err(_) => true,
1770 }
1771 {
1772 return 2;
1773 }
1774 (*dev).scroll_button = button;
1775 0
1776}
1777
1778#[no_mangle]
1779pub unsafe extern "C" fn libinput_device_config_scroll_get_button(
1780 dev: *const LibinputDevice,
1781) -> u32 {
1782 if dev.is_null() || !(*dev).supports_button_scroll {
1783 0
1784 } else {
1785 (*dev).scroll_button
1786 }
1787}
1788
1789#[no_mangle]
1790pub unsafe extern "C" fn libinput_device_config_scroll_set_button_lock(
1791 dev: *mut LibinputDevice,
1792 state: u32,
1793) -> u32 {
1794 if dev.is_null() || !(*dev).supports_button_scroll {
1795 return 1;
1796 }
1797 if state > 1 {
1798 return 2;
1799 }
1800 (*dev).scroll_button_lock = state;
1801 0
1802}
1803
1804#[no_mangle]
1805pub unsafe extern "C" fn libinput_device_config_scroll_get_button_lock(
1806 dev: *const LibinputDevice,
1807) -> u32 {
1808 if dev.is_null() || !(*dev).supports_button_scroll {
1809 0
1810 } else {
1811 (*dev).scroll_button_lock
1812 }
1813}
1814
1815#[no_mangle]
1816pub unsafe extern "C" fn libinput_device_config_scroll_get_default_button_lock(
1817 _dev: *const LibinputDevice,
1818) -> u32 {
1819 0
1820}
1821
1822#[no_mangle]
1827pub unsafe extern "C" fn libinput_device_config_click_get_methods(
1828 dev: *const LibinputDevice,
1829) -> u32 {
1830 if dev.is_null() {
1831 return 0;
1832 }
1833 (*dev).click_methods
1834}
1835
1836#[no_mangle]
1837pub unsafe extern "C" fn libinput_device_config_click_set_method(
1838 dev: *mut LibinputDevice,
1839 method: u32,
1840) -> u32 {
1841 if dev.is_null() {
1842 return 1;
1843 }
1844 if !matches!(method, 0..=2) {
1845 return 2;
1846 }
1847 if method != 0 && method & (*dev).click_methods == 0 {
1848 return 1;
1849 }
1850 (*dev).click_method = method;
1851 0
1852}
1853
1854#[no_mangle]
1855pub unsafe extern "C" fn libinput_device_config_click_get_method(
1856 dev: *const LibinputDevice,
1857) -> u32 {
1858 if dev.is_null() {
1859 return 0;
1860 }
1861 (*dev).click_method
1862}
1863
1864#[no_mangle]
1865pub unsafe extern "C" fn libinput_device_config_click_get_default_method(
1866 dev: *const LibinputDevice,
1867) -> u32 {
1868 if dev.is_null() {
1869 0
1870 } else {
1871 (*dev).click_default_method
1872 }
1873}
1874
1875#[no_mangle]
1876pub unsafe extern "C" fn libinput_device_config_click_set_clickfinger_button_map(
1877 dev: *mut LibinputDevice,
1878 map: u32,
1879) -> u32 {
1880 if dev.is_null() {
1881 return 1;
1882 }
1883 if !matches!(map, 0 | 1) {
1884 return 2;
1885 }
1886 if (*dev).click_methods & 2 == 0 {
1887 return 1;
1888 }
1889 (*dev).clickfinger_button_map = map;
1890 0
1891}
1892
1893#[no_mangle]
1894pub unsafe extern "C" fn libinput_device_config_click_get_clickfinger_button_map(
1895 dev: *const LibinputDevice,
1896) -> u32 {
1897 if dev.is_null() || (*dev).click_methods & 2 == 0 {
1898 0
1899 } else {
1900 (*dev).clickfinger_button_map
1901 }
1902}
1903
1904#[no_mangle]
1905pub unsafe extern "C" fn libinput_device_config_click_get_default_clickfinger_button_map(
1906 dev: *const LibinputDevice,
1907) -> u32 {
1908 if dev.is_null() || (*dev).click_methods & 2 == 0 {
1909 0
1910 } else {
1911 (*dev).clickfinger_default_button_map
1912 }
1913}
1914
1915#[no_mangle]
1920pub unsafe extern "C" fn libinput_device_config_middle_emulation_is_available(
1921 dev: *const LibinputDevice,
1922) -> libc::c_int {
1923 if dev.is_null() {
1924 return 0;
1925 }
1926 (*dev).middle_emulation_available as libc::c_int
1927}
1928
1929#[no_mangle]
1930pub unsafe extern "C" fn libinput_device_config_middle_emulation_set_enabled(
1931 dev: *mut LibinputDevice,
1932 enabled: u32,
1933) -> u32 {
1934 if dev.is_null() {
1935 return 1;
1936 }
1937 if enabled > 1 {
1938 return 2;
1939 }
1940 if enabled == 1 && !(*dev).middle_emulation_available {
1941 return 1;
1942 }
1943 (*dev).middle_emulation = enabled != 0;
1944 0
1945}
1946
1947#[no_mangle]
1948pub unsafe extern "C" fn libinput_device_config_middle_emulation_get_enabled(
1949 dev: *const LibinputDevice,
1950) -> u32 {
1951 if dev.is_null() || !(*dev).middle_emulation_available {
1952 return 0;
1953 }
1954 (*dev).middle_emulation as u32
1955}
1956
1957#[no_mangle]
1958pub unsafe extern "C" fn libinput_device_config_middle_emulation_get_default_enabled(
1959 dev: *const LibinputDevice,
1960) -> u32 {
1961 if dev.is_null() || !(*dev).middle_emulation_available {
1962 return 0;
1963 }
1964 (*dev).middle_emulation_default as u32
1965}
1966
1967#[no_mangle]
1972pub unsafe extern "C" fn libinput_device_config_dwt_is_available(
1973 dev: *const LibinputDevice,
1974) -> libc::c_int {
1975 (!dev.is_null() && (*dev).dwt_available) as libc::c_int
1976}
1977
1978#[no_mangle]
1979pub unsafe extern "C" fn libinput_device_config_dwt_set_enabled(
1980 dev: *mut LibinputDevice,
1981 enabled: u32,
1982) -> u32 {
1983 if dev.is_null() {
1984 return 1;
1985 }
1986 if !matches!(enabled, 0 | 1) {
1987 return 2;
1988 }
1989 if !(*dev).dwt_available {
1990 return if enabled == 0 { 0 } else { 1 };
1991 }
1992 (*dev).dwt_enabled = enabled == 1;
1993 0
1994}
1995
1996#[no_mangle]
1997pub unsafe extern "C" fn libinput_device_config_dwt_get_enabled(dev: *const LibinputDevice) -> u32 {
1998 if dev.is_null() || !(*dev).dwt_available {
1999 return 0;
2000 }
2001 (*dev).dwt_enabled as u32
2002}
2003
2004#[no_mangle]
2005pub unsafe extern "C" fn libinput_device_config_dwt_get_default_enabled(
2006 dev: *const LibinputDevice,
2007) -> u32 {
2008 (!dev.is_null() && (*dev).dwt_available) as u32
2009}
2010
2011#[no_mangle]
2012pub unsafe extern "C" fn libinput_device_config_dwt_set_timeout(
2013 dev: *mut LibinputDevice,
2014 millis: u32,
2015) -> u32 {
2016 if dev.is_null() {
2017 return 1;
2018 }
2019 if millis == 0 {
2020 return 2;
2021 }
2022 if !(*dev).dwt_available {
2023 return 1;
2024 }
2025 if !(100..=5000).contains(&millis) {
2026 return 2;
2027 }
2028 (*dev).dwt_timeout = millis;
2029 0
2030}
2031
2032#[no_mangle]
2033pub unsafe extern "C" fn libinput_device_config_dwt_get_timeout(dev: *const LibinputDevice) -> u32 {
2034 if dev.is_null() || !(*dev).dwt_available {
2035 0
2036 } else {
2037 (*dev).dwt_timeout
2038 }
2039}
2040
2041#[no_mangle]
2042pub unsafe extern "C" fn libinput_device_config_dwt_get_default_timeout(
2043 dev: *const LibinputDevice,
2044) -> u32 {
2045 if !dev.is_null() && (*dev).dwt_available {
2046 500
2047 } else {
2048 0
2049 }
2050}
2051
2052#[no_mangle]
2053pub unsafe extern "C" fn libinput_device_config_dwtp_is_available(
2054 dev: *const LibinputDevice,
2055) -> libc::c_int {
2056 (!dev.is_null() && (*dev).dwtp_available) as libc::c_int
2057}
2058
2059#[no_mangle]
2060pub unsafe extern "C" fn libinput_device_config_dwtp_set_enabled(
2061 dev: *mut LibinputDevice,
2062 enabled: u32,
2063) -> u32 {
2064 if dev.is_null() {
2065 return 1;
2066 }
2067 if !matches!(enabled, 0 | 1) {
2068 return 2;
2069 }
2070 if !(*dev).dwtp_available {
2071 return if enabled == 0 { 0 } else { 1 };
2072 }
2073 (*dev).dwtp_enabled = enabled == 1;
2074 0
2075}
2076
2077#[no_mangle]
2078pub unsafe extern "C" fn libinput_device_config_dwtp_get_enabled(
2079 dev: *const LibinputDevice,
2080) -> u32 {
2081 if dev.is_null() || !(*dev).dwtp_available {
2082 0
2083 } else {
2084 (*dev).dwtp_enabled as u32
2085 }
2086}
2087
2088#[no_mangle]
2089pub unsafe extern "C" fn libinput_device_config_dwtp_get_default_enabled(
2090 dev: *const LibinputDevice,
2091) -> u32 {
2092 (!dev.is_null() && (*dev).dwtp_available) as u32
2093}
2094
2095#[no_mangle]
2096pub unsafe extern "C" fn libinput_device_config_dwtp_set_timeout(
2097 dev: *mut LibinputDevice,
2098 millis: u32,
2099) -> u32 {
2100 if dev.is_null() {
2101 return 1;
2102 }
2103 if millis == 0 {
2104 return 2;
2105 }
2106 if !(*dev).dwtp_available {
2107 return 1;
2108 }
2109 if !(100..=5000).contains(&millis) {
2110 return 2;
2111 }
2112 (*dev).dwtp_timeout = millis;
2113 0
2114}
2115
2116#[no_mangle]
2117pub unsafe extern "C" fn libinput_device_config_dwtp_get_timeout(
2118 dev: *const LibinputDevice,
2119) -> u32 {
2120 if dev.is_null() || !(*dev).dwtp_available {
2121 0
2122 } else {
2123 (*dev).dwtp_timeout
2124 }
2125}
2126
2127#[no_mangle]
2128pub unsafe extern "C" fn libinput_device_config_dwtp_get_default_timeout(
2129 dev: *const LibinputDevice,
2130) -> u32 {
2131 if !dev.is_null() && (*dev).dwtp_available {
2132 300
2133 } else {
2134 0
2135 }
2136}
2137
2138#[no_mangle]
2143pub unsafe extern "C" fn libinput_device_config_calibration_has_matrix(
2144 dev: *const LibinputDevice,
2145) -> libc::c_int {
2146 if dev.is_null() {
2147 return 0;
2148 }
2149 (*dev).calibration_available as libc::c_int
2150}
2151
2152#[no_mangle]
2153pub unsafe extern "C" fn libinput_device_config_calibration_set_matrix(
2154 dev: *mut LibinputDevice,
2155 matrix: *const f32,
2156) -> u32 {
2157 if dev.is_null() || matrix.is_null() || !(*dev).calibration_available {
2158 return 1;
2159 }
2160 (*dev)
2161 .calibration
2162 .copy_from_slice(std::slice::from_raw_parts(matrix, 6));
2163 0
2164}
2165
2166#[no_mangle]
2167pub unsafe extern "C" fn libinput_device_config_calibration_get_matrix(
2168 dev: *const LibinputDevice,
2169 matrix: *mut f32,
2170) -> libc::c_int {
2171 if dev.is_null() || matrix.is_null() || !(*dev).calibration_available {
2172 return 0;
2173 }
2174 std::slice::from_raw_parts_mut(matrix, 6).copy_from_slice(&(*dev).calibration);
2175 ((*dev).calibration != [1.0_f32, 0.0, 0.0, 0.0, 1.0, 0.0]) as libc::c_int
2176}
2177
2178#[no_mangle]
2179pub unsafe extern "C" fn libinput_device_config_calibration_get_default_matrix(
2180 dev: *const LibinputDevice,
2181 matrix: *mut f32,
2182) -> libc::c_int {
2183 if dev.is_null() || matrix.is_null() || !(*dev).calibration_available {
2184 return 0;
2185 }
2186 std::slice::from_raw_parts_mut(matrix, 6).copy_from_slice(&(*dev).default_calibration);
2187 ((*dev).default_calibration != [1.0_f32, 0.0, 0.0, 0.0, 1.0, 0.0]) as libc::c_int
2188}
2189
2190#[no_mangle]
2195pub unsafe extern "C" fn libinput_device_get_seat(dev: *const LibinputDevice) -> *mut libc::c_void {
2196 if dev.is_null() {
2197 return std::ptr::null_mut();
2198 }
2199 (*dev).seat as *mut libc::c_void
2200}
2201
2202#[no_mangle]
2203pub unsafe extern "C" fn libinput_device_set_seat_logical_name(
2204 dev: *mut LibinputDevice,
2205 name: *const libc::c_char,
2206) -> libc::c_int {
2207 if dev.is_null() || name.is_null() || (*dev).seat.is_null() {
2208 return -1;
2209 }
2210 let name = CStr::from_ptr(name);
2211 if name.to_bytes().is_empty() || name.to_bytes().len() > 255 {
2212 return -1;
2213 }
2214 if (*(*dev).seat).logical_name.as_c_str() == name {
2215 return 0;
2216 }
2217 let Ok(logical_name) = std::ffi::CString::new(name.to_bytes()) else {
2218 return -1;
2219 };
2220 let ctx = (*dev).context;
2221 if ctx.is_null() {
2222 return -1;
2223 }
2224 let physical_name = (*(*dev).seat).physical_name.clone();
2225 let new_seat = (*ctx)
2226 .seats
2227 .iter()
2228 .copied()
2229 .find(|seat| {
2230 !seat.is_null()
2231 && (**seat).physical_name == physical_name
2232 && (**seat).logical_name == logical_name
2233 })
2234 .unwrap_or_else(|| {
2235 let seat = Box::into_raw(Box::new(LibinputSeat {
2236 physical_name,
2237 logical_name,
2238 refcount: std::sync::atomic::AtomicI32::new(1),
2239 user_data: std::ptr::null_mut(),
2240 context: ctx,
2241 button_count: std::sync::atomic::AtomicU32::new(0),
2242 key_count: std::sync::atomic::AtomicU32::new(0),
2243 }));
2244 (*ctx).seats.push(seat);
2245 seat
2246 });
2247
2248 let path = std::path::PathBuf::from((*dev).devnode.to_string_lossy().into_owned());
2249 let mut removed = std::collections::VecDeque::new();
2250 let mut added = Vec::new();
2251 let replaced = if let Ok(mut backend) = (*ctx).backend.lock() {
2252 if backend.remove_device(ctx, dev, &mut removed) {
2253 backend.try_open(ctx, &path, &mut added);
2254 true
2255 } else {
2256 false
2257 }
2258 } else {
2259 false
2260 };
2261 let Some(replacement) = added.first().map(|event| event.device) else {
2262 return -1;
2263 };
2264 if !replaced || replacement.is_null() {
2265 return -1;
2266 }
2267 (*ctx).devices.retain(|candidate| *candidate != dev);
2268 libinput_device_unref(dev);
2269 (*replacement).seat = new_seat;
2270 (*ctx).event_queue.extend(removed);
2271 (*ctx).event_queue.extend(added);
2272 (*replacement).abi.seat = new_seat;
2273 (*ctx).signal_fd();
2274 0
2275}
2276
2277#[no_mangle]
2278pub unsafe extern "C" fn libinput_seat_get_physical_name(
2279 seat: *const libc::c_void,
2280) -> *const libc::c_char {
2281 if seat.is_null() {
2282 return std::ptr::null();
2283 }
2284 (*(seat as *const LibinputSeat)).physical_name.as_ptr()
2285}
2286
2287#[no_mangle]
2288pub unsafe extern "C" fn libinput_seat_get_logical_name(
2289 seat: *const libc::c_void,
2290) -> *const libc::c_char {
2291 if seat.is_null() {
2292 return std::ptr::null();
2293 }
2294 (*(seat as *const LibinputSeat)).logical_name.as_ptr()
2295}
2296
2297#[no_mangle]
2298pub unsafe extern "C" fn libinput_seat_get_context(
2299 seat: *const libc::c_void,
2300) -> *mut LibinputContext {
2301 if seat.is_null() {
2302 return std::ptr::null_mut();
2303 }
2304 (*(seat as *const LibinputSeat)).context
2305}
2306
2307#[no_mangle]
2308pub unsafe extern "C" fn libinput_seat_ref(seat: *mut libc::c_void) -> *mut libc::c_void {
2309 if !seat.is_null() {
2310 (*(seat as *mut LibinputSeat))
2311 .refcount
2312 .fetch_add(1, std::sync::atomic::Ordering::SeqCst);
2313 }
2314 seat
2315}
2316
2317#[no_mangle]
2318pub unsafe extern "C" fn libinput_seat_unref(seat: *mut libc::c_void) -> *mut libc::c_void {
2319 if !seat.is_null() {
2320 let seat = seat as *mut LibinputSeat;
2321 if (*seat)
2322 .refcount
2323 .fetch_sub(1, std::sync::atomic::Ordering::AcqRel)
2324 == 1
2325 {
2326 drop(Box::from_raw(seat));
2327 }
2328 }
2329 std::ptr::null_mut()
2330}
2331
2332#[no_mangle]
2333pub unsafe extern "C" fn libinput_seat_set_user_data(
2334 seat: *mut libc::c_void,
2335 data: *mut libc::c_void,
2336) {
2337 if !seat.is_null() {
2338 (*(seat as *mut LibinputSeat)).user_data = data;
2339 }
2340}
2341
2342#[no_mangle]
2343pub unsafe extern "C" fn libinput_seat_get_user_data(
2344 seat: *const libc::c_void,
2345) -> *mut libc::c_void {
2346 if seat.is_null() {
2347 return std::ptr::null_mut();
2348 }
2349 (*(seat as *const LibinputSeat)).user_data
2350}
2351
2352#[no_mangle]
2357pub unsafe extern "C" fn libinput_config_status_to_str(status: u32) -> *const libc::c_char {
2358 match status {
2359 0 => b"success\0".as_ptr().cast(),
2360 1 => b"unsupported\0".as_ptr().cast(),
2361 2 => b"invalid\0".as_ptr().cast(),
2362 _ => std::ptr::null(),
2363 }
2364}
2365
2366#[no_mangle]
2371pub unsafe extern "C" fn libinput_log_set_priority(ctx: *mut LibinputContext, priority: u32) {
2372 if !ctx.is_null() {
2373 (*ctx).log_priority = priority;
2374 }
2375}
2376
2377#[no_mangle]
2378pub unsafe extern "C" fn libinput_log_get_priority(ctx: *const LibinputContext) -> u32 {
2379 if ctx.is_null() {
2380 return 30;
2381 }
2382 (*ctx).log_priority
2383}
2384
2385#[no_mangle]
2386pub unsafe extern "C" fn libinput_log_set_handler(
2387 ctx: *mut LibinputContext,
2388 handler: Option<
2389 unsafe extern "C" fn(
2390 ctx: *mut LibinputContext,
2391 priority: u32,
2392 format: *const libc::c_char,
2393 args: *mut libc::c_void,
2394 ),
2395 >,
2396) {
2397 if ctx.is_null() {
2398 return;
2399 }
2400 (*ctx).log_handler = handler;
2401}
2402
2403#[no_mangle]
2408pub unsafe extern "C" fn libinput_set_user_data(
2409 ctx: *mut LibinputContext,
2410 data: *mut libc::c_void,
2411) {
2412 if ctx.is_null() {
2413 return;
2414 }
2415 (*ctx).user_data = data;
2416}
2417
2418#[no_mangle]
2419pub unsafe extern "C" fn libinput_get_user_data(ctx: *const LibinputContext) -> *mut libc::c_void {
2420 if ctx.is_null() {
2421 return std::ptr::null_mut();
2422 }
2423 (*ctx).user_data
2424}
2425
2426#[no_mangle]
2427pub unsafe extern "C" fn libinput_device_set_user_data(
2428 dev: *mut LibinputDevice,
2429 data: *mut libc::c_void,
2430) {
2431 if dev.is_null() {
2432 return;
2433 }
2434 (*dev).user_data = data;
2435 (*dev).abi.user_data = data;
2436}
2437
2438#[no_mangle]
2439pub unsafe extern "C" fn libinput_device_get_user_data(
2440 dev: *const LibinputDevice,
2441) -> *mut libc::c_void {
2442 if dev.is_null() {
2443 return std::ptr::null_mut();
2444 }
2445 (*dev).user_data
2446}
2447
2448#[no_mangle]
2453pub unsafe extern "C" fn libinput_device_config_area_has_rectangle(
2454 dev: *const LibinputDevice,
2455) -> libc::c_int {
2456 if dev.is_null() {
2457 return 0;
2458 }
2459 (*dev).area_available as libc::c_int
2460}
2461
2462#[no_mangle]
2463pub unsafe extern "C" fn libinput_device_config_area_set_rectangle(
2464 dev: *mut LibinputDevice,
2465 rectangle: *const LibinputConfigAreaRectangle,
2466) -> u32 {
2467 if dev.is_null() || !(*dev).area_available {
2468 return 1;
2469 }
2470 if rectangle.is_null() {
2471 return 2;
2472 }
2473 let rectangle = &*rectangle;
2474 if rectangle.x1 >= rectangle.x2
2475 || rectangle.y1 >= rectangle.y2
2476 || rectangle.x1 < 0.0
2477 || rectangle.x2 > 1.0
2478 || rectangle.y1 < 0.0
2479 || rectangle.y2 > 1.0
2480 {
2481 return 2;
2482 }
2483 (*dev).wanted_area = [rectangle.x1, rectangle.y1, rectangle.x2, rectangle.y2];
2484 if !(*dev).tablet_in_proximity {
2485 (*dev).area = (*dev).wanted_area;
2486 }
2487 0
2488}
2489
2490#[no_mangle]
2491pub unsafe extern "C" fn libinput_device_config_area_get_rectangle(
2492 dev: *const LibinputDevice,
2493) -> LibinputConfigAreaRectangle {
2494 let area = if dev.is_null() || !(*dev).area_available {
2495 [0.0, 0.0, 1.0, 1.0]
2496 } else {
2497 (*dev).area
2498 };
2499 LibinputConfigAreaRectangle {
2500 x1: area[0],
2501 y1: area[1],
2502 x2: area[2],
2503 y2: area[3],
2504 }
2505}
2506
2507#[no_mangle]
2508pub unsafe extern "C" fn libinput_device_config_area_get_default_rectangle(
2509 _dev: *const LibinputDevice,
2510) -> LibinputConfigAreaRectangle {
2511 LibinputConfigAreaRectangle {
2512 x1: 0.0,
2513 y1: 0.0,
2514 x2: 1.0,
2515 y2: 1.0,
2516 }
2517}
2518
2519#[no_mangle]
2520pub unsafe extern "C" fn libinput_device_config_rotation_is_available(
2521 dev: *const LibinputDevice,
2522) -> libc::c_int {
2523 if dev.is_null() {
2524 return 0;
2525 }
2526 (*dev).rotation_available as libc::c_int
2527}
2528
2529#[no_mangle]
2530pub unsafe extern "C" fn libinput_device_config_rotation_set_angle(
2531 dev: *mut LibinputDevice,
2532 degrees_cw: u32,
2533) -> u32 {
2534 if dev.is_null() {
2535 return 1;
2536 }
2537 if degrees_cw >= 360 {
2538 return 2;
2539 }
2540 if !(*dev).rotation_available && degrees_cw != 0 {
2541 return 1;
2542 }
2543 (*dev).rotation_angle = degrees_cw;
2544 0
2545}
2546
2547#[no_mangle]
2548pub unsafe extern "C" fn libinput_device_config_rotation_get_angle(
2549 dev: *const LibinputDevice,
2550) -> u32 {
2551 if dev.is_null() {
2552 0
2553 } else {
2554 (*dev).rotation_angle
2555 }
2556}
2557
2558#[no_mangle]
2559pub unsafe extern "C" fn libinput_device_config_rotation_get_default_angle(
2560 _dev: *const LibinputDevice,
2561) -> u32 {
2562 0
2563}
2564
2565#[no_mangle]
2566pub unsafe extern "C" fn libinput_device_config_scroll_get_default_button(
2567 dev: *const LibinputDevice,
2568) -> u32 {
2569 if dev.is_null() || !(*dev).supports_button_scroll {
2570 0
2571 } else {
2572 (*dev).scroll_default_button
2573 }
2574}
2575
2576#[no_mangle]
2577pub unsafe extern "C" fn libinput_device_config_send_events_get_modes(
2578 dev: *const LibinputDevice,
2579) -> u32 {
2580 if dev.is_null() {
2581 return 0;
2582 }
2583 (*dev).send_events_modes
2584}
2585
2586#[no_mangle]
2587pub unsafe extern "C" fn libinput_device_config_send_events_set_mode(
2588 dev: *mut LibinputDevice,
2589 mode: u32,
2590) -> u32 {
2591 if dev.is_null() {
2592 return 1;
2593 }
2594 let supported = (*dev).send_events_modes;
2595 if mode & !supported != 0 {
2596 return 1;
2597 }
2598 let previous = (*dev).send_events_mode;
2599 let next = if mode & 1 != 0 { 1 } else { mode };
2600 (*dev).send_events_mode = next;
2601 if previous != 1 && next == 1 {
2602 let ctx = (*dev).context;
2603 if !ctx.is_null() {
2604 let mut events = std::collections::VecDeque::new();
2605 if let Ok(mut backend) = (*ctx).backend.lock() {
2606 backend.release_active_inputs(ctx, dev, &mut events);
2607 }
2608 (*ctx).event_queue.extend(events);
2609 }
2610 }
2611 0
2612}
2613
2614#[no_mangle]
2615pub unsafe extern "C" fn libinput_device_config_send_events_get_mode(
2616 dev: *const LibinputDevice,
2617) -> u32 {
2618 if dev.is_null() {
2619 return 0;
2620 }
2621 (*dev).send_events_mode
2622}
2623
2624#[no_mangle]
2625pub unsafe extern "C" fn libinput_device_config_send_events_get_default_mode(
2626 _dev: *const LibinputDevice,
2627) -> u32 {
2628 0
2629}
2630
2631#[no_mangle]
2632pub unsafe extern "C" fn libinput_device_config_tap_get_default_drag_lock_enabled(
2633 _dev: *const LibinputDevice,
2634) -> u32 {
2635 0
2636}
2637
2638#[no_mangle]
2639pub unsafe extern "C" fn libinput_device_get_device_group(
2640 dev: *const LibinputDevice,
2641) -> *mut libc::c_void {
2642 if dev.is_null() {
2643 return std::ptr::null_mut();
2644 }
2645 (*dev).group.cast()
2646}
2647
2648#[no_mangle]
2649pub unsafe extern "C" fn libinput_device_group_ref(group: *mut libc::c_void) -> *mut libc::c_void {
2650 if group.is_null() {
2651 return std::ptr::null_mut();
2652 }
2653 let group = group.cast::<LibinputDeviceGroup>();
2654 (*group)
2655 .refcount
2656 .fetch_add(1, std::sync::atomic::Ordering::Relaxed);
2657 group.cast()
2658}
2659
2660#[no_mangle]
2661pub unsafe extern "C" fn libinput_device_group_unref(
2662 group: *mut libc::c_void,
2663) -> *mut libc::c_void {
2664 if group.is_null() {
2665 return std::ptr::null_mut();
2666 }
2667 let group = group.cast::<LibinputDeviceGroup>();
2668 if (*group)
2669 .refcount
2670 .fetch_sub(1, std::sync::atomic::Ordering::AcqRel)
2671 == 1
2672 {
2673 drop(Box::from_raw(group));
2674 std::ptr::null_mut()
2675 } else {
2676 group.cast()
2677 }
2678}
2679
2680#[no_mangle]
2681pub unsafe extern "C" fn libinput_device_group_set_user_data(
2682 group: *mut libc::c_void,
2683 data: *mut libc::c_void,
2684) {
2685 if !group.is_null() {
2686 (*group.cast::<LibinputDeviceGroup>()).user_data = data;
2687 }
2688}
2689
2690#[no_mangle]
2691pub unsafe extern "C" fn libinput_device_group_get_user_data(
2692 group: *const libc::c_void,
2693) -> *mut libc::c_void {
2694 if group.is_null() {
2695 return std::ptr::null_mut();
2696 }
2697 (*group.cast::<LibinputDeviceGroup>()).user_data
2698}
2699
2700#[no_mangle]
2701pub unsafe extern "C" fn libinput_device_get_id_bustype(dev: *const LibinputDevice) -> u32 {
2702 if dev.is_null() {
2703 return 0;
2704 }
2705 (*dev).bus_type
2706}
2707
2708#[no_mangle]
2709pub unsafe extern "C" fn libinput_device_get_size(
2710 dev: *const LibinputDevice,
2711 width: *mut f64,
2712 height: *mut f64,
2713) -> libc::c_int {
2714 if dev.is_null() || width.is_null() || height.is_null() {
2715 return 0;
2716 }
2717 match ((*dev).width_mm, (*dev).height_mm) {
2718 (Some(w), Some(h)) => {
2719 *width = w;
2720 *height = h;
2721 0
2722 }
2723 _ => -1,
2724 }
2725}
2726
2727#[no_mangle]
2728pub unsafe extern "C" fn libinput_device_get_udev_device(
2729 dev: *const LibinputDevice,
2730) -> *mut libc::c_void {
2731 if dev.is_null() || (*dev).udev_device.is_null() {
2732 return std::ptr::null_mut();
2733 }
2734 udev::udev_device_ref((*dev).udev_device)
2735}
2736
2737#[no_mangle]
2738pub unsafe extern "C" fn libinput_device_keyboard_has_key(
2739 dev: *const LibinputDevice,
2740 key: u32,
2741) -> libc::c_int {
2742 if dev.is_null() || !(*dev).has_keyboard {
2743 return -1;
2744 }
2745 if key > u16::MAX as u32 {
2746 return 0;
2747 }
2748 (*dev).event_codes.contains(&(key as u16)) as libc::c_int
2749}
2750
2751#[no_mangle]
2752pub unsafe extern "C" fn libinput_device_led_update(dev: *mut LibinputDevice, _leds: u32) -> u32 {
2753 if dev.is_null() {
2754 return 1;
2755 }
2756 0
2757}
2758
2759#[no_mangle]
2760pub unsafe extern "C" fn libinput_device_pointer_has_button(
2761 dev: *const LibinputDevice,
2762 button: u32,
2763) -> libc::c_int {
2764 if dev.is_null() || button > u16::MAX as u32 {
2765 return 0;
2766 }
2767 if !(*dev).has_pointer {
2768 return -1;
2769 }
2770 (*dev).event_codes.contains(&(button as u16)) as libc::c_int
2771}
2772
2773#[no_mangle]
2774pub unsafe extern "C" fn libinput_device_switch_has_switch(
2775 dev: *const LibinputDevice,
2776 sw: u32,
2777) -> libc::c_int {
2778 if dev.is_null() {
2779 return 0;
2780 }
2781 if !(*dev).has_switch {
2782 return 0;
2783 }
2784 let kernel_code = match sw {
2785 1 => 0,
2786 2 => 1,
2787 3 => 10,
2788 _ => return 0,
2789 };
2790 (*dev).switch_codes.contains(&kernel_code) as libc::c_int
2791}
2792
2793#[no_mangle]
2794pub unsafe extern "C" fn libinput_device_tablet_pad_get_mode_group(
2795 dev: *const LibinputDevice,
2796 index: u32,
2797) -> *mut libc::c_void {
2798 if dev.is_null() || !(*dev).has_tablet_pad || index != 0 {
2799 return std::ptr::null_mut();
2800 }
2801 (*dev).tablet_pad_mode_group.cast()
2802}
2803
2804#[no_mangle]
2805pub unsafe extern "C" fn libinput_device_tablet_pad_get_num_buttons(
2806 dev: *const LibinputDevice,
2807) -> u32 {
2808 if dev.is_null() || !(*dev).has_tablet_pad {
2809 return u32::MAX;
2810 }
2811 (*dev).tablet_pad_button_codes.len() as u32
2812}
2813
2814#[no_mangle]
2815pub unsafe extern "C" fn libinput_device_tablet_pad_get_num_dials(
2816 dev: *const LibinputDevice,
2817) -> u32 {
2818 if dev.is_null() || !(*dev).has_tablet_pad {
2819 return u32::MAX;
2820 }
2821 (*dev).tablet_pad_num_dials
2822}
2823
2824#[no_mangle]
2825pub unsafe extern "C" fn libinput_device_tablet_pad_get_num_mode_groups(
2826 dev: *const LibinputDevice,
2827) -> u32 {
2828 u32::from(!dev.is_null() && (*dev).has_tablet_pad)
2829}
2830
2831#[no_mangle]
2832pub unsafe extern "C" fn libinput_device_tablet_pad_get_num_rings(
2833 dev: *const LibinputDevice,
2834) -> u32 {
2835 if dev.is_null() || !(*dev).has_tablet_pad {
2836 return u32::MAX;
2837 }
2838 (*dev).tablet_pad_num_rings
2839}
2840
2841#[no_mangle]
2842pub unsafe extern "C" fn libinput_device_tablet_pad_get_num_strips(
2843 dev: *const LibinputDevice,
2844) -> u32 {
2845 if dev.is_null() || !(*dev).has_tablet_pad {
2846 return u32::MAX;
2847 }
2848 (*dev).tablet_pad_num_strips
2849}
2850
2851#[no_mangle]
2852pub unsafe extern "C" fn libinput_device_tablet_pad_has_key(
2853 dev: *const LibinputDevice,
2854 code: u32,
2855) -> libc::c_int {
2856 if dev.is_null() || !(*dev).has_tablet_pad {
2857 return -1;
2858 }
2859 (code <= u16::MAX as u32 && (*dev).event_codes.contains(&(code as u16))) as libc::c_int
2860}
2861
2862#[no_mangle]
2863pub unsafe extern "C" fn libinput_event_get_tablet_pad_event(
2864 event: *mut LibinputEvent,
2865) -> *mut LibinputEvent {
2866 if event.is_null() {
2867 return std::ptr::null_mut();
2868 }
2869 match (*event).event_type {
2870 LibinputEventType::LIBINPUT_EVENT_TABLET_PAD_BUTTON
2871 | LibinputEventType::LIBINPUT_EVENT_TABLET_PAD_RING
2872 | LibinputEventType::LIBINPUT_EVENT_TABLET_PAD_STRIP
2873 | LibinputEventType::LIBINPUT_EVENT_TABLET_PAD_KEY
2874 | LibinputEventType::LIBINPUT_EVENT_TABLET_PAD_DIAL => event,
2875 _ => std::ptr::null_mut(),
2876 }
2877}
2878
2879#[no_mangle]
2880pub unsafe extern "C" fn libinput_event_tablet_pad_get_base_event(
2881 event: *mut LibinputEvent,
2882) -> *mut LibinputEvent {
2883 event
2884}
2885
2886#[no_mangle]
2887pub unsafe extern "C" fn libinput_event_get_tablet_tool_event(
2888 event: *mut LibinputEvent,
2889) -> *mut LibinputEvent {
2890 if event.is_null() {
2891 return std::ptr::null_mut();
2892 }
2893 match (*event).event_type {
2894 LibinputEventType::LIBINPUT_EVENT_TABLET_TOOL_AXIS
2895 | LibinputEventType::LIBINPUT_EVENT_TABLET_TOOL_PROXIMITY
2896 | LibinputEventType::LIBINPUT_EVENT_TABLET_TOOL_TIP
2897 | LibinputEventType::LIBINPUT_EVENT_TABLET_TOOL_BUTTON => event,
2898 _ => std::ptr::null_mut(),
2899 }
2900}
2901
2902#[no_mangle]
2903pub unsafe extern "C" fn libinput_event_tablet_tool_get_base_event(
2904 event: *mut LibinputEvent,
2905) -> *mut LibinputEvent {
2906 event
2907}
2908
2909#[no_mangle]
2910pub unsafe extern "C" fn libinput_event_pointer_get_absolute_x_transformed(
2911 event: *const LibinputEvent,
2912 width: u32,
2913) -> f64 {
2914 if event.is_null() {
2915 return 0.0;
2916 }
2917 if let EventPayload::PointerMotionAbsolute(e) = &(*event).payload {
2918 let range = e.x_max - e.x_min;
2919 if range > 0.0 {
2920 (e.abs_x - e.x_min) * f64::from(width) / range
2921 } else {
2922 0.0
2923 }
2924 } else {
2925 0.0
2926 }
2927}
2928
2929#[no_mangle]
2930pub unsafe extern "C" fn libinput_event_pointer_get_absolute_y_transformed(
2931 event: *const LibinputEvent,
2932 height: u32,
2933) -> f64 {
2934 if event.is_null() {
2935 return 0.0;
2936 }
2937 if let EventPayload::PointerMotionAbsolute(e) = &(*event).payload {
2938 let range = e.y_max - e.y_min;
2939 if range > 0.0 {
2940 (e.abs_y - e.y_min) * f64::from(height) / range
2941 } else {
2942 0.0
2943 }
2944 } else {
2945 0.0
2946 }
2947}
2948
2949#[no_mangle]
2950pub unsafe extern "C" fn libinput_event_pointer_get_scroll_value(
2951 event: *const LibinputEvent,
2952 axis: u32,
2953) -> f64 {
2954 libinput_event_pointer_get_axis_value(event, axis)
2955}
2956
2957#[no_mangle]
2958pub unsafe extern "C" fn libinput_event_pointer_get_scroll_value_v120(
2959 event: *const LibinputEvent,
2960 axis: u32,
2961) -> f64 {
2962 if event.is_null() {
2963 return 0.0;
2964 }
2965 if let EventPayload::PointerAxis(e) = &(*event).payload {
2966 return e.value_v120(axis);
2967 }
2968 0.0
2969}
2970
2971#[no_mangle]
2972pub unsafe extern "C" fn libinput_event_switch_get_time_usec(event: *const LibinputEvent) -> u64 {
2973 if event.is_null() {
2974 return 0;
2975 }
2976 if let EventPayload::SwitchToggle(e) = &(*event).payload {
2977 e.time_usec
2978 } else {
2979 0
2980 }
2981}
2982
2983#[no_mangle]
2984pub unsafe extern "C" fn libinput_event_switch_get_time(event: *const LibinputEvent) -> u32 {
2985 (libinput_event_switch_get_time_usec(event) / 1000) as u32
2986}
2987
2988#[no_mangle]
2989pub unsafe extern "C" fn libinput_event_tablet_pad_get_button_number(
2990 event: *const LibinputEvent,
2991) -> u32 {
2992 if event.is_null() {
2993 return 0;
2994 }
2995 match &(*event).payload {
2996 EventPayload::TabletPad(pad) => pad.button,
2997 _ => 0,
2998 }
2999}
3000
3001#[no_mangle]
3002pub unsafe extern "C" fn libinput_event_tablet_pad_get_button_state(
3003 event: *const LibinputEvent,
3004) -> u32 {
3005 if event.is_null() {
3006 return 0;
3007 }
3008 match &(*event).payload {
3009 EventPayload::TabletPad(pad) => pad.button_state,
3010 _ => 0,
3011 }
3012}
3013
3014#[no_mangle]
3015pub unsafe extern "C" fn libinput_event_tablet_pad_get_key(event: *const LibinputEvent) -> u32 {
3016 if event.is_null() {
3017 return 0;
3018 }
3019 match &(*event).payload {
3020 EventPayload::TabletPad(pad) => pad.key,
3021 _ => 0,
3022 }
3023}
3024
3025#[no_mangle]
3026pub unsafe extern "C" fn libinput_event_tablet_pad_get_key_state(
3027 event: *const LibinputEvent,
3028) -> u32 {
3029 if event.is_null() {
3030 return 0;
3031 }
3032 match &(*event).payload {
3033 EventPayload::TabletPad(pad) => pad.key_state,
3034 _ => 0,
3035 }
3036}
3037
3038#[no_mangle]
3039pub unsafe extern "C" fn libinput_event_tablet_pad_get_dial_delta_v120(
3040 event: *const LibinputEvent,
3041) -> f64 {
3042 if event.is_null() {
3043 return 0.0;
3044 }
3045 match &(*event).payload {
3046 EventPayload::TabletPad(pad) => pad.dial_delta_v120,
3047 _ => 0.0,
3048 }
3049}
3050
3051#[no_mangle]
3052pub unsafe extern "C" fn libinput_event_tablet_pad_get_dial_number(
3053 event: *const LibinputEvent,
3054) -> u32 {
3055 if event.is_null() {
3056 return 0;
3057 }
3058 match &(*event).payload {
3059 EventPayload::TabletPad(pad) => pad.dial_number,
3060 _ => 0,
3061 }
3062}
3063
3064#[no_mangle]
3065pub unsafe extern "C" fn libinput_event_tablet_pad_get_mode(event: *const LibinputEvent) -> u32 {
3066 if event.is_null() {
3067 return 0;
3068 }
3069 match &(*event).payload {
3070 EventPayload::TabletPad(pad) => pad.mode,
3071 _ => 0,
3072 }
3073}
3074
3075#[no_mangle]
3076pub unsafe extern "C" fn libinput_event_tablet_pad_get_mode_group(
3077 event: *const LibinputEvent,
3078) -> *mut libc::c_void {
3079 if event.is_null() {
3080 return std::ptr::null_mut();
3081 }
3082 match &(*event).payload {
3083 EventPayload::TabletPad(pad) => pad.mode_group.cast(),
3084 _ => std::ptr::null_mut(),
3085 }
3086}
3087
3088#[no_mangle]
3089pub unsafe extern "C" fn libinput_event_tablet_pad_get_ring_number(
3090 event: *const LibinputEvent,
3091) -> u32 {
3092 if event.is_null() {
3093 return 0;
3094 }
3095 match &(*event).payload {
3096 EventPayload::TabletPad(pad) => pad.ring_number,
3097 _ => 0,
3098 }
3099}
3100
3101#[no_mangle]
3102pub unsafe extern "C" fn libinput_event_tablet_pad_get_ring_position(
3103 event: *const LibinputEvent,
3104) -> f64 {
3105 if event.is_null() {
3106 return 0.0;
3107 }
3108 match &(*event).payload {
3109 EventPayload::TabletPad(pad) => pad.ring_position,
3110 _ => 0.0,
3111 }
3112}
3113
3114#[no_mangle]
3115pub unsafe extern "C" fn libinput_event_tablet_pad_get_ring_source(
3116 event: *const LibinputEvent,
3117) -> u32 {
3118 if event.is_null() {
3119 return 0;
3120 }
3121 match &(*event).payload {
3122 EventPayload::TabletPad(pad) => pad.ring_source,
3123 _ => 0,
3124 }
3125}
3126
3127#[no_mangle]
3128pub unsafe extern "C" fn libinput_event_tablet_pad_get_strip_number(
3129 event: *const LibinputEvent,
3130) -> u32 {
3131 if event.is_null() {
3132 return 0;
3133 }
3134 match &(*event).payload {
3135 EventPayload::TabletPad(pad) => pad.strip_number,
3136 _ => 0,
3137 }
3138}
3139
3140#[no_mangle]
3141pub unsafe extern "C" fn libinput_event_tablet_pad_get_strip_position(
3142 event: *const LibinputEvent,
3143) -> f64 {
3144 if event.is_null() {
3145 return 0.0;
3146 }
3147 match &(*event).payload {
3148 EventPayload::TabletPad(pad) => pad.strip_position,
3149 _ => 0.0,
3150 }
3151}
3152
3153#[no_mangle]
3154pub unsafe extern "C" fn libinput_event_tablet_pad_get_strip_source(
3155 event: *const LibinputEvent,
3156) -> u32 {
3157 if event.is_null() {
3158 return 0;
3159 }
3160 match &(*event).payload {
3161 EventPayload::TabletPad(pad) => pad.strip_source,
3162 _ => 0,
3163 }
3164}
3165
3166#[no_mangle]
3167pub unsafe extern "C" fn libinput_event_tablet_pad_get_time_usec(
3168 event: *const LibinputEvent,
3169) -> u64 {
3170 if event.is_null() {
3171 return 0;
3172 }
3173 match &(*event).payload {
3174 EventPayload::TabletPad(pad) => pad.time_usec,
3175 _ => 0,
3176 }
3177}
3178
3179#[no_mangle]
3180pub unsafe extern "C" fn libinput_event_tablet_pad_get_time(event: *const LibinputEvent) -> u32 {
3181 (libinput_event_tablet_pad_get_time_usec(event) / 1000) as u32
3182}
3183
3184#[no_mangle]
3185pub unsafe extern "C" fn libinput_event_tablet_tool_get_button(event: *const LibinputEvent) -> u32 {
3186 if event.is_null() {
3187 return 0;
3188 }
3189 match &(*event).payload {
3190 EventPayload::TabletTool(tablet) => tablet.button,
3191 _ => 0,
3192 }
3193}
3194
3195#[no_mangle]
3196pub unsafe extern "C" fn libinput_event_tablet_tool_get_button_state(
3197 event: *const LibinputEvent,
3198) -> u32 {
3199 if event.is_null() {
3200 return 0;
3201 }
3202 match &(*event).payload {
3203 EventPayload::TabletTool(tablet) => tablet.button_state,
3204 _ => 0,
3205 }
3206}
3207
3208#[no_mangle]
3209pub unsafe extern "C" fn libinput_event_tablet_tool_get_seat_button_count(
3210 event: *const LibinputEvent,
3211) -> u32 {
3212 if event.is_null() {
3213 return 0;
3214 }
3215 match &(*event).payload {
3216 EventPayload::TabletTool(tablet) => tablet.seat_button_count,
3217 _ => 0,
3218 }
3219}
3220
3221#[no_mangle]
3222pub unsafe extern "C" fn libinput_event_tablet_tool_get_distance(
3223 event: *const LibinputEvent,
3224) -> f64 {
3225 if event.is_null() {
3226 return 0.0;
3227 }
3228 match &(*event).payload {
3229 EventPayload::TabletTool(tablet) => tablet.distance,
3230 _ => 0.0,
3231 }
3232}
3233
3234#[no_mangle]
3235pub unsafe extern "C" fn libinput_event_tablet_tool_get_dx(event: *const LibinputEvent) -> f64 {
3236 if event.is_null() || (*event).event_type != LibinputEventType::LIBINPUT_EVENT_TABLET_TOOL_AXIS
3237 {
3238 return 0.0;
3239 }
3240 match &(*event).payload {
3241 EventPayload::TabletTool(tablet) => tablet.dx,
3242 _ => 0.0,
3243 }
3244}
3245
3246#[no_mangle]
3247pub unsafe extern "C" fn libinput_event_tablet_tool_get_dy(event: *const LibinputEvent) -> f64 {
3248 if event.is_null() || (*event).event_type != LibinputEventType::LIBINPUT_EVENT_TABLET_TOOL_AXIS
3249 {
3250 return 0.0;
3251 }
3252 match &(*event).payload {
3253 EventPayload::TabletTool(tablet) => tablet.dy,
3254 _ => 0.0,
3255 }
3256}
3257
3258#[no_mangle]
3259pub unsafe extern "C" fn libinput_event_tablet_tool_get_pressure(
3260 event: *const LibinputEvent,
3261) -> f64 {
3262 if event.is_null() {
3263 return 0.0;
3264 }
3265 if let EventPayload::TabletTool(tablet) = &(*event).payload {
3266 let range = tablet.pressure_max - tablet.pressure_min;
3267 if range > 0.0 {
3268 ((tablet.pressure - tablet.pressure_min) / range).clamp(0.0, 1.0)
3269 } else {
3270 0.0
3271 }
3272 } else {
3273 0.0
3274 }
3275}
3276
3277#[no_mangle]
3278pub unsafe extern "C" fn libinput_event_tablet_tool_get_x(event: *const LibinputEvent) -> f64 {
3279 if event.is_null() {
3280 return 0.0;
3281 }
3282 if let EventPayload::TabletTool(tablet) = &(*event).payload {
3283 if tablet.x_resolution > 0.0 {
3284 (tablet.x - tablet.x_min) / tablet.x_resolution
3285 } else {
3286 tablet.x - tablet.x_min
3287 }
3288 } else {
3289 0.0
3290 }
3291}
3292
3293#[no_mangle]
3294pub unsafe extern "C" fn libinput_event_tablet_tool_get_y(event: *const LibinputEvent) -> f64 {
3295 if event.is_null() {
3296 return 0.0;
3297 }
3298 if let EventPayload::TabletTool(tablet) = &(*event).payload {
3299 if tablet.y_resolution > 0.0 {
3300 (tablet.y - tablet.y_min) / tablet.y_resolution
3301 } else {
3302 tablet.y - tablet.y_min
3303 }
3304 } else {
3305 0.0
3306 }
3307}
3308
3309#[no_mangle]
3310pub unsafe extern "C" fn libinput_event_tablet_tool_get_proximity_state(
3311 event: *const LibinputEvent,
3312) -> u32 {
3313 if event.is_null() {
3314 return 0;
3315 }
3316 if let EventPayload::TabletTool(tablet) = &(*event).payload {
3317 tablet.proximity_state
3318 } else {
3319 0
3320 }
3321}
3322
3323#[no_mangle]
3324pub unsafe extern "C" fn libinput_event_tablet_tool_get_rotation(
3325 event: *const LibinputEvent,
3326) -> f64 {
3327 if event.is_null() {
3328 return 0.0;
3329 }
3330 match &(*event).payload {
3331 EventPayload::TabletTool(tablet) => tablet.rotation,
3332 _ => 0.0,
3333 }
3334}
3335
3336#[no_mangle]
3337pub unsafe extern "C" fn libinput_event_tablet_tool_get_slider_position(
3338 event: *const LibinputEvent,
3339) -> f64 {
3340 if event.is_null() {
3341 return 0.0;
3342 }
3343 match &(*event).payload {
3344 EventPayload::TabletTool(tablet) => tablet.slider,
3345 _ => 0.0,
3346 }
3347}
3348
3349#[no_mangle]
3350pub unsafe extern "C" fn libinput_event_tablet_tool_get_wheel_delta(
3351 event: *const LibinputEvent,
3352) -> f64 {
3353 if event.is_null() {
3354 return 0.0;
3355 }
3356 match &(*event).payload {
3357 EventPayload::TabletTool(tablet) => tablet.wheel_delta,
3358 _ => 0.0,
3359 }
3360}
3361
3362#[no_mangle]
3363pub unsafe extern "C" fn libinput_event_tablet_tool_get_wheel_delta_discrete(
3364 event: *const LibinputEvent,
3365) -> i32 {
3366 if event.is_null() {
3367 return 0;
3368 }
3369 match &(*event).payload {
3370 EventPayload::TabletTool(tablet) => tablet.wheel_discrete,
3371 _ => 0,
3372 }
3373}
3374
3375#[no_mangle]
3376pub unsafe extern "C" fn libinput_event_tablet_tool_get_size_major(
3377 event: *const LibinputEvent,
3378) -> f64 {
3379 if event.is_null() {
3380 return 0.0;
3381 }
3382 match &(*event).payload {
3383 EventPayload::TabletTool(tablet) => tablet.size_major,
3384 _ => 0.0,
3385 }
3386}
3387
3388#[no_mangle]
3389pub unsafe extern "C" fn libinput_event_tablet_tool_get_size_minor(
3390 event: *const LibinputEvent,
3391) -> f64 {
3392 if event.is_null() {
3393 return 0.0;
3394 }
3395 match &(*event).payload {
3396 EventPayload::TabletTool(tablet) => tablet.size_minor,
3397 _ => 0.0,
3398 }
3399}
3400
3401#[no_mangle]
3402pub unsafe extern "C" fn libinput_event_tablet_tool_get_tilt_x(event: *const LibinputEvent) -> f64 {
3403 if event.is_null() {
3404 return 0.0;
3405 }
3406 match &(*event).payload {
3407 EventPayload::TabletTool(tablet) => tablet.tilt_x,
3408 _ => 0.0,
3409 }
3410}
3411
3412#[no_mangle]
3413pub unsafe extern "C" fn libinput_event_tablet_tool_get_tilt_y(event: *const LibinputEvent) -> f64 {
3414 if event.is_null() {
3415 return 0.0;
3416 }
3417 match &(*event).payload {
3418 EventPayload::TabletTool(tablet) => tablet.tilt_y,
3419 _ => 0.0,
3420 }
3421}
3422
3423#[no_mangle]
3424pub unsafe extern "C" fn libinput_event_tablet_tool_get_time_usec(
3425 event: *const LibinputEvent,
3426) -> u64 {
3427 if event.is_null() {
3428 return 0;
3429 }
3430 if let EventPayload::TabletTool(tablet) = &(*event).payload {
3431 tablet.time_usec
3432 } else {
3433 0
3434 }
3435}
3436
3437#[no_mangle]
3438pub unsafe extern "C" fn libinput_event_tablet_tool_get_time(event: *const LibinputEvent) -> u32 {
3439 (libinput_event_tablet_tool_get_time_usec(event) / 1000) as u32
3440}
3441
3442#[no_mangle]
3443pub unsafe extern "C" fn libinput_event_tablet_tool_get_tip_state(
3444 event: *const LibinputEvent,
3445) -> u32 {
3446 if event.is_null() {
3447 return 0;
3448 }
3449 match &(*event).payload {
3450 EventPayload::TabletTool(tablet) => tablet.tip_state,
3451 _ => 0,
3452 }
3453}
3454
3455#[no_mangle]
3456pub unsafe extern "C" fn libinput_event_tablet_tool_get_tool(
3457 event: *const LibinputEvent,
3458) -> *mut libc::c_void {
3459 if event.is_null() {
3460 return std::ptr::null_mut();
3461 }
3462 if let EventPayload::TabletTool(tablet) = &(*event).payload {
3463 tablet.tool.cast()
3464 } else {
3465 std::ptr::null_mut()
3466 }
3467}
3468
3469#[no_mangle]
3470pub unsafe extern "C" fn libinput_event_tablet_tool_get_x_transformed(
3471 event: *const LibinputEvent,
3472 width: u32,
3473) -> f64 {
3474 if event.is_null() {
3475 return 0.0;
3476 }
3477 if let EventPayload::TabletTool(tablet) = &(*event).payload {
3478 let range = tablet.x_max - tablet.x_min + 1.0;
3479 if range > 0.0 {
3480 (tablet.x - tablet.x_min) * f64::from(width) / range
3481 } else {
3482 0.0
3483 }
3484 } else {
3485 0.0
3486 }
3487}
3488
3489#[no_mangle]
3490pub unsafe extern "C" fn libinput_event_tablet_tool_get_y_transformed(
3491 event: *const LibinputEvent,
3492 height: u32,
3493) -> f64 {
3494 if event.is_null() {
3495 return 0.0;
3496 }
3497 if let EventPayload::TabletTool(tablet) = &(*event).payload {
3498 let range = tablet.y_max - tablet.y_min + 1.0;
3499 if range > 0.0 {
3500 (tablet.y - tablet.y_min) * f64::from(height) / range
3501 } else {
3502 0.0
3503 }
3504 } else {
3505 0.0
3506 }
3507}
3508
3509#[no_mangle]
3510pub unsafe extern "C" fn libinput_event_tablet_tool_x_has_changed(
3511 event: *const LibinputEvent,
3512) -> libc::c_int {
3513 if event.is_null() {
3514 return 0;
3515 }
3516 match &(*event).payload {
3517 EventPayload::TabletTool(tablet) => tablet.x_changed as libc::c_int,
3518 _ => 0,
3519 }
3520}
3521
3522#[no_mangle]
3523pub unsafe extern "C" fn libinput_event_tablet_tool_y_has_changed(
3524 event: *const LibinputEvent,
3525) -> libc::c_int {
3526 if event.is_null() {
3527 return 0;
3528 }
3529 match &(*event).payload {
3530 EventPayload::TabletTool(tablet) => tablet.y_changed as libc::c_int,
3531 _ => 0,
3532 }
3533}
3534
3535#[no_mangle]
3536pub unsafe extern "C" fn libinput_event_tablet_tool_pressure_has_changed(
3537 event: *const LibinputEvent,
3538) -> libc::c_int {
3539 if event.is_null() {
3540 return 0;
3541 }
3542 match &(*event).payload {
3543 EventPayload::TabletTool(tablet) => tablet.pressure_changed as libc::c_int,
3544 _ => 0,
3545 }
3546}
3547
3548#[no_mangle]
3549pub unsafe extern "C" fn libinput_event_tablet_tool_distance_has_changed(
3550 event: *const LibinputEvent,
3551) -> libc::c_int {
3552 if event.is_null() {
3553 return 0;
3554 }
3555 match &(*event).payload {
3556 EventPayload::TabletTool(tablet) => tablet.distance_changed as libc::c_int,
3557 _ => 0,
3558 }
3559}
3560
3561#[no_mangle]
3562pub unsafe extern "C" fn libinput_event_tablet_tool_tilt_x_has_changed(
3563 event: *const LibinputEvent,
3564) -> libc::c_int {
3565 if event.is_null() {
3566 return 0;
3567 }
3568 match &(*event).payload {
3569 EventPayload::TabletTool(tablet) => tablet.tilt_x_changed as libc::c_int,
3570 _ => 0,
3571 }
3572}
3573
3574#[no_mangle]
3575pub unsafe extern "C" fn libinput_event_tablet_tool_tilt_y_has_changed(
3576 event: *const LibinputEvent,
3577) -> libc::c_int {
3578 if event.is_null() {
3579 return 0;
3580 }
3581 match &(*event).payload {
3582 EventPayload::TabletTool(tablet) => tablet.tilt_y_changed as libc::c_int,
3583 _ => 0,
3584 }
3585}
3586
3587#[no_mangle]
3588pub unsafe extern "C" fn libinput_event_tablet_tool_rotation_has_changed(
3589 event: *const LibinputEvent,
3590) -> libc::c_int {
3591 if event.is_null() {
3592 return 0;
3593 }
3594 match &(*event).payload {
3595 EventPayload::TabletTool(tablet) => tablet.rotation_changed as libc::c_int,
3596 _ => 0,
3597 }
3598}
3599
3600#[no_mangle]
3601pub unsafe extern "C" fn libinput_event_tablet_tool_slider_has_changed(
3602 event: *const LibinputEvent,
3603) -> libc::c_int {
3604 if event.is_null() {
3605 return 0;
3606 }
3607 match &(*event).payload {
3608 EventPayload::TabletTool(tablet) => tablet.slider_changed as libc::c_int,
3609 _ => 0,
3610 }
3611}
3612
3613#[no_mangle]
3614pub unsafe extern "C" fn libinput_event_tablet_tool_wheel_has_changed(
3615 event: *const LibinputEvent,
3616) -> libc::c_int {
3617 if event.is_null() {
3618 return 0;
3619 }
3620 match &(*event).payload {
3621 EventPayload::TabletTool(tablet) => tablet.wheel_changed as libc::c_int,
3622 _ => 0,
3623 }
3624}
3625
3626#[no_mangle]
3627pub unsafe extern "C" fn libinput_event_tablet_tool_size_major_has_changed(
3628 event: *const LibinputEvent,
3629) -> libc::c_int {
3630 if event.is_null() {
3631 return 0;
3632 }
3633 match &(*event).payload {
3634 EventPayload::TabletTool(tablet) => tablet.size_major_changed as libc::c_int,
3635 _ => 0,
3636 }
3637}
3638
3639#[no_mangle]
3640pub unsafe extern "C" fn libinput_event_tablet_tool_size_minor_has_changed(
3641 event: *const LibinputEvent,
3642) -> libc::c_int {
3643 if event.is_null() {
3644 return 0;
3645 }
3646 match &(*event).payload {
3647 EventPayload::TabletTool(tablet) => tablet.size_minor_changed as libc::c_int,
3648 _ => 0,
3649 }
3650}
3651
3652#[no_mangle]
3653pub unsafe extern "C" fn libinput_plugin_system_append_default_paths(_ctx: *mut LibinputContext) {}
3654
3655#[no_mangle]
3656pub unsafe extern "C" fn libinput_plugin_system_append_path(
3657 _ctx: *mut LibinputContext,
3658 _path: *const libc::c_char,
3659) {
3660}
3661
3662#[no_mangle]
3663pub unsafe extern "C" fn libinput_plugin_system_load_plugins(
3664 _ctx: *mut LibinputContext,
3665 _flags: libc::c_uint,
3666) -> libc::c_int {
3667 -libc::ENOSYS
3668}
3669
3670#[no_mangle]
3671pub unsafe extern "C" fn libinput_tablet_pad_mode_group_button_is_toggle(
3672 _group: *const libc::c_void,
3673 _button: u32,
3674) -> libc::c_int {
3675 0
3676}
3677
3678#[no_mangle]
3679pub unsafe extern "C" fn libinput_tablet_pad_mode_group_get_index(
3680 group: *const libc::c_void,
3681) -> u32 {
3682 if group.is_null() {
3683 return 0;
3684 }
3685 (*group.cast::<LibinputTabletPadModeGroup>()).index
3686}
3687
3688#[no_mangle]
3689pub unsafe extern "C" fn libinput_tablet_pad_mode_group_get_mode(
3690 group: *const libc::c_void,
3691) -> u32 {
3692 if group.is_null() {
3693 return 0;
3694 }
3695 (*group.cast::<LibinputTabletPadModeGroup>()).current_mode
3696}
3697
3698#[no_mangle]
3699pub unsafe extern "C" fn libinput_tablet_pad_mode_group_get_num_modes(
3700 group: *const libc::c_void,
3701) -> u32 {
3702 if group.is_null() {
3703 return 0;
3704 }
3705 (*group.cast::<LibinputTabletPadModeGroup>()).num_modes
3706}
3707
3708#[no_mangle]
3709pub unsafe extern "C" fn libinput_tablet_pad_mode_group_has_button(
3710 group: *const libc::c_void,
3711 button: u32,
3712) -> libc::c_int {
3713 if group.is_null() {
3714 return 0;
3715 }
3716 (button < (*group.cast::<LibinputTabletPadModeGroup>()).num_buttons) as libc::c_int
3717}
3718
3719#[no_mangle]
3720pub unsafe extern "C" fn libinput_tablet_pad_mode_group_has_dial(
3721 group: *const libc::c_void,
3722 dial: u32,
3723) -> libc::c_int {
3724 if group.is_null() {
3725 return 0;
3726 }
3727 (dial < (*group.cast::<LibinputTabletPadModeGroup>()).num_dials) as libc::c_int
3728}
3729
3730#[no_mangle]
3731pub unsafe extern "C" fn libinput_tablet_pad_mode_group_has_ring(
3732 group: *const libc::c_void,
3733 ring: u32,
3734) -> libc::c_int {
3735 if group.is_null() {
3736 return 0;
3737 }
3738 (ring < (*group.cast::<LibinputTabletPadModeGroup>()).num_rings) as libc::c_int
3739}
3740
3741#[no_mangle]
3742pub unsafe extern "C" fn libinput_tablet_pad_mode_group_has_strip(
3743 group: *const libc::c_void,
3744 strip: u32,
3745) -> libc::c_int {
3746 if group.is_null() {
3747 return 0;
3748 }
3749 (strip < (*group.cast::<LibinputTabletPadModeGroup>()).num_strips) as libc::c_int
3750}
3751
3752#[no_mangle]
3753pub unsafe extern "C" fn libinput_tablet_pad_mode_group_ref(
3754 group: *mut libc::c_void,
3755) -> *mut libc::c_void {
3756 if !group.is_null() {
3757 (*group.cast::<LibinputTabletPadModeGroup>())
3758 .refcount
3759 .fetch_add(1, std::sync::atomic::Ordering::Relaxed);
3760 }
3761 group
3762}
3763
3764#[no_mangle]
3765pub unsafe extern "C" fn libinput_tablet_pad_mode_group_unref(
3766 group: *mut libc::c_void,
3767) -> *mut libc::c_void {
3768 if group.is_null() {
3769 return std::ptr::null_mut();
3770 }
3771 let group_ref = &*group.cast::<LibinputTabletPadModeGroup>();
3772 let current = group_ref
3773 .refcount
3774 .load(std::sync::atomic::Ordering::Relaxed);
3775 if current > 1 {
3776 group_ref
3777 .refcount
3778 .fetch_sub(1, std::sync::atomic::Ordering::AcqRel);
3779 }
3780 group
3781}
3782
3783#[no_mangle]
3784pub unsafe extern "C" fn libinput_tablet_pad_mode_group_set_user_data(
3785 group: *mut libc::c_void,
3786 data: *mut libc::c_void,
3787) {
3788 if !group.is_null() {
3789 (*group.cast::<LibinputTabletPadModeGroup>()).user_data = data;
3790 }
3791}
3792
3793#[no_mangle]
3794pub unsafe extern "C" fn libinput_tablet_pad_mode_group_get_user_data(
3795 group: *const libc::c_void,
3796) -> *mut libc::c_void {
3797 if group.is_null() {
3798 return std::ptr::null_mut();
3799 }
3800 (*group.cast::<LibinputTabletPadModeGroup>()).user_data
3801}
3802
3803#[no_mangle]
3804pub unsafe extern "C" fn libinput_tablet_tool_config_pressure_range_is_available(
3805 tool: *const LibinputTabletTool,
3806) -> libc::c_int {
3807 (!tool.is_null() && (*tool).has_pressure) as libc::c_int
3808}
3809
3810#[no_mangle]
3811pub unsafe extern "C" fn libinput_tablet_tool_config_pressure_range_set(
3812 tool: *mut LibinputTabletTool,
3813 minimum: f64,
3814 maximum: f64,
3815) -> u32 {
3816 if tool.is_null() || !(*tool).has_pressure {
3817 return 1;
3818 }
3819 if minimum < 0.0 || maximum > 1.0 || minimum >= maximum {
3820 return 2;
3821 }
3822 (*tool).wanted_pressure_range_minimum = minimum;
3823 (*tool).wanted_pressure_range_maximum = maximum;
3824 0
3825}
3826
3827#[no_mangle]
3828pub unsafe extern "C" fn libinput_tablet_tool_config_pressure_range_get_minimum(
3829 tool: *const LibinputTabletTool,
3830) -> f64 {
3831 if tool.is_null() {
3832 0.0
3833 } else {
3834 (*tool).wanted_pressure_range_minimum
3835 }
3836}
3837
3838#[no_mangle]
3839pub unsafe extern "C" fn libinput_tablet_tool_config_pressure_range_get_maximum(
3840 tool: *const LibinputTabletTool,
3841) -> f64 {
3842 if tool.is_null() {
3843 1.0
3844 } else {
3845 (*tool).wanted_pressure_range_maximum
3846 }
3847}
3848
3849#[no_mangle]
3850pub unsafe extern "C" fn libinput_tablet_tool_config_pressure_range_get_default_minimum(
3851 _tool: *const libc::c_void,
3852) -> f64 {
3853 0.0
3854}
3855
3856#[no_mangle]
3857pub unsafe extern "C" fn libinput_tablet_tool_config_pressure_range_get_default_maximum(
3858 _tool: *const libc::c_void,
3859) -> f64 {
3860 1.0
3861}
3862
3863#[no_mangle]
3864pub unsafe extern "C" fn libinput_tablet_tool_config_eraser_button_get_modes(
3865 tool: *const libc::c_void,
3866) -> u32 {
3867 let tool = tool.cast::<LibinputTabletTool>();
3868 if tool.is_null() {
3869 0
3870 } else {
3871 (*tool).eraser_button_modes
3872 }
3873}
3874
3875#[no_mangle]
3876pub unsafe extern "C" fn libinput_tablet_tool_config_eraser_button_set_mode(
3877 tool: *mut libc::c_void,
3878 mode: u32,
3879) -> u32 {
3880 let tool = tool.cast::<LibinputTabletTool>();
3881 if tool.is_null() || (mode != 0 && ((*tool).eraser_button_modes & mode) == 0) {
3882 return 1;
3883 }
3884 if !matches!(mode, 0 | 1) {
3885 return 2;
3886 }
3887 (*tool).wanted_eraser_button_mode = mode;
3888 if !(*tool).in_proximity {
3889 (*tool).eraser_button_mode = mode;
3890 }
3891 0
3892}
3893
3894#[no_mangle]
3895pub unsafe extern "C" fn libinput_tablet_tool_config_eraser_button_get_mode(
3896 tool: *const libc::c_void,
3897) -> u32 {
3898 let tool = tool.cast::<LibinputTabletTool>();
3899 if tool.is_null() || (*tool).eraser_button_modes == 0 {
3900 0
3901 } else {
3902 (*tool).wanted_eraser_button_mode
3903 }
3904}
3905
3906#[no_mangle]
3907pub unsafe extern "C" fn libinput_tablet_tool_config_eraser_button_get_default_mode(
3908 _tool: *const libc::c_void,
3909) -> u32 {
3910 0
3911}
3912
3913#[no_mangle]
3914pub unsafe extern "C" fn libinput_tablet_tool_config_eraser_button_set_button(
3915 tool: *mut libc::c_void,
3916 button: u32,
3917) -> u32 {
3918 let tool = tool.cast::<LibinputTabletTool>();
3919 if tool.is_null() || (*tool).eraser_button_modes == 0 {
3920 return 1;
3921 }
3922 let is_button = matches!(button, 0x149 | 0x14b | 0x14c)
3923 || (0x100..0x140).contains(&button)
3924 || (0x150..=0x151).contains(&button)
3925 || (0x220..=0x223).contains(&button)
3926 || (0x2c0..=0x2e7).contains(&button);
3927 if !is_button {
3928 return 2;
3929 }
3930 (*tool).wanted_eraser_button = button;
3931 if !(*tool).in_proximity {
3932 (*tool).eraser_button = button;
3933 }
3934 0
3935}
3936
3937#[no_mangle]
3938pub unsafe extern "C" fn libinput_tablet_tool_config_eraser_button_get_button(
3939 tool: *const libc::c_void,
3940) -> u32 {
3941 let tool = tool.cast::<LibinputTabletTool>();
3942 if tool.is_null() || (*tool).eraser_button_modes == 0 {
3943 0
3944 } else {
3945 (*tool).wanted_eraser_button
3946 }
3947}
3948
3949#[no_mangle]
3950pub unsafe extern "C" fn libinput_tablet_tool_config_eraser_button_get_default_button(
3951 tool: *const libc::c_void,
3952) -> u32 {
3953 let tool = tool.cast::<LibinputTabletTool>();
3954 if tool.is_null() || (*tool).eraser_button_modes == 0 {
3955 0
3956 } else {
3957 (*tool).default_eraser_button
3958 }
3959}
3960
3961#[no_mangle]
3962pub unsafe extern "C" fn libinput_tablet_tool_get_name(
3963 tool: *const libc::c_void,
3964) -> *const libc::c_char {
3965 let tool = tool.cast::<LibinputTabletTool>();
3966 if tool.is_null() {
3967 return std::ptr::null();
3968 }
3969 let tool = tool.cast::<LibinputTabletTool>();
3970 let tool = tool as *mut LibinputTabletTool;
3971 if let Some(name) = (*tool).name.as_ref() {
3972 return name.as_ptr();
3973 }
3974 if let Some(name) = crate::backend::tablet_tool_name_for_id((*tool).tool_id) {
3975 (*tool).name = Some(name);
3976 (*tool)
3977 .name
3978 .as_ref()
3979 .map_or(std::ptr::null(), |name| name.as_ptr())
3980 } else {
3981 std::ptr::null()
3982 }
3983}
3984
3985#[no_mangle]
3986pub unsafe extern "C" fn libinput_tablet_tool_get_serial(tool: *const libc::c_void) -> u64 {
3987 let tool = tool.cast::<LibinputTabletTool>();
3988 if tool.is_null() {
3989 0
3990 } else {
3991 (*tool).serial
3992 }
3993}
3994
3995#[no_mangle]
3996pub unsafe extern "C" fn libinput_tablet_tool_get_tool_id(tool: *const libc::c_void) -> u64 {
3997 let tool = tool.cast::<LibinputTabletTool>();
3998 if tool.is_null() {
3999 0
4000 } else {
4001 (*tool).tool_id
4002 }
4003}
4004
4005#[no_mangle]
4006pub unsafe extern "C" fn libinput_tablet_tool_get_type(tool: *const libc::c_void) -> u32 {
4007 let tool = tool.cast::<LibinputTabletTool>();
4008 if tool.is_null() {
4009 0
4010 } else {
4011 (*tool).tool_type
4012 }
4013}
4014
4015#[no_mangle]
4016pub unsafe extern "C" fn libinput_tablet_tool_has_distance(
4017 tool: *const libc::c_void,
4018) -> libc::c_int {
4019 let tool = tool.cast::<LibinputTabletTool>();
4020 (!tool.is_null() && (*tool).has_distance) as libc::c_int
4021}
4022
4023#[no_mangle]
4024pub unsafe extern "C" fn libinput_tablet_tool_has_button(
4025 tool: *const libc::c_void,
4026 button: u32,
4027) -> libc::c_int {
4028 let tool = tool.cast::<LibinputTabletTool>();
4029 (!tool.is_null() && (*tool).buttons.contains(&button)) as libc::c_int
4030}
4031
4032#[no_mangle]
4033pub unsafe extern "C" fn libinput_tablet_tool_has_size(tool: *const libc::c_void) -> libc::c_int {
4034 let tool = tool.cast::<LibinputTabletTool>();
4035 (!tool.is_null() && (*tool).has_size) as libc::c_int
4036}
4037
4038#[no_mangle]
4039pub unsafe extern "C" fn libinput_tablet_tool_is_unique(tool: *const libc::c_void) -> libc::c_int {
4040 let tool = tool.cast::<LibinputTabletTool>();
4041 (!tool.is_null() && (*tool).serial != 0) as libc::c_int
4042}
4043
4044#[no_mangle]
4045pub unsafe extern "C" fn libinput_tablet_tool_set_user_data(
4046 tool: *mut libc::c_void,
4047 data: *mut libc::c_void,
4048) {
4049 let tool = tool.cast::<LibinputTabletTool>();
4050 if !tool.is_null() {
4051 (*tool).user_data = data;
4052 }
4053}
4054
4055#[no_mangle]
4056pub unsafe extern "C" fn libinput_tablet_tool_get_user_data(
4057 tool: *const libc::c_void,
4058) -> *mut libc::c_void {
4059 let tool = tool.cast::<LibinputTabletTool>();
4060 if tool.is_null() {
4061 std::ptr::null_mut()
4062 } else {
4063 (*tool).user_data
4064 }
4065}
4066
4067#[no_mangle]
4068pub unsafe extern "C" fn libinput_tablet_tool_has_pressure(
4069 tool: *const libc::c_void,
4070) -> libc::c_int {
4071 let tool = tool.cast::<LibinputTabletTool>();
4072 (!tool.is_null() && (*tool).has_pressure) as libc::c_int
4073}
4074
4075#[no_mangle]
4076pub unsafe extern "C" fn libinput_tablet_tool_has_rotation(
4077 tool: *const libc::c_void,
4078) -> libc::c_int {
4079 let tool = tool.cast::<LibinputTabletTool>();
4080 (!tool.is_null() && (*tool).has_rotation) as libc::c_int
4081}
4082
4083#[no_mangle]
4084pub unsafe extern "C" fn libinput_tablet_tool_has_slider(tool: *const libc::c_void) -> libc::c_int {
4085 let tool = tool.cast::<LibinputTabletTool>();
4086 (!tool.is_null() && (*tool).has_slider) as libc::c_int
4087}
4088
4089#[no_mangle]
4090pub unsafe extern "C" fn libinput_tablet_tool_has_tilt(tool: *const libc::c_void) -> libc::c_int {
4091 let tool = tool.cast::<LibinputTabletTool>();
4092 (!tool.is_null() && (*tool).has_tilt) as libc::c_int
4093}
4094
4095#[no_mangle]
4096pub unsafe extern "C" fn libinput_tablet_tool_has_wheel(tool: *const libc::c_void) -> libc::c_int {
4097 let tool = tool.cast::<LibinputTabletTool>();
4098 (!tool.is_null() && (*tool).has_wheel) as libc::c_int
4099}
4100
4101#[no_mangle]
4102pub unsafe extern "C" fn libinput_tablet_tool_ref(tool: *mut libc::c_void) -> *mut libc::c_void {
4103 let tablet_tool = tool.cast::<LibinputTabletTool>();
4104 if !tablet_tool.is_null() {
4105 (*tablet_tool)
4106 .refcount
4107 .fetch_add(1, std::sync::atomic::Ordering::Relaxed);
4108 }
4109 tool
4110}
4111
4112#[no_mangle]
4113pub unsafe extern "C" fn libinput_tablet_tool_unref(tool: *mut libc::c_void) -> *mut libc::c_void {
4114 let tablet_tool = tool.cast::<LibinputTabletTool>();
4115 if tablet_tool.is_null() {
4116 return std::ptr::null_mut();
4117 }
4118 if (*tablet_tool)
4119 .refcount
4120 .fetch_sub(1, std::sync::atomic::Ordering::AcqRel)
4121 == 1
4122 {
4123 drop(Box::from_raw(tablet_tool));
4124 std::ptr::null_mut()
4125 } else {
4126 tool
4127 }
4128}
4129
4130#[no_mangle]
4135pub unsafe extern "C" fn libinput_suspend(ctx: *mut LibinputContext) {
4136 if ctx.is_null() {
4137 return;
4138 }
4139 let mut events = std::collections::VecDeque::new();
4140 if let Ok(mut backend) = (*ctx).backend.lock() {
4141 backend.suspend(ctx, &mut events);
4142 }
4143 (*ctx).event_queue.extend(events);
4144}
4145
4146#[no_mangle]
4147pub unsafe extern "C" fn libinput_resume(ctx: *mut LibinputContext) -> libc::c_int {
4148 if ctx.is_null() {
4149 return -1;
4150 }
4151 let mut events = std::collections::VecDeque::new();
4152 let status = if let Ok(mut backend) = (*ctx).backend.lock() {
4153 backend.resume(ctx, &mut events)
4154 } else {
4155 return -1;
4156 };
4157 (*ctx).event_queue.extend(events);
4158 if !(*ctx).event_queue.is_empty() {
4159 (*ctx).signal_fd();
4160 }
4161 status
4162}
4163
4164#[cfg(test)]
4165mod tests {
4166 use super::*;
4167
4168 unsafe extern "C" fn deny_open(
4169 _path: *const libc::c_char,
4170 _flags: libc::c_int,
4171 _user_data: *mut libc::c_void,
4172 ) -> libc::c_int {
4173 -libc::EACCES
4174 }
4175
4176 unsafe extern "C" fn close_fd(_fd: libc::c_int, _user_data: *mut libc::c_void) {}
4177
4178 static INTERFACE: LibinputInterface = LibinputInterface {
4179 open_restricted: Some(deny_open),
4180 close_restricted: Some(close_fd),
4181 };
4182
4183 #[test]
4184 fn udev_context_requires_interface_and_udev() {
4185 unsafe {
4186 let fake_udev = 1usize as *mut libc::c_void;
4187 assert!(libinput_udev_create_context(
4188 std::ptr::null(),
4189 std::ptr::null_mut(),
4190 fake_udev,
4191 )
4192 .is_null());
4193 assert!(libinput_udev_create_context(
4194 &INTERFACE,
4195 std::ptr::null_mut(),
4196 std::ptr::null_mut(),
4197 )
4198 .is_null());
4199 }
4200 }
4201
4202 #[test]
4203 fn seat_assignment_is_udev_only_and_happens_once() {
4204 unsafe {
4205 let fake_udev = 1usize as *mut libc::c_void;
4206 let seat = std::ffi::CString::new("seat0").unwrap();
4207 let udev_ctx =
4208 libinput_udev_create_context(&INTERFACE, std::ptr::null_mut(), fake_udev);
4209 assert!(!udev_ctx.is_null());
4210 assert_eq!(libinput_udev_assign_seat(udev_ctx, seat.as_ptr()), 0);
4211 assert_eq!(libinput_udev_assign_seat(udev_ctx, seat.as_ptr()), -1);
4212 libinput_unref(udev_ctx);
4213
4214 let path_ctx = libinput_path_create_context(&INTERFACE, std::ptr::null_mut());
4215 assert!(!path_ctx.is_null());
4216 assert_eq!(libinput_udev_assign_seat(path_ctx, seat.as_ptr()), -1);
4217 libinput_unref(path_ctx);
4218 }
4219 }
4220
4221 #[test]
4222 fn suspend_and_resume_are_null_safe() {
4223 unsafe {
4224 libinput_suspend(std::ptr::null_mut());
4225 assert_eq!(libinput_resume(std::ptr::null_mut()), -1);
4226 }
4227 }
4228}