Merge branch 'input_improvements' into 'master'
Couple of graphics and input subsystem refactorings See merge request redox-os/drivers!216
This commit is contained in:
Generated
+5
@@ -190,6 +190,7 @@ name = "bgad"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"common",
|
||||
"inputd",
|
||||
"libredox",
|
||||
"orbclient",
|
||||
"pcid",
|
||||
@@ -423,6 +424,7 @@ dependencies = [
|
||||
"orbclient",
|
||||
"ransid",
|
||||
"redox-daemon",
|
||||
"redox-scheme",
|
||||
"redox_event",
|
||||
"redox_syscall",
|
||||
]
|
||||
@@ -1035,10 +1037,12 @@ version = "0.1.0"
|
||||
dependencies = [
|
||||
"bitflags 1.3.2",
|
||||
"common",
|
||||
"inputd",
|
||||
"libredox",
|
||||
"log",
|
||||
"orbclient",
|
||||
"redox-daemon",
|
||||
"redox_event",
|
||||
"redox_syscall",
|
||||
]
|
||||
|
||||
@@ -1593,6 +1597,7 @@ version = "0.1.0"
|
||||
dependencies = [
|
||||
"bitflags 2.6.0",
|
||||
"common",
|
||||
"inputd",
|
||||
"log",
|
||||
"orbclient",
|
||||
"redox_syscall",
|
||||
|
||||
+3
-2
@@ -4,12 +4,10 @@ members = [
|
||||
"common",
|
||||
"hwd",
|
||||
"pcid",
|
||||
"ps2d",
|
||||
"vboxd",
|
||||
"xhcid",
|
||||
"usbctl",
|
||||
"usbhubd",
|
||||
"usbhidd",
|
||||
"inputd",
|
||||
"virtio-core",
|
||||
|
||||
@@ -23,6 +21,9 @@ members = [
|
||||
"graphics/vesad",
|
||||
"graphics/virtio-gpud",
|
||||
|
||||
"input/ps2d",
|
||||
"input/usbhidd",
|
||||
|
||||
"net/alxd",
|
||||
"net/driver-network",
|
||||
"net/e1000d",
|
||||
|
||||
@@ -9,5 +9,6 @@ redox-daemon = "0.1"
|
||||
redox_syscall = "0.5"
|
||||
|
||||
common = { path = "../../common" }
|
||||
inputd = { path = "../../inputd" }
|
||||
pcid = { path = "../../pcid" }
|
||||
libredox = "0.1.3"
|
||||
|
||||
@@ -4,6 +4,7 @@ extern crate syscall;
|
||||
use std::fs::File;
|
||||
use std::io::{Read, Write};
|
||||
|
||||
use inputd::ProducerHandle;
|
||||
use pcid_interface::PciFunctionHandle;
|
||||
use syscall::call::iopl;
|
||||
use syscall::data::Packet;
|
||||
@@ -35,7 +36,7 @@ fn main() {
|
||||
|
||||
let mut scheme = BgaScheme {
|
||||
bga,
|
||||
display: File::open("/scheme/input/producer").ok(),
|
||||
display: ProducerHandle::new().ok(),
|
||||
};
|
||||
|
||||
scheme.update_size();
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
use std::fs::File;
|
||||
use std::io::Write;
|
||||
use std::str;
|
||||
use inputd::ProducerHandle;
|
||||
use syscall::data::Stat;
|
||||
use syscall::{Error, Result, SchemeMut, EACCES, EINVAL, MODE_CHR};
|
||||
|
||||
@@ -8,14 +7,14 @@ use crate::bga::Bga;
|
||||
|
||||
pub struct BgaScheme {
|
||||
pub bga: Bga,
|
||||
pub display: Option<File>,
|
||||
pub display: Option<ProducerHandle>,
|
||||
}
|
||||
|
||||
impl BgaScheme {
|
||||
pub fn update_size(&mut self) {
|
||||
if let Some(ref mut display) = self.display {
|
||||
let _ = display.write(
|
||||
&orbclient::ResizeEvent {
|
||||
let _ = display.write_event(
|
||||
orbclient::ResizeEvent {
|
||||
width: self.bga.width() as u32,
|
||||
height: self.bga.height() as u32,
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ ransid = "0.4"
|
||||
redox_event = "0.4"
|
||||
redox_syscall = "0.5"
|
||||
redox-daemon = "0.1"
|
||||
redox-scheme = { git = "https://gitlab.redox-os.org/redox-os/redox-scheme.git" }
|
||||
|
||||
inputd = { path = "../../inputd" }
|
||||
libredox = "0.1.3"
|
||||
|
||||
@@ -157,22 +157,8 @@ impl Display {
|
||||
|
||||
let url =
|
||||
String::from_utf8(Vec::from(&buf[..count])).expect("Could not create Utf8 Url String");
|
||||
let path = Self::url_parts(&url)?;
|
||||
let (width, height) = Self::parse_display_path(path);
|
||||
let path = url.split(':').nth(1).expect("Could not get path from url");
|
||||
|
||||
Ok((display_file, width, height))
|
||||
}
|
||||
|
||||
fn url_parts(url: &str) -> io::Result<&str> {
|
||||
let mut url_parts = url.split(':');
|
||||
url_parts
|
||||
.next()
|
||||
.expect("Could not get scheme name from url");
|
||||
let path = url_parts.next().expect("Could not get path from url");
|
||||
Ok(path)
|
||||
}
|
||||
|
||||
fn parse_display_path(path: &str) -> (usize, usize) {
|
||||
let mut path_parts = path.split('/').skip(1);
|
||||
let width = path_parts
|
||||
.next()
|
||||
@@ -185,7 +171,7 @@ impl Display {
|
||||
.parse::<usize>()
|
||||
.unwrap_or(0);
|
||||
|
||||
(width, height)
|
||||
Ok((display_file, width, height))
|
||||
}
|
||||
|
||||
pub fn resize(&mut self, width: usize, height: usize) {
|
||||
|
||||
+49
-60
@@ -1,14 +1,12 @@
|
||||
#![feature(io_error_more)]
|
||||
|
||||
use event::EventQueue;
|
||||
use libredox::errno::ESTALE;
|
||||
use libredox::errno::{EAGAIN, EINTR, ESTALE};
|
||||
use orbclient::Event;
|
||||
use std::fs::{File, OpenOptions};
|
||||
use std::io::{ErrorKind, Read, Write};
|
||||
use redox_scheme::{CallRequest, RequestKind, Response, SignalBehavior, Socket};
|
||||
use std::os::fd::{AsRawFd, BorrowedFd};
|
||||
use std::os::unix::fs::OpenOptionsExt;
|
||||
use std::{env, mem, slice};
|
||||
use syscall::{Packet, SchemeMut, EVENT_READ, O_NONBLOCK};
|
||||
use syscall::EVENT_READ;
|
||||
|
||||
use crate::scheme::{FbconScheme, VtIndex};
|
||||
|
||||
@@ -42,16 +40,10 @@ fn inner(daemon: redox_daemon::Daemon, vt_ids: &[usize]) -> ! {
|
||||
|
||||
// FIXME listen for resize events from inputd and handle them
|
||||
|
||||
let mut socket = OpenOptions::new()
|
||||
.write(true)
|
||||
.create(true)
|
||||
.truncate(true)
|
||||
.custom_flags(O_NONBLOCK as i32)
|
||||
.open(":fbcon")
|
||||
.expect("fbcond: failed to create fbcon scheme");
|
||||
let mut socket = Socket::nonblock("fbcon").expect("fbcond: failed to create fbcon scheme");
|
||||
event_queue
|
||||
.subscribe(
|
||||
socket.as_raw_fd().as_raw_fd() as usize,
|
||||
socket.inner().raw(),
|
||||
VtIndex::SCHEMA_SENTINEL,
|
||||
event::EventFlags::READ,
|
||||
)
|
||||
@@ -91,37 +83,49 @@ fn inner(daemon: redox_daemon::Daemon, vt_ids: &[usize]) -> ! {
|
||||
}
|
||||
|
||||
fn handle_event(
|
||||
socket: &mut File,
|
||||
socket: &mut Socket,
|
||||
scheme: &mut FbconScheme,
|
||||
blocked: &mut Vec<Packet>,
|
||||
blocked: &mut Vec<CallRequest>,
|
||||
event: VtIndex,
|
||||
) {
|
||||
match event {
|
||||
VtIndex::SCHEMA_SENTINEL => {
|
||||
loop {
|
||||
let mut packet = Packet::default();
|
||||
match socket.read(&mut packet) {
|
||||
Ok(0) => break,
|
||||
Err(err) if err.kind() == ErrorKind::WouldBlock => {
|
||||
break;
|
||||
let request = match socket.next_request(SignalBehavior::Restart) {
|
||||
Ok(Some(request)) => request,
|
||||
Ok(None) => {
|
||||
// Scheme likely got unmounted
|
||||
std::process::exit(0);
|
||||
}
|
||||
Ok(_) => {}
|
||||
Err(err) => {
|
||||
panic!("fbcond: failed to read display scheme: {err}");
|
||||
}
|
||||
}
|
||||
Err(err) if err.errno == EAGAIN => break,
|
||||
Err(err) => panic!("vesad: failed to read display scheme: {err}"),
|
||||
};
|
||||
|
||||
// If it is a read packet, and there is no data, block it. Otherwise, handle packet
|
||||
if packet.a == syscall::number::SYS_READ
|
||||
&& packet.d > 0
|
||||
&& scheme.can_read(packet.b).is_none()
|
||||
{
|
||||
blocked.push(packet);
|
||||
} else {
|
||||
scheme.handle(&mut packet);
|
||||
socket
|
||||
.write(&packet)
|
||||
.expect("fbcond: failed to write display scheme");
|
||||
match request.kind() {
|
||||
RequestKind::Call(call_request) => {
|
||||
if let Some(resp) = call_request.handle_scheme_block_mut(scheme) {
|
||||
socket
|
||||
.write_response(resp, SignalBehavior::Restart)
|
||||
.expect("vesad: failed to write display scheme");
|
||||
} else {
|
||||
blocked.push(call_request);
|
||||
}
|
||||
}
|
||||
RequestKind::Cancellation(cancellation_request) => {
|
||||
if let Some(i) = blocked
|
||||
.iter()
|
||||
.position(|req| req.request().request_id() == cancellation_request.id)
|
||||
{
|
||||
let blocked_req = blocked.remove(i);
|
||||
let resp = Response::new(&blocked_req, Err(syscall::Error::new(EINTR)));
|
||||
socket
|
||||
.write_response(resp, SignalBehavior::Restart)
|
||||
.expect("vesad: failed to write display scheme");
|
||||
}
|
||||
}
|
||||
RequestKind::MsyncMsg | RequestKind::MunmapMsg | RequestKind::MmapMsg => {
|
||||
unreachable!()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -150,16 +154,15 @@ fn handle_event(
|
||||
}
|
||||
}
|
||||
|
||||
// If there are blocked readers, and data is available, handle them
|
||||
// If there are blocked readers, try to handle them.
|
||||
{
|
||||
let mut i = 0;
|
||||
while i < blocked.len() {
|
||||
if scheme.can_read(blocked[i].b).is_some() {
|
||||
let mut packet = blocked.remove(i);
|
||||
scheme.handle(&mut packet);
|
||||
if let Some(resp) = blocked[i].handle_scheme_block_mut(scheme) {
|
||||
socket
|
||||
.write(&packet)
|
||||
.expect("fbcond: failed to write display scheme");
|
||||
.write_response(resp, SignalBehavior::Restart)
|
||||
.expect("vesad: failed to write display scheme");
|
||||
blocked.remove(i);
|
||||
} else {
|
||||
i += 1;
|
||||
}
|
||||
@@ -171,30 +174,16 @@ fn handle_event(
|
||||
continue;
|
||||
}
|
||||
|
||||
// Can't use scheme.can_read() because we borrow handles as mutable.
|
||||
// (and because it'd treat O_NONBLOCK sockets differently)
|
||||
let count = scheme
|
||||
let can_read = scheme
|
||||
.vts
|
||||
.get(&handle.vt_i)
|
||||
.and_then(|console| console.can_read())
|
||||
.unwrap_or(0);
|
||||
.map_or(false, |console| console.can_read());
|
||||
|
||||
if count > 0 {
|
||||
if can_read {
|
||||
if !handle.notified_read {
|
||||
handle.notified_read = true;
|
||||
let event_packet = Packet {
|
||||
id: 0,
|
||||
pid: 0,
|
||||
uid: 0,
|
||||
gid: 0,
|
||||
a: syscall::number::SYS_FEVENT,
|
||||
b: *handle_id,
|
||||
c: EVENT_READ.bits(),
|
||||
d: count,
|
||||
};
|
||||
|
||||
socket
|
||||
.write(&event_packet)
|
||||
.post_fevent(*handle_id, EVENT_READ.bits())
|
||||
.expect("fbcond: failed to write display event");
|
||||
}
|
||||
} else {
|
||||
|
||||
@@ -2,7 +2,8 @@ use std::collections::BTreeMap;
|
||||
use std::os::fd::AsRawFd;
|
||||
|
||||
use event::{EventQueue, UserData};
|
||||
use syscall::{Error, EventFlags, Result, SchemeMut, EBADF, EINVAL, ENOENT, O_NONBLOCK};
|
||||
use redox_scheme::SchemeBlockMut;
|
||||
use syscall::{Error, EventFlags, Result, EBADF, EINVAL, ENOENT, O_NONBLOCK};
|
||||
|
||||
use crate::display::Display;
|
||||
use crate::text::TextScreen;
|
||||
@@ -61,22 +62,6 @@ impl FbconScheme {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn can_read(&self, id: usize) -> Option<usize> {
|
||||
if let Some(handle) = self.handles.get(&id) {
|
||||
if let Some(console) = self.vts.get(&handle.vt_i) {
|
||||
console
|
||||
.can_read()
|
||||
.or(if handle.flags & O_NONBLOCK == O_NONBLOCK {
|
||||
Some(0)
|
||||
} else {
|
||||
None
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Some(0)
|
||||
}
|
||||
|
||||
fn resize(&mut self, width: usize, height: usize, stride: usize) {
|
||||
for console in self.vts.values_mut() {
|
||||
console.resize(width, height);
|
||||
@@ -84,8 +69,14 @@ impl FbconScheme {
|
||||
}
|
||||
}
|
||||
|
||||
impl SchemeMut for FbconScheme {
|
||||
fn open(&mut self, path_str: &str, flags: usize, _uid: u32, _gid: u32) -> Result<usize> {
|
||||
impl SchemeBlockMut for FbconScheme {
|
||||
fn open(
|
||||
&mut self,
|
||||
path_str: &str,
|
||||
flags: usize,
|
||||
_uid: u32,
|
||||
_gid: u32,
|
||||
) -> Result<Option<usize>> {
|
||||
let vt_i = VtIndex(path_str.parse::<usize>().map_err(|_| Error::new(ENOENT))?);
|
||||
if let Some(_console) = self.vts.get_mut(&vt_i) {
|
||||
let id = self.next_id;
|
||||
@@ -101,13 +92,13 @@ impl SchemeMut for FbconScheme {
|
||||
},
|
||||
);
|
||||
|
||||
Ok(id)
|
||||
Ok(Some(id))
|
||||
} else {
|
||||
Err(Error::new(ENOENT))
|
||||
}
|
||||
}
|
||||
|
||||
fn dup(&mut self, id: usize, buf: &[u8]) -> Result<usize> {
|
||||
fn dup(&mut self, id: usize, buf: &[u8]) -> Result<Option<usize>> {
|
||||
if !buf.is_empty() {
|
||||
return Err(Error::new(EINVAL));
|
||||
}
|
||||
@@ -123,19 +114,23 @@ impl SchemeMut for FbconScheme {
|
||||
|
||||
self.handles.insert(new_id, handle);
|
||||
|
||||
Ok(new_id)
|
||||
Ok(Some(new_id))
|
||||
}
|
||||
|
||||
fn fevent(&mut self, id: usize, flags: syscall::EventFlags) -> Result<syscall::EventFlags> {
|
||||
fn fevent(
|
||||
&mut self,
|
||||
id: usize,
|
||||
flags: syscall::EventFlags,
|
||||
) -> Result<Option<syscall::EventFlags>> {
|
||||
let handle = self.handles.get_mut(&id).ok_or(Error::new(EBADF))?;
|
||||
|
||||
handle.notified_read = false;
|
||||
|
||||
handle.events = flags;
|
||||
Ok(syscall::EventFlags::empty())
|
||||
Ok(Some(syscall::EventFlags::empty()))
|
||||
}
|
||||
|
||||
fn fpath(&mut self, id: usize, buf: &mut [u8]) -> Result<usize> {
|
||||
fn fpath(&mut self, id: usize, buf: &mut [u8]) -> Result<Option<usize>> {
|
||||
let handle = self.handles.get(&id).ok_or(Error::new(EBADF))?;
|
||||
|
||||
let path_str = format!("fbcon:{}", handle.vt_i.0);
|
||||
@@ -148,37 +143,53 @@ impl SchemeMut for FbconScheme {
|
||||
i += 1;
|
||||
}
|
||||
|
||||
Ok(i)
|
||||
Ok(Some(i))
|
||||
}
|
||||
|
||||
fn fsync(&mut self, id: usize) -> Result<usize> {
|
||||
fn fsync(&mut self, id: usize) -> Result<Option<usize>> {
|
||||
let _handle = self.handles.get(&id).ok_or(Error::new(EBADF))?;
|
||||
|
||||
return Ok(0);
|
||||
return Ok(Some(0));
|
||||
}
|
||||
|
||||
fn read(&mut self, id: usize, buf: &mut [u8]) -> Result<usize> {
|
||||
fn read(
|
||||
&mut self,
|
||||
id: usize,
|
||||
buf: &mut [u8],
|
||||
_offset: u64,
|
||||
_fcntl_flags: u32,
|
||||
) -> Result<Option<usize>> {
|
||||
let handle = self.handles.get(&id).ok_or(Error::new(EBADF))?;
|
||||
|
||||
if let Some(screen) = self.vts.get_mut(&handle.vt_i) {
|
||||
return screen.read(buf);
|
||||
if !screen.can_read() && handle.flags & O_NONBLOCK != O_NONBLOCK {
|
||||
return Ok(None);
|
||||
} else {
|
||||
return screen.read(buf).map(Some);
|
||||
}
|
||||
}
|
||||
|
||||
Err(Error::new(EBADF))
|
||||
}
|
||||
|
||||
fn write(&mut self, id: usize, buf: &[u8]) -> Result<usize> {
|
||||
fn write(
|
||||
&mut self,
|
||||
id: usize,
|
||||
buf: &[u8],
|
||||
_offset: u64,
|
||||
_fcntl_flags: u32,
|
||||
) -> Result<Option<usize>> {
|
||||
let handle = self.handles.get(&id).ok_or(Error::new(EBADF))?;
|
||||
|
||||
if let Some(console) = self.vts.get_mut(&handle.vt_i) {
|
||||
console.write(buf)
|
||||
console.write(buf).map(Some)
|
||||
} else {
|
||||
Err(Error::new(EBADF))
|
||||
}
|
||||
}
|
||||
|
||||
fn close(&mut self, id: usize) -> Result<usize> {
|
||||
fn close(&mut self, id: usize) -> Result<Option<usize>> {
|
||||
self.handles.remove(&id).ok_or(Error::new(EBADF))?;
|
||||
Ok(0)
|
||||
Ok(Some(0))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -204,12 +204,8 @@ impl TextScreen {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn can_read(&self) -> Option<usize> {
|
||||
if self.input.is_empty() {
|
||||
None
|
||||
} else {
|
||||
Some(self.input.len())
|
||||
}
|
||||
pub fn can_read(&self) -> bool {
|
||||
!self.input.is_empty()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -7,8 +7,10 @@ edition = "2018"
|
||||
bitflags = "1"
|
||||
log = "0.4"
|
||||
orbclient = "0.3.27"
|
||||
redox_event = "0.4.1"
|
||||
redox_syscall = "0.5"
|
||||
redox-daemon = "0.1"
|
||||
libredox = "0.1.3"
|
||||
|
||||
common = { path = "../common" }
|
||||
common = { path = "../../common" }
|
||||
inputd = { path = "../../inputd" }
|
||||
@@ -6,11 +6,13 @@ extern crate orbclient;
|
||||
extern crate syscall;
|
||||
|
||||
use std::fs::OpenOptions;
|
||||
use std::io::{Read, Write};
|
||||
use std::io::Read;
|
||||
use std::os::unix::fs::OpenOptionsExt;
|
||||
use std::os::unix::io::AsRawFd;
|
||||
use std::{env, process};
|
||||
|
||||
use event::{user_data, EventQueue};
|
||||
use inputd::ProducerHandle;
|
||||
use log::info;
|
||||
use syscall::call::iopl;
|
||||
|
||||
@@ -49,16 +51,17 @@ fn daemon(daemon: redox_daemon::Daemon) -> ! {
|
||||
|
||||
info!("ps2d: using keymap '{}'", keymap_name);
|
||||
|
||||
let input = OpenOptions::new()
|
||||
.write(true)
|
||||
.open("/scheme/input/producer")
|
||||
.expect("ps2d: failed to open /scheme/input/producer");
|
||||
let input = ProducerHandle::new().expect("ps2d: failed to open input producer");
|
||||
|
||||
let mut event_file = OpenOptions::new()
|
||||
.read(true)
|
||||
.write(true)
|
||||
.open("/scheme/event")
|
||||
.expect("ps2d: failed to open /scheme/event");
|
||||
user_data! {
|
||||
enum Source {
|
||||
Keyboard,
|
||||
Mouse,
|
||||
}
|
||||
}
|
||||
|
||||
let event_queue: EventQueue<Source> =
|
||||
EventQueue::new().expect("ps2d: failed to create event queue");
|
||||
|
||||
let mut key_file = OpenOptions::new()
|
||||
.read(true)
|
||||
@@ -67,13 +70,13 @@ fn daemon(daemon: redox_daemon::Daemon) -> ! {
|
||||
.open("/scheme/serio/0")
|
||||
.expect("ps2d: failed to open /scheme/serio/0");
|
||||
|
||||
event_file
|
||||
.write(&syscall::Event {
|
||||
id: key_file.as_raw_fd() as usize,
|
||||
flags: syscall::EVENT_READ,
|
||||
data: 0,
|
||||
})
|
||||
.expect("ps2d: failed to event /scheme/serio/0");
|
||||
event_queue
|
||||
.subscribe(
|
||||
key_file.as_raw_fd() as usize,
|
||||
Source::Keyboard,
|
||||
event::EventFlags::READ,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let mut mouse_file = OpenOptions::new()
|
||||
.read(true)
|
||||
@@ -82,13 +85,13 @@ fn daemon(daemon: redox_daemon::Daemon) -> ! {
|
||||
.open("/scheme/serio/1")
|
||||
.expect("ps2d: failed to open /scheme/serio/1");
|
||||
|
||||
event_file
|
||||
.write(&syscall::Event {
|
||||
id: mouse_file.as_raw_fd() as usize,
|
||||
flags: syscall::EVENT_READ,
|
||||
data: 1,
|
||||
})
|
||||
.expect("ps2d: failed to event /scheme/serio/1");
|
||||
event_queue
|
||||
.subscribe(
|
||||
mouse_file.as_raw_fd() as usize,
|
||||
Source::Mouse,
|
||||
event::EventFlags::READ,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
libredox::call::setrens(0, 0).expect("ps2d: failed to enter null namespace");
|
||||
|
||||
@@ -99,7 +102,7 @@ fn daemon(daemon: redox_daemon::Daemon) -> ! {
|
||||
let mut ps2d = Ps2d::new(input, keymap);
|
||||
|
||||
let mut data = [0; 256];
|
||||
loop {
|
||||
for event in event_queue.map(|e| e.expect("ps2d: failed to get next event").user_data) {
|
||||
// There are some gotchas with ps/2 controllers that require this weird
|
||||
// way of doing things. You read key and mouse data from the same
|
||||
// place. There is a status register that may show you which the data
|
||||
@@ -109,19 +112,9 @@ fn daemon(daemon: redox_daemon::Daemon) -> ! {
|
||||
// Due to this, we have a kernel driver doing a small amount of work
|
||||
// to grab bytes and sort them based on the source
|
||||
|
||||
let mut event = syscall::Event::default();
|
||||
if event_file
|
||||
.read(&mut event)
|
||||
.expect("ps2d: failed to read event file")
|
||||
== 0
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
let (file, keyboard) = match event.data {
|
||||
0 => (&mut key_file, true),
|
||||
1 => (&mut mouse_file, false),
|
||||
_ => continue,
|
||||
let (file, keyboard) = match event {
|
||||
Source::Keyboard => (&mut key_file, true),
|
||||
Source::Mouse => (&mut mouse_file, false),
|
||||
};
|
||||
|
||||
loop {
|
||||
@@ -1,8 +1,4 @@
|
||||
use std::fs::File;
|
||||
use std::io::Write;
|
||||
use std::os::unix::io::AsRawFd;
|
||||
use std::str;
|
||||
|
||||
use inputd::ProducerHandle;
|
||||
use log::{error, warn};
|
||||
use orbclient::{ButtonEvent, KeyEvent, MouseEvent, MouseRelativeEvent, ScrollEvent};
|
||||
|
||||
@@ -26,7 +22,7 @@ pub struct Ps2d<F: Fn(u8, bool) -> char> {
|
||||
ps2: Ps2,
|
||||
vmmouse: bool,
|
||||
vmmouse_relative: bool,
|
||||
input: File,
|
||||
input: ProducerHandle,
|
||||
extended: bool,
|
||||
lshift: bool,
|
||||
rshift: bool,
|
||||
@@ -43,7 +39,7 @@ pub struct Ps2d<F: Fn(u8, bool) -> char> {
|
||||
}
|
||||
|
||||
impl<F: Fn(u8, bool) -> char> Ps2d<F> {
|
||||
pub fn new(input: File, keymap: F) -> Self {
|
||||
pub fn new(input: ProducerHandle, keymap: F) -> Self {
|
||||
let mut ps2 = Ps2::new();
|
||||
let extra_packet = ps2.init().expect("ps2d: failed to initialize");
|
||||
|
||||
@@ -229,8 +225,8 @@ impl<F: Fn(u8, bool) -> char> Ps2d<F> {
|
||||
|
||||
if scancode != 0 {
|
||||
self.input
|
||||
.write(
|
||||
&KeyEvent {
|
||||
.write_event(
|
||||
KeyEvent {
|
||||
character: (self.get_char)(
|
||||
ps2_scancode,
|
||||
self.lshift || self.rshift,
|
||||
@@ -263,8 +259,8 @@ impl<F: Fn(u8, bool) -> char> Ps2d<F> {
|
||||
if self.vmmouse_relative {
|
||||
if dx != 0 || dy != 0 {
|
||||
self.input
|
||||
.write(
|
||||
&MouseRelativeEvent {
|
||||
.write_event(
|
||||
MouseRelativeEvent {
|
||||
dx: dx as i32,
|
||||
dy: dy as i32,
|
||||
}
|
||||
@@ -279,15 +275,15 @@ impl<F: Fn(u8, bool) -> char> Ps2d<F> {
|
||||
self.mouse_x = x;
|
||||
self.mouse_y = y;
|
||||
self.input
|
||||
.write(&MouseEvent { x, y }.to_event())
|
||||
.write_event(MouseEvent { x, y }.to_event())
|
||||
.expect("ps2d: failed to write mouse event");
|
||||
}
|
||||
};
|
||||
|
||||
if dz != 0 {
|
||||
self.input
|
||||
.write(
|
||||
&ScrollEvent {
|
||||
.write_event(
|
||||
ScrollEvent {
|
||||
x: 0,
|
||||
y: -(dz as i32),
|
||||
}
|
||||
@@ -307,11 +303,11 @@ impl<F: Fn(u8, bool) -> char> Ps2d<F> {
|
||||
self.mouse_middle = middle;
|
||||
self.mouse_right = right;
|
||||
self.input
|
||||
.write(
|
||||
&ButtonEvent {
|
||||
left: left,
|
||||
middle: middle,
|
||||
right: right,
|
||||
.write_event(
|
||||
ButtonEvent {
|
||||
left,
|
||||
middle,
|
||||
right,
|
||||
}
|
||||
.to_event(),
|
||||
)
|
||||
@@ -355,13 +351,13 @@ impl<F: Fn(u8, bool) -> char> Ps2d<F> {
|
||||
|
||||
if dx != 0 || dy != 0 {
|
||||
self.input
|
||||
.write(&MouseRelativeEvent { dx: dx, dy: dy }.to_event())
|
||||
.write_event(MouseRelativeEvent { dx, dy }.to_event())
|
||||
.expect("ps2d: failed to write mouse event");
|
||||
}
|
||||
|
||||
if dz != 0 {
|
||||
self.input
|
||||
.write(&ScrollEvent { x: 0, y: dz }.to_event())
|
||||
.write_event(ScrollEvent { x: 0, y: dz }.to_event())
|
||||
.expect("ps2d: failed to write scroll event");
|
||||
}
|
||||
|
||||
@@ -376,11 +372,11 @@ impl<F: Fn(u8, bool) -> char> Ps2d<F> {
|
||||
self.mouse_middle = middle;
|
||||
self.mouse_right = right;
|
||||
self.input
|
||||
.write(
|
||||
&ButtonEvent {
|
||||
left: left,
|
||||
middle: middle,
|
||||
right: right,
|
||||
.write_event(
|
||||
ButtonEvent {
|
||||
left,
|
||||
middle,
|
||||
right,
|
||||
}
|
||||
.to_event(),
|
||||
)
|
||||
@@ -13,6 +13,7 @@ log = "0.4"
|
||||
orbclient = "0.3.47"
|
||||
redox_syscall = "0.5"
|
||||
rehid = { git = "https://gitlab.redox-os.org/redox-os/rehid.git" }
|
||||
xhcid = { path = "../xhcid" }
|
||||
xhcid = { path = "../../xhcid" }
|
||||
|
||||
common = { path = "../common" }
|
||||
common = { path = "../../common" }
|
||||
inputd = { path = "../../inputd" }
|
||||
@@ -1,8 +1,7 @@
|
||||
use std::collections::VecDeque;
|
||||
use std::env;
|
||||
use std::fs::File;
|
||||
use std::io::{Read, Write};
|
||||
|
||||
use inputd::ProducerHandle;
|
||||
use orbclient::KeyEvent as OrbKeyEvent;
|
||||
use rehid::{
|
||||
report_desc::{self, ReportTy, REPORT_DESC_TY},
|
||||
@@ -17,7 +16,7 @@ mod keymap;
|
||||
mod reqs;
|
||||
|
||||
fn send_key_event(
|
||||
display: &mut File,
|
||||
display: &mut ProducerHandle,
|
||||
usage_page: u16,
|
||||
usage: u16,
|
||||
pressed: bool,
|
||||
@@ -159,7 +158,7 @@ fn send_key_event(
|
||||
pressed,
|
||||
};
|
||||
|
||||
match display.write(&key_event.to_event()) {
|
||||
match display.write_event(key_event.to_event()) {
|
||||
Ok(_) => (),
|
||||
Err(err) => {
|
||||
log::warn!("failed to send key event to orbital: {}", err);
|
||||
@@ -277,8 +276,7 @@ fn main() {
|
||||
let report_ty = ReportTy::Input;
|
||||
let report_id = 0;
|
||||
|
||||
let mut display =
|
||||
File::open("/scheme/input/producer").expect("Failed to open orbital input socket");
|
||||
let mut display = ProducerHandle::new().expect("Failed to open input socket");
|
||||
let mut endpoint_opt = match endp_desc_opt {
|
||||
Some((endp_num, _endp_desc)) => match handle.open_endpoint(endp_num as u8) {
|
||||
Ok(ok) => Some(ok),
|
||||
@@ -405,7 +403,7 @@ fn main() {
|
||||
y: mouse_pos.1 * 2,
|
||||
};
|
||||
|
||||
match display.write(&mouse_event.to_event()) {
|
||||
match display.write_event(mouse_event.to_event()) {
|
||||
Ok(_) => (),
|
||||
Err(err) => {
|
||||
log::warn!("failed to send mouse event to orbital: {}", err);
|
||||
@@ -419,7 +417,7 @@ fn main() {
|
||||
dy: mouse_dy,
|
||||
};
|
||||
|
||||
match display.write(&mouse_event.to_event()) {
|
||||
match display.write_event(mouse_event.to_event()) {
|
||||
Ok(_) => (),
|
||||
Err(err) => {
|
||||
log::warn!("failed to send mouse event to orbital: {}", err);
|
||||
@@ -430,7 +428,7 @@ fn main() {
|
||||
if scroll_y != 0 {
|
||||
let scroll_event = orbclient::event::ScrollEvent { x: 0, y: scroll_y };
|
||||
|
||||
match display.write(&scroll_event.to_event()) {
|
||||
match display.write_event(scroll_event.to_event()) {
|
||||
Ok(_) => (),
|
||||
Err(err) => {
|
||||
log::warn!("failed to send scroll event to orbital: {}", err);
|
||||
@@ -447,7 +445,7 @@ fn main() {
|
||||
middle: buttons[2],
|
||||
};
|
||||
|
||||
match display.write(&button_event.to_event()) {
|
||||
match display.write_event(button_event.to_event()) {
|
||||
Ok(_) => (),
|
||||
Err(err) => {
|
||||
log::warn!("failed to send button event to orbital: {}", err);
|
||||
@@ -162,3 +162,16 @@ impl Damage {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
pub struct ProducerHandle(File);
|
||||
|
||||
impl ProducerHandle {
|
||||
pub fn new() -> Result<Self, Error> {
|
||||
File::open("/scheme/input/producer").map(ProducerHandle)
|
||||
}
|
||||
|
||||
pub fn write_event(&mut self, event: orbclient::Event) -> Result<(), Error> {
|
||||
self.0.write(&event)?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user