diff --git a/Cargo.toml b/Cargo.toml index 4da2394..2247890 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,5 +1,37 @@ -[workspace] -members = [ - "pinnacle", - "pinnacle_api", +[package] +name = "pinnacle" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +tracing = "0.1.37" +tracing-subscriber = { version = "0.3.17", features = ["env-filter"] } +smithay = { git = "https://github.com/Smithay/smithay", rev = "9b3d173" } +smithay-drm-extras = { git = "https://github.com/Smithay/smithay", optional = true } +thiserror = "1.0.40" +xcursor = {version = "0.3.4", optional = true } +image = {version = "0.24.0", default-features = false, optional = true} +serde = { version = "1.0.164", features = ["derive"] } +rmp = { version = "0.8.11" } +rmp-serde = { version = "1.1.1" } + +[features] +default = ["egl", "winit", "udev"] +egl = ["smithay/use_system_lib", "smithay/backend_egl"] +udev = [ + "smithay-drm-extras", + "smithay/backend_libinput", + "smithay/backend_udev", + "smithay/backend_drm", + "smithay/backend_gbm", + "smithay/backend_vulkan", + "smithay/backend_egl", + "smithay/backend_session_libseat", + "image", + "smithay/renderer_gl", + "smithay/renderer_multi", + "xcursor", ] +winit = ["smithay/backend_winit", "smithay/backend_drm"] diff --git a/pinnacle/Cargo.toml b/pinnacle/Cargo.toml deleted file mode 100644 index 19fc880..0000000 --- a/pinnacle/Cargo.toml +++ /dev/null @@ -1,35 +0,0 @@ -[package] -name = "pinnacle" -version = "0.1.0" -edition = "2021" - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[dependencies] -pinnacle_api = { path = "../pinnacle_api" } -tracing = "0.1.37" -tracing-subscriber = { version = "0.3.17", features = ["env-filter"] } -smithay = { git = "https://github.com/Smithay/smithay", rev = "9b3d173" } -smithay-drm-extras = { git = "https://github.com/Smithay/smithay", optional = true } -thiserror = "1.0.40" -xcursor = {version = "0.3.4", optional = true } -image = {version = "0.24.0", default-features = false, optional = true} - -[features] -default = ["egl", "winit", "udev"] -egl = ["smithay/use_system_lib", "smithay/backend_egl"] -udev = [ - "smithay-drm-extras", - "smithay/backend_libinput", - "smithay/backend_udev", - "smithay/backend_drm", - "smithay/backend_gbm", - "smithay/backend_vulkan", - "smithay/backend_egl", - "smithay/backend_session_libseat", - "image", - "smithay/renderer_gl", - "smithay/renderer_multi", - "xcursor", -] -winit = ["smithay/backend_winit", "smithay/backend_drm"] diff --git a/pinnacle_api/Cargo.toml b/pinnacle_api/Cargo.toml deleted file mode 100644 index 9bf52bb..0000000 --- a/pinnacle_api/Cargo.toml +++ /dev/null @@ -1,15 +0,0 @@ -[package] -name = "pinnacle_api" -version = "0.1.0" -edition = "2021" - -[dependencies] -tracing = "0.1.37" -tracing-subscriber = { version = "0.3.17", features = ["env-filter"] } -rkyv = { version = "0.7.42", features = ["validation", "strict"] } -num_enum = "0.6.1" -serde = { version = "1.0.164", features = ["derive"] } -serde_json = { version = "1.0.96" } -rmp-serde = { version = "1.1.1" } -xkbcommon = { version = "0.5.0" } -smithay = { git = "https://github.com/Smithay/smithay", rev = "9b3d173" } diff --git a/pinnacle_api/src/lib.rs b/pinnacle_api/src/lib.rs deleted file mode 100644 index 38e8a25..0000000 --- a/pinnacle_api/src/lib.rs +++ /dev/null @@ -1,189 +0,0 @@ -use std::{ - error::Error, - io, - os::unix::net::{UnixListener, UnixStream}, - path::Path, -}; - -use smithay::reexports::calloop::{ - self, generic::Generic, EventSource, Interest, Mode, PostAction, -}; - -use crate::message::Msg; - -pub mod message; - -const SOCKET_PATH: &str = "/tmp/pinnacle_socket"; - -pub fn run() -> Result<(), Box> { - let socket_path = Path::new(SOCKET_PATH); - - if socket_path.exists() { - std::fs::remove_file(socket_path)?; - } - - let listener = UnixListener::bind(SOCKET_PATH)?; - - std::thread::spawn(move || { - for stream in listener.incoming() { - match stream { - Ok(stream) => { - std::thread::spawn(|| handle_client(stream)); - } - Err(err) => { - eprintln!("Incoming stream error: {}", err); - } - } - } - }); - - Ok(()) -} - -fn handle_client(stream: UnixStream) { - loop { - let msg: Msg = rmp_serde::from_read(&stream).unwrap(); - - println!("{:?}", msg); - } -} - -pub struct PinnacleSocketSource { - socket: Generic, -} - -impl PinnacleSocketSource { - pub fn new() -> Result { - let socket_path = Path::new(SOCKET_PATH); - - if socket_path.exists() { - std::fs::remove_file(socket_path)?; - } - - let listener = UnixListener::bind(SOCKET_PATH)?; - - let socket = Generic::new(listener, Interest::READ, Mode::Level); - - Ok(Self { socket }) - } -} - -impl EventSource for PinnacleSocketSource { - type Event = UnixStream; - - type Metadata = (); - - type Ret = (); - - type Error = io::Error; - - fn process_events( - &mut self, - readiness: calloop::Readiness, - token: calloop::Token, - mut callback: F, - ) -> Result - where - F: FnMut(Self::Event, &mut Self::Metadata) -> Self::Ret, - { - self.socket - .process_events(readiness, token, |_readiness, listener| { - listener.set_nonblocking(true)?; - while let Ok((stream, _sock_addr)) = listener.accept() { - stream.set_nonblocking(true)?; - callback(stream, &mut ()); - } - - Ok(PostAction::Continue) - }) - } - - fn register( - &mut self, - poll: &mut calloop::Poll, - token_factory: &mut calloop::TokenFactory, - ) -> calloop::Result<()> { - self.socket.register(poll, token_factory) - } - - fn reregister( - &mut self, - poll: &mut calloop::Poll, - token_factory: &mut calloop::TokenFactory, - ) -> calloop::Result<()> { - self.socket.reregister(poll, token_factory) - } - - fn unregister(&mut self, poll: &mut calloop::Poll) -> calloop::Result<()> { - self.socket.unregister(poll) - } -} - -pub struct PinnacleStreamSource { - stream: Generic, -} - -impl PinnacleStreamSource { - pub fn new(stream: UnixStream) -> Self { - Self { - stream: Generic::new(stream, Interest::READ, Mode::Level), - } - } -} - -impl EventSource for PinnacleStreamSource { - type Event = Msg; - - type Metadata = (); - - type Ret = (); - - type Error = io::Error; - - fn process_events( - &mut self, - readiness: calloop::Readiness, - token: calloop::Token, - mut callback: F, - ) -> Result - where - F: FnMut(Self::Event, &mut Self::Metadata) -> Self::Ret, - { - self.stream - .process_events(readiness, token, |_readiness, stream| { - match rmp_serde::from_read(stream as &UnixStream) { - Ok(msg) => callback(msg, &mut ()), - Err(rmp_serde::decode::Error::InvalidMarkerRead(err)) - if err.kind() == io::ErrorKind::UnexpectedEof => - { - stream.shutdown(std::net::Shutdown::Both)?; - println!("Stream closed: {:?}", err); - return Ok(PostAction::Remove); - } - Err(err) => println!("{:?}", err), - } - - Ok(PostAction::Continue) - }) - } - - fn register( - &mut self, - poll: &mut calloop::Poll, - token_factory: &mut calloop::TokenFactory, - ) -> calloop::Result<()> { - self.stream.register(poll, token_factory) - } - - fn reregister( - &mut self, - poll: &mut calloop::Poll, - token_factory: &mut calloop::TokenFactory, - ) -> calloop::Result<()> { - self.stream.reregister(poll, token_factory) - } - - fn unregister(&mut self, poll: &mut calloop::Poll) -> calloop::Result<()> { - self.stream.unregister(poll) - } -} diff --git a/pinnacle_api_lua/README.md b/pinnacle_api_lua/README.md index cefd36c..84a3d4d 100644 --- a/pinnacle_api_lua/README.md +++ b/pinnacle_api_lua/README.md @@ -1,2 +1,2 @@ -The cffi library courtesy of https://github.com/q66/cffi-lua. The luaposix library courtesy of https://github.com/luaposix/luaposix. +NOTE: there is an issue with this library where recv's return value is size_t, not ssize_t as it should be. This library uses a patched version, see https://github.com/luaposix/luaposix/issues/354. diff --git a/pinnacle_api_lua/init.lua b/pinnacle_api_lua/init.lua index d5799eb..1d489b7 100644 --- a/pinnacle_api_lua/init.lua +++ b/pinnacle_api_lua/init.lua @@ -1,29 +1,35 @@ -- require("luarocks.loader") -package.path = "./lib/?.lua;./lib/?/init.lua;" .. package.path -package.cpath = "./lib/?.so;" .. package.cpath +local LOCAL_PATH = "/home/jason/projects/pinnacle/pinnacle_api_lua" + +package.path = LOCAL_PATH .. "/lib/?.lua;" .. LOCAL_PATH .. "/lib/?/init.lua;" .. package.path +package.cpath = LOCAL_PATH .. "/lib/?.so;" .. package.cpath local socket = require("posix.sys.socket") -local msgpack = require("lib.msgpack") +local fcntl = require("posix.fcntl") +local msgpack = require("msgpack") local SOCKET_PATH = "/tmp/pinnacle_socket" -local CONFIG_PATH = os.getenv("XDG_CONFIG_HOME") .. "/pinnacle/init.lua" +local CONFIG_PATH = (os.getenv("XDG_CONFIG_HOME") or "~/.config") .. "/pinnacle/init.lua" package.path = CONFIG_PATH .. ";" .. package.path -local sockaddr = { - family = socket.AF_UNIX, - path = SOCKET_PATH, -} - +---@type integer local socket_fd = assert(socket.socket(socket.AF_UNIX, socket.SOCK_STREAM, 0), "Failed to create socket") print("created socket at fd " .. socket_fd) -assert(0 == socket.connect(socket_fd, sockaddr), "Failed to connect to Pinnacle socket") +assert(0 == socket.connect(socket_fd, { + family = socket.AF_UNIX, + path = SOCKET_PATH, +}), "Failed to connect to Pinnacle socket") function SendMsg(data) - socket.send(socket_fd, msgpack.encode(data)) + local encoded = msgpack.encode(data) + assert(encoded) + local len = encoded:len() + socket.send(socket_fd, string.pack("=I4", len)) + socket.send(socket_fd, encoded) end ---@type function[] @@ -31,24 +37,51 @@ CallbackTable = {} assert(pcall(require, "pinnacle"), "config file not found") --- local str = msgpack.encode({ --- SetMousebind = { button = 6 }, --- }) --- local str = msgpack.encode({ --- SetKeybind = { --- key = "This is a key", --- modifiers = { "ctrl", "boogers", "numpty" }, --- }, --- }) --- print(str) --- --- socket.send(socket_fd, str) +---Read the specified number of bytes. +---@param socket_fd integer The socket file descriptor +---@param count integer The amount of bytes to read +---@return string|nil data +---@return string|nil err_msg +---@return integer|nil err_num +local function read_exact(socket_fd, count) + local len_to_read = count + local data = "" + while len_to_read > 0 do + local bytes, err_msg, errnum = socket.recv(socket_fd, len_to_read) --- unistd.close(socket_fd) + if bytes == nil then + -- TODO: handle errors + print("bytes was nil") + return bytes, err_msg, errnum + end --- local keys = require("keys") --- --- local input = require("input") --- input.keybind({ "Shift", "Ctrl" }, keys.c, "CloseWindow") -while true do + ---@type integer + local recv_len = bytes:len() + + if recv_len == 0 then + print("stream closed") + break + end + + len_to_read = len_to_read - recv_len + assert(len_to_read >= 0, "Overread message boundary") + + data = data .. bytes + end + return data +end + +-- TODO: set timeouts so that you actually make sure the msg is correct +while true do + local msg_len_bytes, err_msg, err_num = read_exact(socket_fd, 4) + assert(msg_len_bytes) + + ---@type integer + local msg_len = string.unpack("=I4", msg_len_bytes) + + local msg_bytes, err_msg2, err_num2 = read_exact(socket_fd, msg_len) + assert(msg_bytes) + + local tb = msgpack.decode(msg_bytes) + print(tb) end diff --git a/pinnacle_api_lua/lib/msgpack.lua b/pinnacle_api_lua/lib/msgpack.lua index c5ad627..45ca5b3 100644 --- a/pinnacle_api_lua/lib/msgpack.lua +++ b/pinnacle_api_lua/lib/msgpack.lua @@ -346,7 +346,12 @@ return { end end, - -- primary decode function + -- Decode a string of MessagePack data into objects. + -- + ---@param data string The MessagePack packet + ---@param position any + ---@return any ... The decoded values unpacked. If decoding failed, nil + ---@return string | nil error The string "cannot decode MessagePack" if decoding failed decode = function(data, position) local values, value, ok = {} position = position or 1 diff --git a/pinnacle_api_lua/lib/posix/ctype.so b/pinnacle_api_lua/lib/posix/ctype.so new file mode 100755 index 0000000..8e78b96 Binary files /dev/null and b/pinnacle_api_lua/lib/posix/ctype.so differ diff --git a/pinnacle_api_lua/lib/posix/dirent.so b/pinnacle_api_lua/lib/posix/dirent.so new file mode 100755 index 0000000..4452000 Binary files /dev/null and b/pinnacle_api_lua/lib/posix/dirent.so differ diff --git a/pinnacle_api_lua/lib/posix/errno.so b/pinnacle_api_lua/lib/posix/errno.so new file mode 100755 index 0000000..42b34f3 Binary files /dev/null and b/pinnacle_api_lua/lib/posix/errno.so differ diff --git a/pinnacle_api_lua/lib/posix/fcntl.so b/pinnacle_api_lua/lib/posix/fcntl.so new file mode 100755 index 0000000..658f7e8 Binary files /dev/null and b/pinnacle_api_lua/lib/posix/fcntl.so differ diff --git a/pinnacle_api_lua/lib/posix/fnmatch.so b/pinnacle_api_lua/lib/posix/fnmatch.so new file mode 100755 index 0000000..8d5a562 Binary files /dev/null and b/pinnacle_api_lua/lib/posix/fnmatch.so differ diff --git a/pinnacle_api_lua/lib/posix/glob.so b/pinnacle_api_lua/lib/posix/glob.so new file mode 100755 index 0000000..78b4832 Binary files /dev/null and b/pinnacle_api_lua/lib/posix/glob.so differ diff --git a/pinnacle_api_lua/lib/posix/grp.so b/pinnacle_api_lua/lib/posix/grp.so new file mode 100755 index 0000000..bf71ccf Binary files /dev/null and b/pinnacle_api_lua/lib/posix/grp.so differ diff --git a/pinnacle_api_lua/lib/posix/libgen.so b/pinnacle_api_lua/lib/posix/libgen.so new file mode 100755 index 0000000..54fdd9e Binary files /dev/null and b/pinnacle_api_lua/lib/posix/libgen.so differ diff --git a/pinnacle_api_lua/lib/posix/poll.so b/pinnacle_api_lua/lib/posix/poll.so new file mode 100755 index 0000000..96ae97f Binary files /dev/null and b/pinnacle_api_lua/lib/posix/poll.so differ diff --git a/pinnacle_api_lua/lib/posix/pwd.so b/pinnacle_api_lua/lib/posix/pwd.so new file mode 100755 index 0000000..539b795 Binary files /dev/null and b/pinnacle_api_lua/lib/posix/pwd.so differ diff --git a/pinnacle_api_lua/lib/posix/sched.so b/pinnacle_api_lua/lib/posix/sched.so new file mode 100755 index 0000000..9832e23 Binary files /dev/null and b/pinnacle_api_lua/lib/posix/sched.so differ diff --git a/pinnacle_api_lua/lib/posix/signal.so b/pinnacle_api_lua/lib/posix/signal.so new file mode 100755 index 0000000..45c8631 Binary files /dev/null and b/pinnacle_api_lua/lib/posix/signal.so differ diff --git a/pinnacle_api_lua/lib/posix/stdio.so b/pinnacle_api_lua/lib/posix/stdio.so new file mode 100755 index 0000000..61f98cb Binary files /dev/null and b/pinnacle_api_lua/lib/posix/stdio.so differ diff --git a/pinnacle_api_lua/lib/posix/stdlib.so b/pinnacle_api_lua/lib/posix/stdlib.so new file mode 100755 index 0000000..de41648 Binary files /dev/null and b/pinnacle_api_lua/lib/posix/stdlib.so differ diff --git a/pinnacle_api_lua/lib/posix/sys/msg.so b/pinnacle_api_lua/lib/posix/sys/msg.so new file mode 100755 index 0000000..10d0544 Binary files /dev/null and b/pinnacle_api_lua/lib/posix/sys/msg.so differ diff --git a/pinnacle_api_lua/lib/posix/sys/resource.so b/pinnacle_api_lua/lib/posix/sys/resource.so new file mode 100755 index 0000000..154721c Binary files /dev/null and b/pinnacle_api_lua/lib/posix/sys/resource.so differ diff --git a/pinnacle_api_lua/lib/posix/sys/socket.so b/pinnacle_api_lua/lib/posix/sys/socket.so new file mode 100755 index 0000000..1618ba6 Binary files /dev/null and b/pinnacle_api_lua/lib/posix/sys/socket.so differ diff --git a/pinnacle_api_lua/lib/posix/sys/stat.so b/pinnacle_api_lua/lib/posix/sys/stat.so new file mode 100755 index 0000000..1ce1efc Binary files /dev/null and b/pinnacle_api_lua/lib/posix/sys/stat.so differ diff --git a/pinnacle_api_lua/lib/posix/sys/statvfs.so b/pinnacle_api_lua/lib/posix/sys/statvfs.so new file mode 100755 index 0000000..4174488 Binary files /dev/null and b/pinnacle_api_lua/lib/posix/sys/statvfs.so differ diff --git a/pinnacle_api_lua/lib/posix/sys/time.so b/pinnacle_api_lua/lib/posix/sys/time.so new file mode 100755 index 0000000..1c40501 Binary files /dev/null and b/pinnacle_api_lua/lib/posix/sys/time.so differ diff --git a/pinnacle_api_lua/lib/posix/sys/times.so b/pinnacle_api_lua/lib/posix/sys/times.so new file mode 100755 index 0000000..145c147 Binary files /dev/null and b/pinnacle_api_lua/lib/posix/sys/times.so differ diff --git a/pinnacle_api_lua/lib/posix/sys/utsname.so b/pinnacle_api_lua/lib/posix/sys/utsname.so new file mode 100755 index 0000000..b3d67bf Binary files /dev/null and b/pinnacle_api_lua/lib/posix/sys/utsname.so differ diff --git a/pinnacle_api_lua/lib/posix/sys/wait.so b/pinnacle_api_lua/lib/posix/sys/wait.so new file mode 100755 index 0000000..c535590 Binary files /dev/null and b/pinnacle_api_lua/lib/posix/sys/wait.so differ diff --git a/pinnacle_api_lua/lib/posix/syslog.so b/pinnacle_api_lua/lib/posix/syslog.so new file mode 100755 index 0000000..f0ab94f Binary files /dev/null and b/pinnacle_api_lua/lib/posix/syslog.so differ diff --git a/pinnacle_api_lua/lib/posix/termio.so b/pinnacle_api_lua/lib/posix/termio.so new file mode 100755 index 0000000..1444ea1 Binary files /dev/null and b/pinnacle_api_lua/lib/posix/termio.so differ diff --git a/pinnacle_api_lua/lib/posix/time.so b/pinnacle_api_lua/lib/posix/time.so new file mode 100755 index 0000000..43f7067 Binary files /dev/null and b/pinnacle_api_lua/lib/posix/time.so differ diff --git a/pinnacle_api_lua/lib/posix/unistd.so b/pinnacle_api_lua/lib/posix/unistd.so new file mode 100755 index 0000000..ad09fae Binary files /dev/null and b/pinnacle_api_lua/lib/posix/unistd.so differ diff --git a/pinnacle_api_lua/lib/posix/utime.so b/pinnacle_api_lua/lib/posix/utime.so new file mode 100755 index 0000000..a5ec040 Binary files /dev/null and b/pinnacle_api_lua/lib/posix/utime.so differ diff --git a/pinnacle_api_lua/posix/ctype.so b/pinnacle_api_lua/lib/posix3/ctype.so similarity index 100% rename from pinnacle_api_lua/posix/ctype.so rename to pinnacle_api_lua/lib/posix3/ctype.so diff --git a/pinnacle_api_lua/posix/dirent.so b/pinnacle_api_lua/lib/posix3/dirent.so similarity index 100% rename from pinnacle_api_lua/posix/dirent.so rename to pinnacle_api_lua/lib/posix3/dirent.so diff --git a/pinnacle_api_lua/posix/errno.so b/pinnacle_api_lua/lib/posix3/errno.so similarity index 100% rename from pinnacle_api_lua/posix/errno.so rename to pinnacle_api_lua/lib/posix3/errno.so diff --git a/pinnacle_api_lua/posix/fcntl.so b/pinnacle_api_lua/lib/posix3/fcntl.so similarity index 100% rename from pinnacle_api_lua/posix/fcntl.so rename to pinnacle_api_lua/lib/posix3/fcntl.so diff --git a/pinnacle_api_lua/posix/fnmatch.so b/pinnacle_api_lua/lib/posix3/fnmatch.so similarity index 100% rename from pinnacle_api_lua/posix/fnmatch.so rename to pinnacle_api_lua/lib/posix3/fnmatch.so diff --git a/pinnacle_api_lua/posix/glob.so b/pinnacle_api_lua/lib/posix3/glob.so similarity index 100% rename from pinnacle_api_lua/posix/glob.so rename to pinnacle_api_lua/lib/posix3/glob.so diff --git a/pinnacle_api_lua/posix/grp.so b/pinnacle_api_lua/lib/posix3/grp.so similarity index 100% rename from pinnacle_api_lua/posix/grp.so rename to pinnacle_api_lua/lib/posix3/grp.so diff --git a/pinnacle_api_lua/posix/libgen.so b/pinnacle_api_lua/lib/posix3/libgen.so similarity index 100% rename from pinnacle_api_lua/posix/libgen.so rename to pinnacle_api_lua/lib/posix3/libgen.so diff --git a/pinnacle_api_lua/posix/poll.so b/pinnacle_api_lua/lib/posix3/poll.so similarity index 100% rename from pinnacle_api_lua/posix/poll.so rename to pinnacle_api_lua/lib/posix3/poll.so diff --git a/pinnacle_api_lua/posix/pwd.so b/pinnacle_api_lua/lib/posix3/pwd.so similarity index 100% rename from pinnacle_api_lua/posix/pwd.so rename to pinnacle_api_lua/lib/posix3/pwd.so diff --git a/pinnacle_api_lua/posix/sched.so b/pinnacle_api_lua/lib/posix3/sched.so similarity index 100% rename from pinnacle_api_lua/posix/sched.so rename to pinnacle_api_lua/lib/posix3/sched.so diff --git a/pinnacle_api_lua/posix/signal.so b/pinnacle_api_lua/lib/posix3/signal.so similarity index 100% rename from pinnacle_api_lua/posix/signal.so rename to pinnacle_api_lua/lib/posix3/signal.so diff --git a/pinnacle_api_lua/posix/stdio.so b/pinnacle_api_lua/lib/posix3/stdio.so similarity index 100% rename from pinnacle_api_lua/posix/stdio.so rename to pinnacle_api_lua/lib/posix3/stdio.so diff --git a/pinnacle_api_lua/posix/stdlib.so b/pinnacle_api_lua/lib/posix3/stdlib.so similarity index 100% rename from pinnacle_api_lua/posix/stdlib.so rename to pinnacle_api_lua/lib/posix3/stdlib.so diff --git a/pinnacle_api_lua/posix/sys/msg.so b/pinnacle_api_lua/lib/posix3/sys/msg.so similarity index 100% rename from pinnacle_api_lua/posix/sys/msg.so rename to pinnacle_api_lua/lib/posix3/sys/msg.so diff --git a/pinnacle_api_lua/posix/sys/resource.so b/pinnacle_api_lua/lib/posix3/sys/resource.so similarity index 100% rename from pinnacle_api_lua/posix/sys/resource.so rename to pinnacle_api_lua/lib/posix3/sys/resource.so diff --git a/pinnacle_api_lua/posix/sys/socket.so b/pinnacle_api_lua/lib/posix3/sys/socket.so similarity index 100% rename from pinnacle_api_lua/posix/sys/socket.so rename to pinnacle_api_lua/lib/posix3/sys/socket.so diff --git a/pinnacle_api_lua/posix/sys/stat.so b/pinnacle_api_lua/lib/posix3/sys/stat.so similarity index 100% rename from pinnacle_api_lua/posix/sys/stat.so rename to pinnacle_api_lua/lib/posix3/sys/stat.so diff --git a/pinnacle_api_lua/posix/sys/statvfs.so b/pinnacle_api_lua/lib/posix3/sys/statvfs.so similarity index 100% rename from pinnacle_api_lua/posix/sys/statvfs.so rename to pinnacle_api_lua/lib/posix3/sys/statvfs.so diff --git a/pinnacle_api_lua/posix/sys/time.so b/pinnacle_api_lua/lib/posix3/sys/time.so similarity index 100% rename from pinnacle_api_lua/posix/sys/time.so rename to pinnacle_api_lua/lib/posix3/sys/time.so diff --git a/pinnacle_api_lua/posix/sys/times.so b/pinnacle_api_lua/lib/posix3/sys/times.so similarity index 100% rename from pinnacle_api_lua/posix/sys/times.so rename to pinnacle_api_lua/lib/posix3/sys/times.so diff --git a/pinnacle_api_lua/posix/sys/utsname.so b/pinnacle_api_lua/lib/posix3/sys/utsname.so similarity index 100% rename from pinnacle_api_lua/posix/sys/utsname.so rename to pinnacle_api_lua/lib/posix3/sys/utsname.so diff --git a/pinnacle_api_lua/posix/sys/wait.so b/pinnacle_api_lua/lib/posix3/sys/wait.so similarity index 100% rename from pinnacle_api_lua/posix/sys/wait.so rename to pinnacle_api_lua/lib/posix3/sys/wait.so diff --git a/pinnacle_api_lua/posix/syslog.so b/pinnacle_api_lua/lib/posix3/syslog.so similarity index 100% rename from pinnacle_api_lua/posix/syslog.so rename to pinnacle_api_lua/lib/posix3/syslog.so diff --git a/pinnacle_api_lua/posix/termio.so b/pinnacle_api_lua/lib/posix3/termio.so similarity index 100% rename from pinnacle_api_lua/posix/termio.so rename to pinnacle_api_lua/lib/posix3/termio.so diff --git a/pinnacle_api_lua/posix/time.so b/pinnacle_api_lua/lib/posix3/time.so similarity index 100% rename from pinnacle_api_lua/posix/time.so rename to pinnacle_api_lua/lib/posix3/time.so diff --git a/pinnacle_api_lua/posix/unistd.so b/pinnacle_api_lua/lib/posix3/unistd.so similarity index 100% rename from pinnacle_api_lua/posix/unistd.so rename to pinnacle_api_lua/lib/posix3/unistd.so diff --git a/pinnacle_api_lua/posix/utime.so b/pinnacle_api_lua/lib/posix3/utime.so similarity index 100% rename from pinnacle_api_lua/posix/utime.so rename to pinnacle_api_lua/lib/posix3/utime.so diff --git a/pinnacle/resources/cursor.rgba b/resources/cursor.rgba similarity index 100% rename from pinnacle/resources/cursor.rgba rename to resources/cursor.rgba diff --git a/pinnacle/resources/numbers.png b/resources/numbers.png similarity index 100% rename from pinnacle/resources/numbers.png rename to resources/numbers.png diff --git a/src/api.rs b/src/api.rs new file mode 100644 index 0000000..d78cb80 --- /dev/null +++ b/src/api.rs @@ -0,0 +1,144 @@ +pub mod msg; + +use std::{ + io::{self, Read, Write}, + os::unix::net::{UnixDatagram, UnixListener, UnixStream}, + path::Path, +}; + +use smithay::reexports::calloop::{ + self, channel::Sender, generic::Generic, EventSource, Interest, Mode, PostAction, +}; + +use self::msg::{Msg, OutgoingMsg}; + +const SOCKET_PATH: &str = "/tmp/pinnacle_socket"; + +fn handle_client(mut stream: UnixStream, sender: Sender) { + loop { + let mut len_marker_bytes = [0u8; 4]; + if let Err(err) = stream.read_exact(&mut len_marker_bytes) { + if err.kind() == io::ErrorKind::UnexpectedEof { + tracing::warn!("stream closed: {}", err); + stream.shutdown(std::net::Shutdown::Both).unwrap(); + break; + } + }; + + let len_marker = u32::from_ne_bytes(len_marker_bytes); + let mut msg_bytes = vec![0u8; len_marker as usize]; + + if let Err(err) = stream.read_exact(msg_bytes.as_mut_slice()) { + if err.kind() == io::ErrorKind::UnexpectedEof { + tracing::warn!("stream closed: {}", err); + stream.shutdown(std::net::Shutdown::Both).unwrap(); + break; + } + }; + let msg: Msg = rmp_serde::from_slice(msg_bytes.as_slice()).unwrap(); // TODO: handle error + + sender.send(msg).unwrap(); + } + tracing::info!("end of handle_client"); +} + +pub struct PinnacleSocketSource { + socket: Generic, + sender: Sender, +} + +impl PinnacleSocketSource { + pub fn new(sender: Sender) -> Result { + let socket_path = Path::new(SOCKET_PATH); + + if let Ok(exists) = socket_path.try_exists() { + if exists { + std::fs::remove_file(socket_path)?; + } + } + + let listener = UnixListener::bind(SOCKET_PATH)?; + listener.set_nonblocking(true)?; + + let socket = Generic::new(listener, Interest::READ, Mode::Level); + + Ok(Self { socket, sender }) + } +} + +pub fn send_to_client( + stream: &mut UnixStream, + msg: &OutgoingMsg, +) -> Result<(), rmp_serde::encode::Error> { + let msg = rmp_serde::to_vec_named(msg)?; + let msg_len = msg.len() as u32; + let bytes = msg_len.to_ne_bytes(); + + if let Err(err) = stream.write_all(&bytes) { + if err.kind() == io::ErrorKind::BrokenPipe { + // TODO: notify user that config daemon is ded + return Ok(()); // TODO: + } + } + if let Err(err) = stream.write_all(msg.as_slice()) { + if err.kind() == io::ErrorKind::BrokenPipe { + // TODO: something + return Ok(()); // TODO: + } + }; + Ok(()) +} + +impl EventSource for PinnacleSocketSource { + type Event = UnixStream; + + type Metadata = (); + + type Ret = (); + + type Error = io::Error; + + fn process_events( + &mut self, + readiness: calloop::Readiness, + token: calloop::Token, + mut callback: F, + ) -> Result + where + F: FnMut(Self::Event, &mut Self::Metadata) -> Self::Ret, + { + self.socket + .process_events(readiness, token, |_readiness, listener| { + while let Ok((stream, _sock_addr)) = listener.accept() { + let sender = self.sender.clone(); + let callback_stream = stream.try_clone().unwrap(); // TODO: error + callback(callback_stream, &mut ()); + std::thread::spawn(move || { + handle_client(stream, sender); + }); + } + + Ok(PostAction::Continue) + }) + } + + fn register( + &mut self, + poll: &mut calloop::Poll, + token_factory: &mut calloop::TokenFactory, + ) -> calloop::Result<()> { + self.socket.register(poll, token_factory) + } + + fn reregister( + &mut self, + poll: &mut calloop::Poll, + token_factory: &mut calloop::TokenFactory, + ) -> calloop::Result<()> { + self.socket.reregister(poll, token_factory) + } + + fn unregister(&mut self, poll: &mut calloop::Poll) -> calloop::Result<()> { + self.socket.unregister(poll) + } +} diff --git a/pinnacle_api/src/message.rs b/src/api/msg.rs similarity index 87% rename from pinnacle_api/src/message.rs rename to src/api/msg.rs index 6dc252c..ac290ec 100644 --- a/pinnacle_api/src/message.rs +++ b/src/api/msg.rs @@ -41,3 +41,9 @@ impl> From for ModifierMask { Self(mask) } } + +/// Messages sent from the server to each client. +#[derive(Debug, serde::Serialize, serde::Deserialize)] +pub enum OutgoingMsg { + CallCallback(u32), +} diff --git a/pinnacle/src/backend.rs b/src/backend.rs similarity index 100% rename from pinnacle/src/backend.rs rename to src/backend.rs diff --git a/pinnacle/src/backend/udev.rs b/src/backend/udev.rs similarity index 100% rename from pinnacle/src/backend/udev.rs rename to src/backend/udev.rs diff --git a/pinnacle/src/backend/winit.rs b/src/backend/winit.rs similarity index 98% rename from pinnacle/src/backend/winit.rs rename to src/backend/winit.rs index a036feb..bed4e7e 100644 --- a/pinnacle/src/backend/winit.rs +++ b/src/backend/winit.rs @@ -138,7 +138,7 @@ pub fn run_winit() -> Result<(), Box> { Some(dmabuf_default_feedback) } Ok(None) => { - tracing::warn!("failed to query render node, dmabuf will use v3"); // TODO: tracing + tracing::warn!("failed to query render node, dmabuf will use v3"); None } Err(err) => { @@ -181,6 +181,11 @@ pub fn run_winit() -> Result<(), Box> { evt_loop_handle, )?; + // std::process::Command::new("lua") + // .arg("../pinnacle_api_lua/init.lua") + // .spawn() + // .unwrap(); + state .shm_state .update_formats(state.backend_data.backend.renderer().shm_formats()); diff --git a/pinnacle/src/cursor.rs b/src/cursor.rs similarity index 100% rename from pinnacle/src/cursor.rs rename to src/cursor.rs diff --git a/pinnacle/src/grab.rs b/src/grab.rs similarity index 100% rename from pinnacle/src/grab.rs rename to src/grab.rs diff --git a/pinnacle/src/grab/move_grab.rs b/src/grab/move_grab.rs similarity index 100% rename from pinnacle/src/grab/move_grab.rs rename to src/grab/move_grab.rs diff --git a/pinnacle/src/grab/resize_grab.rs b/src/grab/resize_grab.rs similarity index 100% rename from pinnacle/src/grab/resize_grab.rs rename to src/grab/resize_grab.rs diff --git a/pinnacle/src/handlers.rs b/src/handlers.rs similarity index 100% rename from pinnacle/src/handlers.rs rename to src/handlers.rs diff --git a/pinnacle/src/input.rs b/src/input.rs similarity index 95% rename from pinnacle/src/input.rs rename to src/input.rs index c650109..87a24e7 100644 --- a/pinnacle/src/input.rs +++ b/src/input.rs @@ -1,6 +1,6 @@ use std::collections::HashMap; -use pinnacle_api::message::{ModifierMask, Modifiers}; +use crate::api::msg::{ModifierMask, Modifiers, OutgoingMsg}; use smithay::{ backend::input::{ AbsolutePositionEvent, Axis, AxisSource, ButtonState, Event, InputBackend, InputEvent, @@ -216,13 +216,13 @@ impl State { .keybinds .get(&(modifier_mask.into(), keysym.modified_sym())) { - return FilterResult::Intercept(1); + return FilterResult::Intercept(*callback_id); } match keysym.modified_sym() { - keysyms::KEY_L => return FilterResult::Intercept(1), - keysyms::KEY_K => return FilterResult::Intercept(2), - keysyms::KEY_J => return FilterResult::Intercept(3), - keysyms::KEY_H => return FilterResult::Intercept(4), + keysyms::KEY_L => return FilterResult::Intercept(100), + keysyms::KEY_K => return FilterResult::Intercept(200), + keysyms::KEY_J => return FilterResult::Intercept(300), + keysyms::KEY_H => return FilterResult::Intercept(400), keysyms::KEY_Escape => { state.loop_signal.stop(); return FilterResult::Intercept(0); @@ -250,11 +250,22 @@ impl State { self.move_mode = move_mode; let program = match action { - Some(1) => "alacritty", - Some(2) => "nautilus", - Some(3) => "kitty", - Some(4) => "foot", - Some(_) | None => return, + Some(100) => "alacritty", + Some(200) => "nautilus", + Some(300) => "kitty", + Some(400) => "foot", + Some(callback_id) => { + if let Some(stream) = self.api_state.stream.as_mut() { + if let Err(err) = + crate::api::send_to_client(stream, &OutgoingMsg::CallCallback(callback_id)) + { + // TODO: print error + } + } + + return; + } + None => return, }; tracing::info!("Spawning {}", program); diff --git a/pinnacle/src/layout.rs b/src/layout.rs similarity index 100% rename from pinnacle/src/layout.rs rename to src/layout.rs diff --git a/pinnacle/src/layout/automatic.rs b/src/layout/automatic.rs similarity index 100% rename from pinnacle/src/layout/automatic.rs rename to src/layout/automatic.rs diff --git a/pinnacle/src/layout/manual.rs b/src/layout/manual.rs similarity index 100% rename from pinnacle/src/layout/manual.rs rename to src/layout/manual.rs diff --git a/pinnacle/src/main.rs b/src/main.rs similarity index 98% rename from pinnacle/src/main.rs rename to src/main.rs index e6fe6a2..788ab83 100644 --- a/pinnacle/src/main.rs +++ b/src/main.rs @@ -1,3 +1,4 @@ +mod api; mod backend; mod cursor; mod grab; diff --git a/pinnacle/src/pointer.rs b/src/pointer.rs similarity index 100% rename from pinnacle/src/pointer.rs rename to src/pointer.rs diff --git a/pinnacle/src/render.rs b/src/render.rs similarity index 100% rename from pinnacle/src/render.rs rename to src/render.rs diff --git a/pinnacle/src/render/pointer.rs b/src/render/pointer.rs similarity index 100% rename from pinnacle/src/render/pointer.rs rename to src/render/pointer.rs diff --git a/pinnacle/src/state.rs b/src/state.rs similarity index 72% rename from pinnacle/src/state.rs rename to src/state.rs index 17ce3e1..e5eeef2 100644 --- a/pinnacle/src/state.rs +++ b/src/state.rs @@ -1,6 +1,11 @@ -use std::{collections::HashMap, error::Error, os::fd::AsRawFd, sync::Arc}; +use std::{ + collections::HashMap, + error::Error, + os::{fd::AsRawFd, unix::net::UnixStream}, + sync::Arc, +}; -use pinnacle_api::{message::Msg, PinnacleSocketSource, PinnacleStreamSource}; +use crate::api::{msg::Msg, PinnacleSocketSource, PinnacleStreamSource}; use smithay::{ backend::renderer::element::RenderElementStates, desktop::{ @@ -13,7 +18,10 @@ use smithay::{ input::{keyboard::XkbConfig, pointer::CursorImageStatus, Seat, SeatState}, output::Output, reexports::{ - calloop::{generic::Generic, Interest, LoopHandle, LoopSignal, Mode, PostAction}, + calloop::{ + self, channel::Event, generic::Generic, Interest, LoopHandle, LoopSignal, Mode, + PostAction, + }, wayland_server::{ backend::{ClientData, ClientId, DisconnectReason}, protocol::wl_surface::WlSurface, @@ -59,6 +67,7 @@ pub struct State { pub viewporter_state: ViewporterState, pub fractional_scale_manager_state: FractionalScaleManagerState, pub input_state: InputState, + pub api_state: ApiState, pub popup_manager: PopupManager, @@ -97,29 +106,58 @@ impl State { }, )?; - loop_handle.insert_source(PinnacleSocketSource::new()?, |stream, _, data| { - data.state - .loop_handle - .insert_source(PinnacleStreamSource::new(stream), |msg, _, data| { - // TODO: do stuff with msg - match msg { - Msg::SetKeybind { - key, - modifiers, - callback_id, - } => { - tracing::info!("set keybind: {:?}, {}", modifiers, key); - data.state - .input_state - .keybinds - .insert((modifiers.into(), key), callback_id); - } - Msg::SetMousebind { button } => todo!(), - }; - }) - .unwrap(); + let (tx_channel, rx_channel) = calloop::channel::channel::(); + loop_handle.insert_source(rx_channel, |msg, _, data| match msg { + Event::Msg(msg) => { + match msg { + Msg::SetKeybind { + key, + modifiers, + callback_id, + } => { + tracing::info!("set keybind: {:?}, {}", modifiers, key); + data.state + .input_state + .keybinds + .insert((modifiers.into(), key), callback_id); + } + Msg::SetMousebind { button } => todo!(), + }; + } + Event::Closed => todo!(), })?; + // std::thread::spawn(move || { + // crate::api::init_api_socket(tx_channel).unwrap(); + // }); + + loop_handle.insert_source(PinnacleSocketSource::new(tx_channel)?, |stream, _, data| { + if let Some(old_stream) = data.state.api_state.stream.replace(stream) { + old_stream.shutdown(std::net::Shutdown::Both).unwrap(); + } + })?; + // data.state + // .loop_handle + // .insert_source(PinnacleStreamSource::new(stream), |msg, _, data| { + // // TODO: do stuff with msg + // match msg { + // Msg::SetKeybind { + // key, + // modifiers, + // callback_id, + // } => { + // tracing::info!("set keybind: {:?}, {}", modifiers, key); + // data.state + // .input_state + // .keybinds + // .insert((modifiers.into(), key), callback_id); + // } + // Msg::SetMousebind { button } => todo!(), + // }; + // }) + // .unwrap(); + // })?; + let display_handle = display.handle(); let mut seat_state = SeatState::new(); let mut seat = seat_state.new_wl_seat(&display_handle, backend_data.seat_name()); @@ -147,6 +185,7 @@ impl State { input_state: InputState { keybinds: HashMap::new(), }, + api_state: ApiState { stream: None }, seat, @@ -165,6 +204,7 @@ impl State { .cloned() } + // TODO: pub fn handle_msg(msg: Msg) { match msg { Msg::SetKeybind { @@ -231,3 +271,7 @@ pub fn take_presentation_feedback( output_presentation_feedback } + +pub struct ApiState { + pub stream: Option, +} diff --git a/pinnacle/src/window.rs b/src/window.rs similarity index 100% rename from pinnacle/src/window.rs rename to src/window.rs diff --git a/pinnacle/src/window/window_state.rs b/src/window/window_state.rs similarity index 100% rename from pinnacle/src/window/window_state.rs rename to src/window/window_state.rs diff --git a/pinnacle/src/xdg.rs b/src/xdg.rs similarity index 100% rename from pinnacle/src/xdg.rs rename to src/xdg.rs diff --git a/pinnacle/src/xdg/request.rs b/src/xdg/request.rs similarity index 100% rename from pinnacle/src/xdg/request.rs rename to src/xdg/request.rs