167 lines
4.8 KiB
Rust
167 lines
4.8 KiB
Rust
|
use x11::xlib::{self, XKeyEvent};
|
||
|
|
||
|
use anyhow::Result;
|
||
|
|
||
|
use super::{display, window, key, error};
|
||
|
|
||
|
pub type Vec2<T> = (T, T);
|
||
|
|
||
|
pub enum Event {
|
||
|
// only for now relevant event types
|
||
|
KeyPressEvent(KeyEvent),
|
||
|
KeyReleaseEvent(KeyEvent),
|
||
|
ButtonPressEvent(ButtonEvent),
|
||
|
ButtonReleaseEvent(ButtonEvent),
|
||
|
MotionEvent(MotionEvent),
|
||
|
|
||
|
ErrorEvent(ErrorEvent),
|
||
|
CrossingEvent(CrossingEvent),
|
||
|
FocusChangeEvent(FocusChangeEvent),
|
||
|
ExposeEvent(ExposeEvent),
|
||
|
GraphicsExposeEvent(GraphicsExposeEvent),
|
||
|
NoExposeEvent(NoExposeEvent),
|
||
|
VisibilityEvent(VisibilityEvent),
|
||
|
CreateWindowEvent(CreateWindowEvent),
|
||
|
DestroyWindowEvent(DestroyWindowEvent),
|
||
|
UnmapEvent(UnmapEvent),
|
||
|
MapEvent(MapEvent),
|
||
|
MapRequestEvent(MapRequestEvent),
|
||
|
ReparentEvent(ReparentEvent),
|
||
|
ConfigureEvent(ConfigureEvent),
|
||
|
GravityEvent(GravityEvent),
|
||
|
ResizeRequestEvent(ResizeRequestEvent),
|
||
|
ConfigureRequestEvent(ConfigureRequestEvent),
|
||
|
CirculateEvent(CirculateEvent),
|
||
|
CirculateRequestEvent(CirculateRequestEvent),
|
||
|
PropertyEvent(PropertyEvent),
|
||
|
SelectionClearEvent(SelectionClearEvent),
|
||
|
SelectionRequestEvent(SelectionRequestEvent),
|
||
|
SelectionEvent(SelectionEvent),
|
||
|
ColormapEvent(ColormapEvent),
|
||
|
ClientMessageEvent(ClientMessageEvent),
|
||
|
MappingEvent(MappingEvent),
|
||
|
KeymapEvent(KeymapEvent),
|
||
|
}
|
||
|
|
||
|
impl TryFrom<xlib::XEvent> for Event {
|
||
|
type Error = error::XError;
|
||
|
fn try_from(ev_union: xlib::XEvent) -> Result<Self, Self::Error> {
|
||
|
match ev_union.get_type() {
|
||
|
xlib::KeyPress => ,
|
||
|
xlib::KeyRelease => ,
|
||
|
xlib::ButtonPress => ,
|
||
|
xlib::ButtonRelease => ,
|
||
|
xlib::MotionNotify => ,
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
struct GenericEventData {
|
||
|
serial_nr: u64,
|
||
|
sent_by_different_client: bool,
|
||
|
source_display_ptr: *mut xlib::_XDisplay,
|
||
|
window: window::Window,
|
||
|
}
|
||
|
|
||
|
pub enum SwitchState {
|
||
|
Pressed,
|
||
|
Released
|
||
|
}
|
||
|
|
||
|
pub struct KeyEvent {
|
||
|
generic: GenericEventData,
|
||
|
root: window::Window,
|
||
|
subwindow: window::Window,
|
||
|
time: xlib::Time,
|
||
|
pointer_pos: Vec2<i32>,
|
||
|
pointer_pos_root: Vec2<i32>,
|
||
|
state: SwitchState,
|
||
|
key: key::Key,
|
||
|
same_screen: bool
|
||
|
}
|
||
|
|
||
|
impl TryFrom<xlib::XEvent> for KeyEvent {
|
||
|
type Error = error::XError;
|
||
|
fn try_from(raw_ev: xlib::XEvent) -> Result<Self, Self::Error> {
|
||
|
let state = match raw_ev.get_type() {
|
||
|
xlib::KeyPress => SwitchState::Pressed,
|
||
|
xlib::KeyRelease => SwitchState::Released,
|
||
|
ev_type => return Err(error::XError::XEventConversionError { event_type: ev_type })
|
||
|
};
|
||
|
|
||
|
let raw_ev = XKeyEvent::from(raw_ev);
|
||
|
|
||
|
Ok(Self {
|
||
|
generic: GenericEventData {
|
||
|
serial_nr: raw_ev.serial,
|
||
|
sent_by_different_client: raw_ev.send_event != 0,
|
||
|
// make conversion method for display from ptr that maybe should try to check???
|
||
|
// how would i even do this safely
|
||
|
source_display_ptr: raw_ev.display,
|
||
|
window: window::Window { wid: raw_ev.window },
|
||
|
},
|
||
|
root: window::Window { wid: raw_ev.root },
|
||
|
subwindow: window::Window { wid: raw_ev.subwindow } ,
|
||
|
time: raw_ev.time,
|
||
|
pointer_pos: (raw_ev.x, raw_ev.y),
|
||
|
pointer_pos_root: (raw_ev.x_root, raw_ev.y_root),
|
||
|
state: raw_ev.state,
|
||
|
key: key::Key { code: raw_ev.keycode },
|
||
|
same_screen: raw_ev.same_screen != 0
|
||
|
})
|
||
|
}
|
||
|
}
|
||
|
|
||
|
pub struct ButtonEvent {
|
||
|
generic: GenericEventData,
|
||
|
root: window::Window,
|
||
|
time: xlib::Time,
|
||
|
pointer_pos: Vec2<i32>,
|
||
|
pointer_pos_root: Vec2<i32>,
|
||
|
button: u32,
|
||
|
state: SwitchState,
|
||
|
same_screen: bool
|
||
|
}
|
||
|
|
||
|
// change fields and data for this and other events according to xlib doc p. 188-189
|
||
|
pub struct MotionEvent {
|
||
|
generic: GenericEventData,
|
||
|
root: window::Window,
|
||
|
subwindow: window::Window,
|
||
|
time: xlib::Time,
|
||
|
pointer_pos: Vec2<i32>,
|
||
|
pointer_pos_root: Vec2<i32>,
|
||
|
state: u32,
|
||
|
is_hint: u32,
|
||
|
same_screen: bool,
|
||
|
}
|
||
|
|
||
|
// TODO: make these into cool event stuff too
|
||
|
pub struct ErrorEvent {}
|
||
|
pub struct CrossingEvent {}
|
||
|
pub struct FocusChangeEvent {}
|
||
|
pub struct ExposeEvent {}
|
||
|
pub struct GraphicsExposeEvent {}
|
||
|
pub struct NoExposeEvent {}
|
||
|
pub struct VisibilityEvent {}
|
||
|
pub struct CreateWindowEvent {}
|
||
|
pub struct DestroyWindowEvent {}
|
||
|
pub struct UnmapEvent {}
|
||
|
pub struct MapEvent {}
|
||
|
pub struct MapRequestEvent {}
|
||
|
pub struct ReparentEvent {}
|
||
|
pub struct ConfigureEvent {}
|
||
|
pub struct GravityEvent {}
|
||
|
pub struct ResizeRequestEvent {}
|
||
|
pub struct ConfigureRequestEvent {}
|
||
|
pub struct CirculateEvent {}
|
||
|
pub struct CirculateRequestEvent {}
|
||
|
pub struct PropertyEvent {}
|
||
|
pub struct SelectionClearEvent {}
|
||
|
pub struct SelectionRequestEvent {}
|
||
|
pub struct SelectionEvent {}
|
||
|
pub struct ColormapEvent {}
|
||
|
pub struct ClientMessageEvent {}
|
||
|
pub struct MappingEvent {}
|
||
|
pub struct KeymapEvent {}
|