git.lucas.co / cce-mail
mail client (IMAP/SMTP)
git clone https://git.lucas.co/cce-mail.git

src/wpe/input.rs (5.3K)

  1 //! Translating cce-ui input into `WPEEvent`s.
  2 //!
  3 //! Unlike the Servo backend — where `main.rs` carried `dom_key`/`dom_button`
  4 //! helpers and the host took engine types — the mapping lives *here* and
  5 //! [`super::WebKitHost`] takes cce-ui's own `MouseButton` / `KeyEvent`. That
  6 //! keeps engine vocabulary out of the chrome, so switching backends deletes
  7 //! those helpers from `main.rs` rather than rewriting them.
  8 //!
  9 //! **Keyboard is the fiddly part.** `wpe_event_keyboard_new` wants an X11
 10 //! *keysym* (`keyval`), not a character. Latin-1 codepoints are their own
 11 //! keysym; anything above maps to `codepoint + 0x0100_0000`; named keys have
 12 //! fixed `XK_*` values. Getting this wrong is silent — the page just receives
 13 //! nothing useful.
 14 
 15 use cce_ui::widget::{ElementState, Key, KeyEvent, MouseButton, NamedKey};
 16 
 17 use super::ffi::*;
 18 
 19 /// X11 keysyms for the named keys cce-ui reports (`/usr/include/X11/keysymdef.h`).
 20 mod keysym {
 21     pub const BACKSPACE: u32 = 0xff08;
 22     pub const TAB: u32 = 0xff09;
 23     pub const RETURN: u32 = 0xff0d;
 24     pub const ESCAPE: u32 = 0xff1b;
 25     pub const SPACE: u32 = 0x0020;
 26     pub const HOME: u32 = 0xff50;
 27     pub const LEFT: u32 = 0xff51;
 28     pub const UP: u32 = 0xff52;
 29     pub const RIGHT: u32 = 0xff53;
 30     pub const DOWN: u32 = 0xff54;
 31     pub const PAGE_UP: u32 = 0xff55;
 32     pub const PAGE_DOWN: u32 = 0xff56;
 33     pub const END: u32 = 0xff57;
 34     pub const DELETE: u32 = 0xffff;
 35     pub const F1: u32 = 0xffbe;
 36     pub const F2: u32 = 0xffbf;
 37     pub const F3: u32 = 0xffc0;
 38     pub const F4: u32 = 0xffc1;
 39     pub const F5: u32 = 0xffc2;
 40     pub const F6: u32 = 0xffc3;
 41     pub const F7: u32 = 0xffc4;
 42     pub const F8: u32 = 0xffc5;
 43     pub const F9: u32 = 0xffc6;
 44     pub const F10: u32 = 0xffc7;
 45     pub const F11: u32 = 0xffc8;
 46     pub const F12: u32 = 0xffc9;
 47     pub const SHIFT_L: u32 = 0xffe1;
 48     pub const CONTROL_L: u32 = 0xffe3;
 49     pub const ALT_L: u32 = 0xffe9;
 50     pub const SUPER_L: u32 = 0xffeb;
 51 }
 52 
 53 /// A Unicode scalar as an X11 keysym: Latin-1 is identity, the rest is the
 54 /// codepoint in the 0x01000000 plane.
 55 fn unicode_keysym(c: char) -> u32 {
 56     match c as u32 {
 57         cp @ 0x20..=0xff => cp,
 58         cp => cp + 0x0100_0000,
 59     }
 60 }
 61 
 62 /// cce-ui key -> X11 keysym. `None` for keys with no sensible mapping.
 63 pub(super) fn keyval(key: &Key) -> Option<u32> {
 64     Some(match key {
 65         Key::Character(s) => unicode_keysym(s.chars().next()?),
 66         Key::Named(n) => match n {
 67             NamedKey::Backspace => keysym::BACKSPACE,
 68             NamedKey::Tab => keysym::TAB,
 69             NamedKey::Enter => keysym::RETURN,
 70             NamedKey::Escape => keysym::ESCAPE,
 71             NamedKey::Space => keysym::SPACE,
 72             NamedKey::ArrowDown => keysym::DOWN,
 73             NamedKey::ArrowLeft => keysym::LEFT,
 74             NamedKey::ArrowRight => keysym::RIGHT,
 75             NamedKey::ArrowUp => keysym::UP,
 76             NamedKey::End => keysym::END,
 77             NamedKey::Home => keysym::HOME,
 78             NamedKey::PageDown => keysym::PAGE_DOWN,
 79             NamedKey::PageUp => keysym::PAGE_UP,
 80             NamedKey::Delete => keysym::DELETE,
 81             NamedKey::Control => keysym::CONTROL_L,
 82             NamedKey::Shift => keysym::SHIFT_L,
 83             NamedKey::Alt => keysym::ALT_L,
 84             NamedKey::Super => keysym::SUPER_L,
 85             NamedKey::F1 => keysym::F1,
 86             NamedKey::F2 => keysym::F2,
 87             NamedKey::F3 => keysym::F3,
 88             NamedKey::F4 => keysym::F4,
 89             NamedKey::F5 => keysym::F5,
 90             NamedKey::F6 => keysym::F6,
 91             NamedKey::F7 => keysym::F7,
 92             NamedKey::F8 => keysym::F8,
 93             NamedKey::F9 => keysym::F9,
 94             NamedKey::F10 => keysym::F10,
 95             NamedKey::F11 => keysym::F11,
 96             NamedKey::F12 => keysym::F12,
 97         },
 98     })
 99 }
100 
101 /// X11 button numbering, which is what WPE expects.
102 pub(super) fn button_number(b: MouseButton) -> Option<u32> {
103     Some(match b {
104         MouseButton::Left => 1,
105         MouseButton::Middle => 2,
106         MouseButton::Right => 3,
107         // Back/Forward are chrome navigation in `main.rs`, deliberately not
108         // forwarded to the page.
109         _ => return None,
110     })
111 }
112 
113 /// An X11 button number's held-button bit, the form a pointer event's
114 /// modifiers carry it in (`WPE_MODIFIER_POINTER_BUTTON1` is button 1, and the
115 /// five are consecutive).
116 pub(super) fn button_modifier(n: u32) -> WPEModifiers::Type {
117     match n {
118         1..=5 => WPEModifiers::WPE_MODIFIER_POINTER_BUTTON1 << (n - 1),
119         _ => 0,
120     }
121 }
122 
123 pub(super) fn modifiers(ctrl: bool, shift: bool, alt: bool) -> WPEModifiers::Type {
124     let mut m: WPEModifiers::Type = 0;
125     if ctrl {
126         m |= WPEModifiers::WPE_MODIFIER_KEYBOARD_CONTROL;
127     }
128     if shift {
129         m |= WPEModifiers::WPE_MODIFIER_KEYBOARD_SHIFT;
130     }
131     if alt {
132         m |= WPEModifiers::WPE_MODIFIER_KEYBOARD_ALT;
133     }
134     m
135 }
136 
137 pub(super) fn is_pressed(e: &KeyEvent) -> bool {
138     e.state == ElementState::Pressed
139 }
140 
141 /// WPE stamps events with a millisecond clock. It only has to be monotonic
142 /// and consistent — `wpe_view_compute_press_count` uses it for double-click
143 /// detection, so a frozen value would turn every click into a triple-click.
144 pub(super) fn now_ms() -> u32 {
145     use std::time::{SystemTime, UNIX_EPOCH};
146     SystemTime::now()
147         .duration_since(UNIX_EPOCH)
148         .map(|d| d.as_millis() as u32)
149         .unwrap_or(0)
150 }