/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use msg::constellation_msg::{Key, KeyState, KeyModifiers, SHIFT}; /// Takes a character and returns an Option containing a tuple of the /// corresponding keycode and whether shift is required. This is /// currently pretty much ascii-only and the webdriver spec isn't /// entirely clear on how to deal with characters outside this /// range. Returns None if no key corresponding to the character is /// matched. fn key_from_char(key_string: &char) -> Option<(Key, bool)> { match *key_string { ' ' => Some((Key::Space, false)), '\'' => Some((Key::Apostrophe, true)), '\"' => Some((Key::Apostrophe, false)), '<' => Some((Key::Comma, true)), ',' => Some((Key::Comma, false)), '_' => Some((Key::Minus, true)), '-' => Some((Key::Minus, false)), '>' => Some((Key::Period, true)), '.' => Some((Key::Period, false)), '?' => Some((Key::Slash, true)), '/' => Some((Key::Slash, false)), '~' => Some((Key::GraveAccent, true)), '`' => Some((Key::GraveAccent, false)), ')' => Some((Key::Num0, true)), '0' => Some((Key::Num0, false)), '!' => Some((Key::Num1, true)), '1' => Some((Key::Num1, false)), '@' => Some((Key::Num2, true)), '2' => Some((Key::Num2, false)), '#' => Some((Key::Num3, true)), '3' => Some((Key::Num3, false)), '$' => Some((Key::Num4, true)), '4' => Some((Key::Num4, false)), '%' => Some((Key::Num5, true)), '5' => Some((Key::Num5, false)), '^' => Some((Key::Num6, true)), '6' => Some((Key::Num6, false)), '&' => Some((Key::Num7, true)), '7' => Some((Key::Num7, false)), '*' => Some((Key::Num8, true)), '8' => Some((Key::Num8, false)), '(' => Some((Key::Num9, true)), '9' => Some((Key::Num9, false)), ':' => Some((Key::Semicolon, true)), ';' => Some((Key::Semicolon, false)), '+' => Some((Key::Equal, true)), '=' => Some((Key::Equal, false)), 'A' => Some((Key::A, true)), 'a' => Some((Key::A, false)), 'B' => Some((Key::B, true)), 'b' => Some((Key::B, false)), 'C' => Some((Key::C, true)), 'c' => Some((Key::C, false)), 'D' => Some((Key::D, true)), 'd' => Some((Key::D, false)), 'E' => Some((Key::E, true)), 'e' => Some((Key::E, false)), 'F' => Some((Key::F, true)), 'f' => Some((Key::F, false)), 'G' => Some((Key::G, true)), 'g' => Some((Key::G, false)), 'H' => Some((Key::H, true)), 'h' => Some((Key::H, false)), 'I' => Some((Key::I, true)), 'i' => Some((Key::I, false)), 'J' => Some((Key::J, true)), 'j' => Some((Key::J, false)), 'K' => Some((Key::K, true)), 'k' => Some((Key::K, false)), 'L' => Some((Key::L, true)), 'l' => Some((Key::L, false)), 'M' => Some((Key::M, true)), 'm' => Some((Key::M, false)), 'N' => Some((Key::N, true)), 'n' => Some((Key::N, false)), 'O' => Some((Key::O, true)), 'o' => Some((Key::O, false)), 'P' => Some((Key::P, true)), 'p' => Some((Key::P, false)), 'Q' => Some((Key::Q, true)), 'q' => Some((Key::Q, false)), 'R' => Some((Key::R, true)), 'r' => Some((Key::R, false)), 'S' => Some((Key::S, true)), 's' => Some((Key::S, false)), 'T' => Some((Key::T, true)), 't' => Some((Key::T, false)), 'U' => Some((Key::U, true)), 'u' => Some((Key::U, false)), 'V' => Some((Key::V, true)), 'v' => Some((Key::V, false)), 'W' => Some((Key::W, true)), 'w' => Some((Key::W, false)), 'X' => Some((Key::X, true)), 'x' => Some((Key::X, false)), 'Y' => Some((Key::Y, true)), 'y' => Some((Key::Y, false)), 'Z' => Some((Key::Z, true)), 'z' => Some((Key::Z, false)), '{' => Some((Key::LeftBracket, true)), '[' => Some((Key::LeftBracket, false)), '|' => Some((Key::Backslash, true)), '\\' => Some((Key::Backslash, false)), '}' => Some((Key::RightBracket, true)), ']' => Some((Key::RightBracket, false)), '\u{E000}' => None, '\u{E001}' => None, '\u{E002}' => None, '\u{E003}' => Some((Key::Backspace, false)), '\u{E004}' => Some((Key::Tab, false)), '\u{E005}' => None, '\u{E006}' => Some((Key::Enter, false)), // This is supposed to be the Return key '\u{E007}' => Some((Key::Enter, false)), '\u{E008}' => Some((Key::LeftShift, false)), '\u{E009}' => Some((Key::LeftShift, false)), '\u{E00A}' => Some((Key::LeftAlt, false)), '\u{E00B}' => Some((Key::Pause, false)), '\u{E00C}' => Some((Key::Escape, false)), '\u{E00D}' => Some((Key::Space, false)), '\u{E00E}' => Some((Key::PageUp, false)), '\u{E00F}' => Some((Key::PageDown, false)), '\u{E010}' => Some((Key::End, false)), '\u{E011}' => Some((Key::Home, false)), '\u{E012}' => Some((Key::Right, false)), '\u{E013}' => Some((Key::Left, false)), '\u{E014}' => Some((Key::Down, false)), '\u{E015}' => Some((Key::Up, false)), '\u{E016}' => Some((Key::Insert, false)), '\u{E017}' => Some((Key::Delete, false)), '\u{E018}' => Some((Key::Semicolon, false)), '\u{E019}' => Some((Key::Equal, false)), '\u{E01A}' => Some((Key::Kp0, false)), '\u{E01B}' => Some((Key::Kp1, false)), '\u{E01C}' => Some((Key::Kp2, false)), '\u{E01D}' => Some((Key::Kp3, false)), '\u{E01E}' => Some((Key::Kp4, false)), '\u{E01F}' => Some((Key::Kp5, false)), '\u{E020}' => Some((Key::Kp6, false)), '\u{E021}' => Some((Key::Kp7, false)), '\u{E022}' => Some((Key::Kp8, false)), '\u{E023}' => Some((Key::Kp9, false)), '\u{E024}' => Some((Key::KpMultiply, false)), '\u{E025}' => Some((Key::KpAdd, false)), '\u{E026}' => Some((Key::KpEnter, false)), '\u{E027}' => Some((Key::KpSubtract, false)), '\u{E028}' => Some((Key::KpDecimal, false)), '\u{E029}' => Some((Key::KpDivide, false)), '\u{E031}' => Some((Key::F1, false)), '\u{E032}' => Some((Key::F2, false)), '\u{E033}' => Some((Key::F3, false)), '\u{E034}' => Some((Key::F4, false)), '\u{E035}' => Some((Key::F5, false)), '\u{E036}' => Some((Key::F6, false)), '\u{E037}' => Some((Key::F7, false)), '\u{E038}' => Some((Key::F8, false)), '\u{E039}' => Some((Key::F9, false)), '\u{E03A}' => Some((Key::F10, false)), '\u{E03B}' => Some((Key::F11, false)), '\u{E03C}' => Some((Key::F12, false)), '\u{E03D}' => None, '\u{E040}' => None, _ => None } } pub fn keycodes_to_keys(key_codes: &[char]) -> Result, String> { let mut rv = vec![]; for char_code in key_codes.iter() { let (key, with_shift) = key_from_char(char_code).ok_or(format!("Unsupported character code {}", char_code))?; let modifiers = if with_shift { SHIFT } else { KeyModifiers::empty() }; rv.push((key, modifiers, KeyState::Pressed)); rv.push((key, modifiers, KeyState::Released)); }; Ok(rv) }