mirror of
https://github.com/wez/wezterm.git
synced 2024-11-27 02:25:28 +03:00
send keyboard input to the pty
This commit is contained in:
parent
f879447d59
commit
1ae85b2349
@ -4,6 +4,7 @@ name = "wterm"
|
|||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
bitflags = "1.0.1"
|
||||||
failure = "0.1.1"
|
failure = "0.1.1"
|
||||||
freetype = "0.3.0"
|
freetype = "0.3.0"
|
||||||
harfbuzz-sys = "0.1.15"
|
harfbuzz-sys = "0.1.15"
|
||||||
@ -23,5 +24,6 @@ features = [
|
|||||||
"ewmh",
|
"ewmh",
|
||||||
"misc",
|
"misc",
|
||||||
"shm",
|
"shm",
|
||||||
|
"keysyms",
|
||||||
]
|
]
|
||||||
version = "0.2.0"
|
version = "0.2.0"
|
||||||
|
12
src/main.rs
12
src/main.rs
@ -1,5 +1,7 @@
|
|||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate failure;
|
extern crate failure;
|
||||||
|
#[macro_use]
|
||||||
|
extern crate bitflags;
|
||||||
extern crate unicode_width;
|
extern crate unicode_width;
|
||||||
extern crate unicode_segmentation;
|
extern crate unicode_segmentation;
|
||||||
extern crate harfbuzz_sys;
|
extern crate harfbuzz_sys;
|
||||||
@ -26,6 +28,7 @@ use std::process::Command;
|
|||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
mod xgfx;
|
mod xgfx;
|
||||||
|
mod xkeysyms;
|
||||||
mod font;
|
mod font;
|
||||||
use font::{Font, FontPattern, ftwrap};
|
use font::{Font, FontPattern, ftwrap};
|
||||||
|
|
||||||
@ -57,7 +60,11 @@ fn dispatch_gui(
|
|||||||
}
|
}
|
||||||
xcb::KEY_PRESS => {
|
xcb::KEY_PRESS => {
|
||||||
let key_press: &xcb::KeyPressEvent = unsafe { xcb::cast_event(&event) };
|
let key_press: &xcb::KeyPressEvent = unsafe { xcb::cast_event(&event) };
|
||||||
println!("Key '{}' pressed", key_press.detail());
|
window.key_down(key_press)?;
|
||||||
|
}
|
||||||
|
xcb::KEY_RELEASE => {
|
||||||
|
let key_press: &xcb::KeyPressEvent = unsafe { xcb::cast_event(&event) };
|
||||||
|
window.key_up(key_press)?;
|
||||||
}
|
}
|
||||||
xcb::CLIENT_MESSAGE => {
|
xcb::CLIENT_MESSAGE => {
|
||||||
let msg: &xcb::ClientMessageEvent = unsafe { xcb::cast_event(&event) };
|
let msg: &xcb::ClientMessageEvent = unsafe { xcb::cast_event(&event) };
|
||||||
@ -101,8 +108,7 @@ fn run() -> Result<(), Error> {
|
|||||||
initial_pixel_height,
|
initial_pixel_height,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
let mut cmd = Command::new("top");
|
let cmd = Command::new("zsh");
|
||||||
// cmd.arg("-l");
|
|
||||||
let child = slave.spawn_command(cmd)?;
|
let child = slave.spawn_command(cmd)?;
|
||||||
eprintln!("spawned: {:?}", child);
|
eprintln!("spawned: {:?}", child);
|
||||||
|
|
||||||
|
@ -1,11 +1,35 @@
|
|||||||
//! Terminal model
|
//! Terminal model
|
||||||
|
|
||||||
|
use failure::Error;
|
||||||
use std;
|
use std;
|
||||||
use unicode_segmentation;
|
use unicode_segmentation;
|
||||||
use vte;
|
use vte;
|
||||||
|
|
||||||
pub mod color;
|
pub mod color;
|
||||||
|
|
||||||
|
bitflags! {
|
||||||
|
#[derive(Default)]
|
||||||
|
pub struct KeyModifiers :u8{
|
||||||
|
const CTRL = 1;
|
||||||
|
const ALT = 2;
|
||||||
|
const META = 4;
|
||||||
|
const SUPER = 8;
|
||||||
|
const SHIFT = 16;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
||||||
|
pub enum KeyCode {
|
||||||
|
Char(char),
|
||||||
|
Unknown,
|
||||||
|
Control,
|
||||||
|
Alt,
|
||||||
|
Meta,
|
||||||
|
Super,
|
||||||
|
Hyper,
|
||||||
|
Shift,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
pub struct CellAttributes {
|
pub struct CellAttributes {
|
||||||
attributes: u16,
|
attributes: u16,
|
||||||
@ -328,6 +352,48 @@ impl TerminalState {
|
|||||||
&mut self.screen
|
&mut self.screen
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn key_down<W: std::io::Write>(
|
||||||
|
&mut self,
|
||||||
|
key: KeyCode,
|
||||||
|
mods: KeyModifiers,
|
||||||
|
write: &mut W,
|
||||||
|
) -> Result<(), Error> {
|
||||||
|
match key {
|
||||||
|
KeyCode::Char(c) => {
|
||||||
|
let adjusted = if mods.contains(KeyModifiers::CTRL) && c <= 0xff as char {
|
||||||
|
if mods.contains(KeyModifiers::SHIFT) {
|
||||||
|
// If shift is held we have C == 0x43 and want to translate
|
||||||
|
// that into 0x03
|
||||||
|
(c as u8 - 0x40) as char
|
||||||
|
} else {
|
||||||
|
// If shift is not held we have c == 0x63 and want to translate
|
||||||
|
// that into 0x03
|
||||||
|
(c as u8 - 0x60) as char
|
||||||
|
}
|
||||||
|
} else if mods.contains(KeyModifiers::ALT) && c <= 0xff as char {
|
||||||
|
(c as u8 | 0x80) as char
|
||||||
|
} else {
|
||||||
|
c
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut buf = [0; 8];
|
||||||
|
let encoded = adjusted.encode_utf8(&mut buf);
|
||||||
|
write.write(encoded.as_bytes())?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
_ => Ok(()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn key_up<W: std::io::Write>(
|
||||||
|
&mut self,
|
||||||
|
key: KeyCode,
|
||||||
|
mods: KeyModifiers,
|
||||||
|
write: &mut W,
|
||||||
|
) -> Result<(), Error> {
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Terminal {
|
pub struct Terminal {
|
||||||
@ -390,6 +456,24 @@ impl Terminal {
|
|||||||
let len = screen.lines.len();
|
let len = screen.lines.len();
|
||||||
(width, &screen.lines[len - height..len])
|
(width, &screen.lines[len - height..len])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn key_down<W: std::io::Write>(
|
||||||
|
&mut self,
|
||||||
|
key: KeyCode,
|
||||||
|
mods: KeyModifiers,
|
||||||
|
write: &mut W,
|
||||||
|
) -> Result<(), Error> {
|
||||||
|
self.state.key_down(key, mods, write)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn key_up<W: std::io::Write>(
|
||||||
|
&mut self,
|
||||||
|
key: KeyCode,
|
||||||
|
mods: KeyModifiers,
|
||||||
|
write: &mut W,
|
||||||
|
) -> Result<(), Error> {
|
||||||
|
self.state.key_up(key, mods, write)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
31
src/xgfx.rs
31
src/xgfx.rs
@ -4,9 +4,12 @@ use std::ops::Deref;
|
|||||||
use std::result;
|
use std::result;
|
||||||
use xcb;
|
use xcb;
|
||||||
use xcb_util;
|
use xcb_util;
|
||||||
|
use xcb_util::ffi::keysyms::{xcb_key_press_lookup_keysym, xcb_key_symbols_alloc,
|
||||||
|
xcb_key_symbols_free, xcb_key_symbols_t};
|
||||||
|
|
||||||
use failure::{self, Error};
|
use failure::{self, Error};
|
||||||
pub type Result<T> = result::Result<T, Error>;
|
pub type Result<T> = result::Result<T, Error>;
|
||||||
|
pub use xkeysyms::*;
|
||||||
|
|
||||||
use super::term::color::RgbColor;
|
use super::term::color::RgbColor;
|
||||||
|
|
||||||
@ -15,6 +18,7 @@ pub struct Connection {
|
|||||||
screen_num: i32,
|
screen_num: i32,
|
||||||
atom_protocols: xcb::Atom,
|
atom_protocols: xcb::Atom,
|
||||||
atom_delete: xcb::Atom,
|
atom_delete: xcb::Atom,
|
||||||
|
keysyms: *mut xcb_key_symbols_t,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Deref for Connection {
|
impl Deref for Connection {
|
||||||
@ -35,11 +39,14 @@ impl Connection {
|
|||||||
.get_reply()?
|
.get_reply()?
|
||||||
.atom();
|
.atom();
|
||||||
|
|
||||||
|
let keysyms = unsafe { xcb_key_symbols_alloc(conn.get_raw_conn()) };
|
||||||
|
|
||||||
Ok(Connection {
|
Ok(Connection {
|
||||||
conn,
|
conn,
|
||||||
screen_num,
|
screen_num,
|
||||||
atom_protocols,
|
atom_protocols,
|
||||||
atom_delete,
|
atom_delete,
|
||||||
|
keysyms,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -54,6 +61,26 @@ impl Connection {
|
|||||||
pub fn atom_delete(&self) -> xcb::Atom {
|
pub fn atom_delete(&self) -> xcb::Atom {
|
||||||
self.atom_delete
|
self.atom_delete
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn lookup_keysym(&self, event: &xcb::KeyPressEvent, shifted: bool) -> xcb::Keysym {
|
||||||
|
unsafe {
|
||||||
|
let sym =
|
||||||
|
xcb_key_press_lookup_keysym(self.keysyms, event.ptr, if shifted { 1 } else { 0 });
|
||||||
|
if sym == 0 && shifted {
|
||||||
|
xcb_key_press_lookup_keysym(self.keysyms, event.ptr, 0)
|
||||||
|
} else {
|
||||||
|
sym
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Drop for Connection {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
unsafe {
|
||||||
|
xcb_key_symbols_free(self.keysyms);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The X protocol allows referencing a number of drawable
|
/// The X protocol allows referencing a number of drawable
|
||||||
@ -105,7 +132,9 @@ impl<'a> Window<'a> {
|
|||||||
&[
|
&[
|
||||||
(
|
(
|
||||||
xcb::CW_EVENT_MASK,
|
xcb::CW_EVENT_MASK,
|
||||||
xcb::EVENT_MASK_EXPOSURE | xcb::EVENT_MASK_KEY_PRESS | xcb::EVENT_MASK_STRUCTURE_NOTIFY,
|
xcb::EVENT_MASK_EXPOSURE | xcb::EVENT_MASK_KEY_PRESS |
|
||||||
|
xcb::EVENT_MASK_KEY_RELEASE |
|
||||||
|
xcb::EVENT_MASK_STRUCTURE_NOTIFY,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
).request_check()?;
|
).request_check()?;
|
||||||
|
239
src/xkeysyms.rs
Normal file
239
src/xkeysyms.rs
Normal file
@ -0,0 +1,239 @@
|
|||||||
|
#![allow(non_upper_case_globals, dead_code)]
|
||||||
|
use xcb::KeyPressEvent;
|
||||||
|
use xcb::ffi::xproto::xcb_keysym_t;
|
||||||
|
|
||||||
|
pub const XK_VoidSymbol: xcb_keysym_t = 0xffffff;
|
||||||
|
pub const XK_BackSpace: xcb_keysym_t = 0xff08;
|
||||||
|
pub const XK_Tab: xcb_keysym_t = 0xff09;
|
||||||
|
pub const XK_Linefeed: xcb_keysym_t = 0xff0a;
|
||||||
|
pub const XK_Clear: xcb_keysym_t = 0xff0b;
|
||||||
|
pub const XK_Return: xcb_keysym_t = 0xff0d;
|
||||||
|
pub const XK_Pause: xcb_keysym_t = 0xff13;
|
||||||
|
pub const XK_Scroll_Lock: xcb_keysym_t = 0xff14;
|
||||||
|
pub const XK_Sys_Req: xcb_keysym_t = 0xff15;
|
||||||
|
pub const XK_Escape: xcb_keysym_t = 0xff1b;
|
||||||
|
pub const XK_Delete: xcb_keysym_t = 0xffff;
|
||||||
|
|
||||||
|
pub const XK_Home: xcb_keysym_t = 0xff50;
|
||||||
|
pub const XK_Left: xcb_keysym_t = 0xff51;
|
||||||
|
pub const XK_Up: xcb_keysym_t = 0xff52;
|
||||||
|
pub const XK_Right: xcb_keysym_t = 0xff53;
|
||||||
|
pub const XK_Down: xcb_keysym_t = 0xff54;
|
||||||
|
pub const XK_Prior: xcb_keysym_t = 0xff55;
|
||||||
|
pub const XK_Page_Up: xcb_keysym_t = 0xff55;
|
||||||
|
pub const XK_Next: xcb_keysym_t = 0xff56;
|
||||||
|
pub const XK_Page_Down: xcb_keysym_t = 0xff56;
|
||||||
|
pub const XK_End: xcb_keysym_t = 0xff57;
|
||||||
|
pub const XK_Begin: xcb_keysym_t = 0xff58;
|
||||||
|
|
||||||
|
pub const XK_KP_Space: xcb_keysym_t = 0xff80;
|
||||||
|
pub const XK_KP_Tab: xcb_keysym_t = 0xff89;
|
||||||
|
pub const XK_KP_Enter: xcb_keysym_t = 0xff8d;
|
||||||
|
pub const XK_KP_F1: xcb_keysym_t = 0xff91;
|
||||||
|
pub const XK_KP_F2: xcb_keysym_t = 0xff92;
|
||||||
|
pub const XK_KP_F3: xcb_keysym_t = 0xff93;
|
||||||
|
pub const XK_KP_F4: xcb_keysym_t = 0xff94;
|
||||||
|
pub const XK_KP_Home: xcb_keysym_t = 0xff95;
|
||||||
|
pub const XK_KP_Left: xcb_keysym_t = 0xff96;
|
||||||
|
pub const XK_KP_Up: xcb_keysym_t = 0xff97;
|
||||||
|
pub const XK_KP_Right: xcb_keysym_t = 0xff98;
|
||||||
|
pub const XK_KP_Down: xcb_keysym_t = 0xff99;
|
||||||
|
pub const XK_KP_Prior: xcb_keysym_t = 0xff9a;
|
||||||
|
pub const XK_KP_Page_Up: xcb_keysym_t = 0xff9a;
|
||||||
|
pub const XK_KP_Next: xcb_keysym_t = 0xff9b;
|
||||||
|
pub const XK_KP_Page_Down: xcb_keysym_t = 0xff9b;
|
||||||
|
pub const XK_KP_End: xcb_keysym_t = 0xff9c;
|
||||||
|
pub const XK_KP_Begin: xcb_keysym_t = 0xff9d;
|
||||||
|
pub const XK_KP_Insert: xcb_keysym_t = 0xff9e;
|
||||||
|
pub const XK_KP_Delete: xcb_keysym_t = 0xff9f;
|
||||||
|
pub const XK_KP_Equal: xcb_keysym_t = 0xffbd;
|
||||||
|
pub const XK_KP_Multiply: xcb_keysym_t = 0xffaa;
|
||||||
|
pub const XK_KP_Add: xcb_keysym_t = 0xffab;
|
||||||
|
pub const XK_KP_Separator: xcb_keysym_t = 0xffac;
|
||||||
|
pub const XK_KP_Subtract: xcb_keysym_t = 0xffad;
|
||||||
|
pub const XK_KP_Decimal: xcb_keysym_t = 0xffae;
|
||||||
|
pub const XK_KP_Divide: xcb_keysym_t = 0xffaf;
|
||||||
|
|
||||||
|
pub const XK_KP_0: xcb_keysym_t = 0xffb0;
|
||||||
|
pub const XK_KP_1: xcb_keysym_t = 0xffb1;
|
||||||
|
pub const XK_KP_2: xcb_keysym_t = 0xffb2;
|
||||||
|
pub const XK_KP_3: xcb_keysym_t = 0xffb3;
|
||||||
|
pub const XK_KP_4: xcb_keysym_t = 0xffb4;
|
||||||
|
pub const XK_KP_5: xcb_keysym_t = 0xffb5;
|
||||||
|
pub const XK_KP_6: xcb_keysym_t = 0xffb6;
|
||||||
|
pub const XK_KP_7: xcb_keysym_t = 0xffb7;
|
||||||
|
pub const XK_KP_8: xcb_keysym_t = 0xffb8;
|
||||||
|
pub const XK_KP_9: xcb_keysym_t = 0xffb9;
|
||||||
|
|
||||||
|
pub const XK_F1: xcb_keysym_t = 0xffbe;
|
||||||
|
pub const XK_F2: xcb_keysym_t = 0xffbf;
|
||||||
|
pub const XK_F3: xcb_keysym_t = 0xffc0;
|
||||||
|
pub const XK_F4: xcb_keysym_t = 0xffc1;
|
||||||
|
pub const XK_F5: xcb_keysym_t = 0xffc2;
|
||||||
|
pub const XK_F6: xcb_keysym_t = 0xffc3;
|
||||||
|
pub const XK_F7: xcb_keysym_t = 0xffc4;
|
||||||
|
pub const XK_F8: xcb_keysym_t = 0xffc5;
|
||||||
|
pub const XK_F9: xcb_keysym_t = 0xffc6;
|
||||||
|
pub const XK_F10: xcb_keysym_t = 0xffc7;
|
||||||
|
pub const XK_F11: xcb_keysym_t = 0xffc8;
|
||||||
|
pub const XK_F12: xcb_keysym_t = 0xffc9;
|
||||||
|
|
||||||
|
pub const XK_Shift_L: xcb_keysym_t = 0xffe1;
|
||||||
|
pub const XK_Shift_R: xcb_keysym_t = 0xffe2;
|
||||||
|
pub const XK_Control_L: xcb_keysym_t = 0xffe3;
|
||||||
|
pub const XK_Control_R: xcb_keysym_t = 0xffe4;
|
||||||
|
pub const XK_Caps_Lock: xcb_keysym_t = 0xffe5;
|
||||||
|
pub const XK_Shift_Lock: xcb_keysym_t = 0xffe6;
|
||||||
|
|
||||||
|
pub const XK_Meta_L: xcb_keysym_t = 0xffe7;
|
||||||
|
pub const XK_Meta_R: xcb_keysym_t = 0xffe8;
|
||||||
|
pub const XK_Alt_L: xcb_keysym_t = 0xffe9;
|
||||||
|
pub const XK_Alt_R: xcb_keysym_t = 0xffea;
|
||||||
|
pub const XK_Super_L: xcb_keysym_t = 0xffeb;
|
||||||
|
pub const XK_Super_R: xcb_keysym_t = 0xffec;
|
||||||
|
pub const XK_Hyper_L: xcb_keysym_t = 0xffed;
|
||||||
|
pub const XK_Hyper_R: xcb_keysym_t = 0xffee;
|
||||||
|
|
||||||
|
pub const XK_space: xcb_keysym_t = 0x0020;
|
||||||
|
pub const XK_exclam: xcb_keysym_t = 0x0021;
|
||||||
|
pub const XK_quotedbl: xcb_keysym_t = 0x0022;
|
||||||
|
pub const XK_numbersign: xcb_keysym_t = 0x0023;
|
||||||
|
pub const XK_dollar: xcb_keysym_t = 0x0024;
|
||||||
|
pub const XK_percent: xcb_keysym_t = 0x0025;
|
||||||
|
pub const XK_ampersand: xcb_keysym_t = 0x0026;
|
||||||
|
pub const XK_apostrophe: xcb_keysym_t = 0x0027;
|
||||||
|
pub const XK_quoteright: xcb_keysym_t = 0x0027;
|
||||||
|
pub const XK_parenleft: xcb_keysym_t = 0x0028;
|
||||||
|
pub const XK_parenright: xcb_keysym_t = 0x0029;
|
||||||
|
pub const XK_asterisk: xcb_keysym_t = 0x002a;
|
||||||
|
pub const XK_plus: xcb_keysym_t = 0x002b;
|
||||||
|
pub const XK_comma: xcb_keysym_t = 0x002c;
|
||||||
|
pub const XK_minus: xcb_keysym_t = 0x002d;
|
||||||
|
pub const XK_period: xcb_keysym_t = 0x002e;
|
||||||
|
pub const XK_slash: xcb_keysym_t = 0x002f;
|
||||||
|
pub const XK_0: xcb_keysym_t = 0x0030;
|
||||||
|
pub const XK_1: xcb_keysym_t = 0x0031;
|
||||||
|
pub const XK_2: xcb_keysym_t = 0x0032;
|
||||||
|
pub const XK_3: xcb_keysym_t = 0x0033;
|
||||||
|
pub const XK_4: xcb_keysym_t = 0x0034;
|
||||||
|
pub const XK_5: xcb_keysym_t = 0x0035;
|
||||||
|
pub const XK_6: xcb_keysym_t = 0x0036;
|
||||||
|
pub const XK_7: xcb_keysym_t = 0x0037;
|
||||||
|
pub const XK_8: xcb_keysym_t = 0x0038;
|
||||||
|
pub const XK_9: xcb_keysym_t = 0x0039;
|
||||||
|
pub const XK_colon: xcb_keysym_t = 0x003a;
|
||||||
|
pub const XK_semicolon: xcb_keysym_t = 0x003b;
|
||||||
|
pub const XK_less: xcb_keysym_t = 0x003c;
|
||||||
|
pub const XK_equal: xcb_keysym_t = 0x003d;
|
||||||
|
pub const XK_greater: xcb_keysym_t = 0x003e;
|
||||||
|
pub const XK_question: xcb_keysym_t = 0x003f;
|
||||||
|
pub const XK_at: xcb_keysym_t = 0x0040;
|
||||||
|
pub const XK_A: xcb_keysym_t = 0x0041;
|
||||||
|
pub const XK_B: xcb_keysym_t = 0x0042;
|
||||||
|
pub const XK_C: xcb_keysym_t = 0x0043;
|
||||||
|
pub const XK_D: xcb_keysym_t = 0x0044;
|
||||||
|
pub const XK_E: xcb_keysym_t = 0x0045;
|
||||||
|
pub const XK_F: xcb_keysym_t = 0x0046;
|
||||||
|
pub const XK_G: xcb_keysym_t = 0x0047;
|
||||||
|
pub const XK_H: xcb_keysym_t = 0x0048;
|
||||||
|
pub const XK_I: xcb_keysym_t = 0x0049;
|
||||||
|
pub const XK_J: xcb_keysym_t = 0x004a;
|
||||||
|
pub const XK_K: xcb_keysym_t = 0x004b;
|
||||||
|
pub const XK_L: xcb_keysym_t = 0x004c;
|
||||||
|
pub const XK_M: xcb_keysym_t = 0x004d;
|
||||||
|
pub const XK_N: xcb_keysym_t = 0x004e;
|
||||||
|
pub const XK_O: xcb_keysym_t = 0x004f;
|
||||||
|
pub const XK_P: xcb_keysym_t = 0x0050;
|
||||||
|
pub const XK_Q: xcb_keysym_t = 0x0051;
|
||||||
|
pub const XK_R: xcb_keysym_t = 0x0052;
|
||||||
|
pub const XK_S: xcb_keysym_t = 0x0053;
|
||||||
|
pub const XK_T: xcb_keysym_t = 0x0054;
|
||||||
|
pub const XK_U: xcb_keysym_t = 0x0055;
|
||||||
|
pub const XK_V: xcb_keysym_t = 0x0056;
|
||||||
|
pub const XK_W: xcb_keysym_t = 0x0057;
|
||||||
|
pub const XK_X: xcb_keysym_t = 0x0058;
|
||||||
|
pub const XK_Y: xcb_keysym_t = 0x0059;
|
||||||
|
pub const XK_Z: xcb_keysym_t = 0x005a;
|
||||||
|
pub const XK_bracketleft: xcb_keysym_t = 0x005b;
|
||||||
|
pub const XK_backslash: xcb_keysym_t = 0x005c;
|
||||||
|
pub const XK_bracketright: xcb_keysym_t = 0x005d;
|
||||||
|
pub const XK_asciicircum: xcb_keysym_t = 0x005e;
|
||||||
|
pub const XK_underscore: xcb_keysym_t = 0x005f;
|
||||||
|
pub const XK_grave: xcb_keysym_t = 0x0060;
|
||||||
|
pub const XK_quoteleft: xcb_keysym_t = 0x0060;
|
||||||
|
pub const XK_a: xcb_keysym_t = 0x0061;
|
||||||
|
pub const XK_b: xcb_keysym_t = 0x0062;
|
||||||
|
pub const XK_c: xcb_keysym_t = 0x0063;
|
||||||
|
pub const XK_d: xcb_keysym_t = 0x0064;
|
||||||
|
pub const XK_e: xcb_keysym_t = 0x0065;
|
||||||
|
pub const XK_f: xcb_keysym_t = 0x0066;
|
||||||
|
pub const XK_g: xcb_keysym_t = 0x0067;
|
||||||
|
pub const XK_h: xcb_keysym_t = 0x0068;
|
||||||
|
pub const XK_i: xcb_keysym_t = 0x0069;
|
||||||
|
pub const XK_j: xcb_keysym_t = 0x006a;
|
||||||
|
pub const XK_k: xcb_keysym_t = 0x006b;
|
||||||
|
pub const XK_l: xcb_keysym_t = 0x006c;
|
||||||
|
pub const XK_m: xcb_keysym_t = 0x006d;
|
||||||
|
pub const XK_n: xcb_keysym_t = 0x006e;
|
||||||
|
pub const XK_o: xcb_keysym_t = 0x006f;
|
||||||
|
pub const XK_p: xcb_keysym_t = 0x0070;
|
||||||
|
pub const XK_q: xcb_keysym_t = 0x0071;
|
||||||
|
pub const XK_r: xcb_keysym_t = 0x0072;
|
||||||
|
pub const XK_s: xcb_keysym_t = 0x0073;
|
||||||
|
pub const XK_t: xcb_keysym_t = 0x0074;
|
||||||
|
pub const XK_u: xcb_keysym_t = 0x0075;
|
||||||
|
pub const XK_v: xcb_keysym_t = 0x0076;
|
||||||
|
pub const XK_w: xcb_keysym_t = 0x0077;
|
||||||
|
pub const XK_x: xcb_keysym_t = 0x0078;
|
||||||
|
pub const XK_y: xcb_keysym_t = 0x0079;
|
||||||
|
pub const XK_z: xcb_keysym_t = 0x007a;
|
||||||
|
pub const XK_braceleft: xcb_keysym_t = 0x007b;
|
||||||
|
pub const XK_bar: xcb_keysym_t = 0x007c;
|
||||||
|
pub const XK_braceright: xcb_keysym_t = 0x007d;
|
||||||
|
pub const XK_asciitilde: xcb_keysym_t = 0x007e;
|
||||||
|
|
||||||
|
use term::KeyCode;
|
||||||
|
use term::KeyModifiers;
|
||||||
|
|
||||||
|
impl From<xcb_keysym_t> for KeyCode {
|
||||||
|
fn from(k: xcb_keysym_t) -> Self {
|
||||||
|
match k {
|
||||||
|
XK_space...XK_asciitilde => {
|
||||||
|
// This range overlaps with ascii
|
||||||
|
KeyCode::Char(k as u8 as char)
|
||||||
|
}
|
||||||
|
XK_BackSpace | XK_Tab | XK_Linefeed | XK_Return | XK_Escape => {
|
||||||
|
KeyCode::Char((k & 0xff) as u8 as char)
|
||||||
|
}
|
||||||
|
XK_Control_L | XK_Control_R => KeyCode::Control,
|
||||||
|
XK_Alt_L | XK_Alt_R => KeyCode::Alt,
|
||||||
|
XK_Meta_L | XK_Meta_R => KeyCode::Meta,
|
||||||
|
XK_Super_L | XK_Super_R => KeyCode::Super,
|
||||||
|
XK_Hyper_L | XK_Hyper_R => KeyCode::Hyper,
|
||||||
|
XK_Shift_L | XK_Shift_R => KeyCode::Shift,
|
||||||
|
_ => KeyCode::Unknown,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn modifiers(event: &KeyPressEvent) -> KeyModifiers {
|
||||||
|
use xcb::xproto::*;
|
||||||
|
|
||||||
|
let mut mods = KeyModifiers::default();
|
||||||
|
let state = event.state() as u32;
|
||||||
|
|
||||||
|
if state & MOD_MASK_SHIFT != 0 {
|
||||||
|
mods |= KeyModifiers::SHIFT;
|
||||||
|
}
|
||||||
|
if state & MOD_MASK_CONTROL != 0 {
|
||||||
|
mods |= KeyModifiers::CTRL;
|
||||||
|
}
|
||||||
|
if state & MOD_MASK_1 != 0 {
|
||||||
|
mods |= KeyModifiers::ALT;
|
||||||
|
}
|
||||||
|
if state & MOD_MASK_4 != 0 {
|
||||||
|
mods |= KeyModifiers::SUPER;
|
||||||
|
}
|
||||||
|
|
||||||
|
mods
|
||||||
|
}
|
25
src/xwin.rs
25
src/xwin.rs
@ -5,8 +5,10 @@ use std::io::Read;
|
|||||||
use std::mem;
|
use std::mem;
|
||||||
use std::process::Child;
|
use std::process::Child;
|
||||||
use std::slice;
|
use std::slice;
|
||||||
use term;
|
use term::{self, KeyCode, KeyModifiers};
|
||||||
|
use xcb;
|
||||||
use xgfx::{self, Connection, Drawable};
|
use xgfx::{self, Connection, Drawable};
|
||||||
|
use xkeysyms;
|
||||||
|
|
||||||
pub struct TerminalWindow<'a> {
|
pub struct TerminalWindow<'a> {
|
||||||
window: xgfx::Window<'a>,
|
window: xgfx::Window<'a>,
|
||||||
@ -324,4 +326,25 @@ impl<'a> TerminalWindow<'a> {
|
|||||||
pub fn need_paint(&self) -> bool {
|
pub fn need_paint(&self) -> bool {
|
||||||
self.need_paint
|
self.need_paint
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn decode_key(&self, event: &xcb::KeyPressEvent) -> (KeyCode, KeyModifiers) {
|
||||||
|
let mods = xkeysyms::modifiers(event);
|
||||||
|
let sym = self.conn.lookup_keysym(
|
||||||
|
event,
|
||||||
|
mods.contains(KeyModifiers::SHIFT),
|
||||||
|
);
|
||||||
|
(sym.into(), mods)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn key_down(&mut self, event: &xcb::KeyPressEvent) -> Result<(), Error> {
|
||||||
|
let (code, mods) = self.decode_key(event);
|
||||||
|
println!("Key pressed {:?} {:?}", code, mods);
|
||||||
|
self.terminal.key_down(code, mods, &mut self.pty)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn key_up(&mut self, event: &xcb::KeyPressEvent) -> Result<(), Error> {
|
||||||
|
let (code, mods) = self.decode_key(event);
|
||||||
|
println!("Key released {:?} {:?}", code, mods);
|
||||||
|
self.terminal.key_up(code, mods, &mut self.pty)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user