├── .gitignore ├── rustfmt.toml ├── cognitive ├── dharma │ ├── tests │ │ └── common │ │ │ └── mod.rs │ ├── Cargo.toml │ └── src │ │ ├── timer.rs │ │ ├── dharma.rs │ │ └── system.rs ├── renderer_gl │ ├── src │ │ ├── fragment.100.glsl │ │ ├── fragment.300.glsl │ │ ├── vertex.300.glsl │ │ ├── vertex.100.glsl │ │ └── lib.rs │ └── Cargo.toml ├── exhibitor │ ├── tests │ │ └── common │ │ │ ├── mod.rs │ │ │ └── configurations.rs │ ├── Cargo.toml │ └── src │ │ ├── lib.rs │ │ └── surface_history.rs ├── frames │ ├── tests │ │ ├── common │ │ │ ├── mod.rs │ │ │ ├── surface_listing_mock.rs │ │ │ └── surface_access_mock.rs │ │ └── test_frame_converting.rs │ ├── Cargo.toml │ └── src │ │ ├── lib.rs │ │ └── converting.rs ├── timber │ └── Cargo.toml ├── inputs │ ├── src │ │ ├── lib.rs │ │ ├── keymap.rs │ │ └── keyboard_state.rs │ └── Cargo.toml ├── graphics │ ├── Cargo.toml │ └── src │ │ ├── lib.rs │ │ ├── errors.rs │ │ └── gbm_tools.rs ├── wayland_frontend │ ├── src │ │ ├── protocol │ │ │ ├── mod.rs │ │ │ ├── weston_screenshooter.rs │ │ │ ├── display.rs │ │ │ ├── output.rs │ │ │ └── registry.rs │ │ ├── constants.rs │ │ ├── macros.rs │ │ ├── global.rs │ │ ├── lib.rs │ │ ├── gateway.rs │ │ └── mediator.rs │ └── Cargo.toml ├── aesthetics │ ├── Cargo.toml │ └── src │ │ ├── lib.rs │ │ ├── aesthetics.rs │ │ ├── background.rs │ │ └── cursor.rs ├── outputs │ ├── Cargo.toml │ └── src │ │ ├── lib.rs │ │ ├── output.rs │ │ └── output_mock.rs ├── qualia │ ├── Cargo.toml │ └── src │ │ ├── timing.rs │ │ ├── transfer.rs │ │ ├── settings.rs │ │ ├── lib.rs │ │ ├── configuration.rs │ │ ├── errors.rs │ │ ├── macros.rs │ │ └── image.rs ├── cognitive │ ├── Cargo.toml │ └── cognitive.rs └── device_manager │ ├── Cargo.toml │ └── src │ ├── drivers.rs │ ├── lib.rs │ ├── pageflip.rs │ ├── graphics_manager.rs │ └── device_access.rs ├── perceptia ├── coordination │ ├── Cargo.toml │ ├── lib.rs │ └── context.rs ├── gears │ ├── Cargo.toml │ ├── lib.rs │ └── functions.rs ├── perceptia │ ├── Cargo.toml │ ├── perceptia.rs │ ├── aesthetics_module.rs │ └── device_manager_module.rs ├── perceptiactl │ ├── Cargo.toml │ ├── about.rs │ ├── verify_config.rs │ └── perceptiactl.rs └── skylane_simple_framework │ ├── Cargo.toml │ └── src │ ├── protocol │ ├── mod.rs │ ├── screenshooter.rs │ ├── display.rs │ ├── callback.rs │ ├── compositor.rs │ ├── shell.rs │ ├── shm.rs │ └── drm.rs │ ├── lib.rs │ ├── defs.rs │ ├── listener.rs │ └── event_handler.rs ├── .travis.yml ├── info ├── authors.md ├── manual.perceptiactl.adoc ├── manual.perceptia.adoc ├── license.mit.txt ├── license.md ├── installation.md ├── manifesto.md └── concepts.md ├── Cargo.toml └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | target/ 2 | -------------------------------------------------------------------------------- /rustfmt.toml: -------------------------------------------------------------------------------- 1 | verbose = true 2 | fn_call_width = 100 3 | chain_one_line_max = 100 4 | where_density = "Tall" 5 | use_try_shorthand = true 6 | write_mode = "Overwrite" 7 | -------------------------------------------------------------------------------- /cognitive/dharma/tests/common/mod.rs: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of 2 | // the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/ 3 | 4 | //! Common parts of `dharma` tests. 5 | 6 | pub mod mocks; 7 | -------------------------------------------------------------------------------- /cognitive/renderer_gl/src/fragment.100.glsl: -------------------------------------------------------------------------------- 1 | #version 100 2 | 3 | //! Fragment shader source code for OpenGL ES 2.0 (GLSL ES 100) 4 | 5 | varying highp vec2 v_texcoords; 6 | uniform sampler2D texture; 7 | 8 | void main(void) 9 | { 10 | gl_FragColor = texture2D(texture, v_texcoords); 11 | } 12 | -------------------------------------------------------------------------------- /cognitive/renderer_gl/src/fragment.300.glsl: -------------------------------------------------------------------------------- 1 | #version 300 es 2 | 3 | //! Fragment shader source code for OpenGL ES 3.0 (GLSL ES 300) 4 | 5 | in highp vec2 v_texcoords; 6 | uniform sampler2D texture; 7 | out highp vec4 color; 8 | 9 | void main(void) 10 | { 11 | color = texture2D(texture, v_texcoords); 12 | } 13 | -------------------------------------------------------------------------------- /perceptia/coordination/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "coordination" 3 | version = "0.0.1" 4 | authors = ["Wojciech Kluczka "] 5 | 6 | [dependencies] 7 | dharma = "0.1" 8 | timber = "0.1" 9 | cognitive-graphics = "0.1" 10 | cognitive-qualia = "0.1" 11 | gears = { path = "../gears" } 12 | 13 | [lib] 14 | name = "coordination" 15 | path = "lib.rs" 16 | -------------------------------------------------------------------------------- /cognitive/exhibitor/tests/common/mod.rs: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of 2 | // the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/ 3 | 4 | //! Common functionality for unit tests. 5 | 6 | #![allow(dead_code)] 7 | 8 | pub mod configurations; 9 | pub mod exhibitor_mixins; 10 | -------------------------------------------------------------------------------- /perceptia/gears/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "gears" 3 | version = "0.0.1" 4 | authors = ["Wojciech Kluczka "] 5 | 6 | [dependencies] 7 | libc = "0.2" 8 | uinput-sys = "0.1" 9 | yaml-rust = "0.3" 10 | serde = "0.9" 11 | serde_yaml = "0.6" 12 | dharma = "0.1" 13 | timber = "0.1" 14 | cognitive-qualia = "0.1" 15 | 16 | [lib] 17 | name = "gears" 18 | path = "lib.rs" 19 | -------------------------------------------------------------------------------- /cognitive/frames/tests/common/mod.rs: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of 2 | // the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/ 3 | 4 | //! Common functionality for unit tests. 5 | 6 | #![allow(dead_code)] 7 | 8 | pub mod layouts; 9 | pub mod assertions; 10 | pub mod surface_access_mock; 11 | pub mod surface_listing_mock; 12 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: rust 2 | dist: trusty 3 | 4 | rust: 5 | - stable 6 | - beta 7 | - nightly 8 | - 1.16.0 9 | 10 | matrix: 11 | allow_failures: 12 | - rust: nightly 13 | 14 | before_install: 15 | - sudo apt-get update 16 | 17 | addons: 18 | apt: 19 | packages: 20 | - libdrm-dev 21 | - libgbm-dev 22 | - libudev-dev 23 | - libdbus-1-dev 24 | - libegl1-mesa-dev 25 | - libxkbcommon-dev 26 | 27 | script: | 28 | cargo build --all && cargo test --all 29 | -------------------------------------------------------------------------------- /cognitive/timber/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "timber" 3 | version = "0.1.0" 4 | description = "Simple configurable logging" 5 | documentation = "https://docs.rs/timber" 6 | homepage = "https://github.com/perceptia/perceptia" 7 | repository = "https://github.com/perceptia/perceptia" 8 | keywords = ["log", "logs", "logging", "timber"] 9 | license = "MIT" 10 | authors = ["Wojciech Kluczka "] 11 | 12 | [dependencies] 13 | time = "0.1" 14 | 15 | [lib] 16 | name = "timber" 17 | path = "timber.rs" 18 | -------------------------------------------------------------------------------- /cognitive/inputs/src/lib.rs: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of 2 | // the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/ 3 | 4 | //! Tools for handling events from input devices. 5 | 6 | extern crate xkbcommon; 7 | extern crate cognitive_qualia as qualia; 8 | 9 | pub mod codes; 10 | 11 | pub mod keyboard_state; 12 | pub use keyboard_state::{KeyboardState, KeyMods}; 13 | 14 | pub mod keymap; 15 | pub use keymap::Keymap; 16 | -------------------------------------------------------------------------------- /cognitive/renderer_gl/src/vertex.300.glsl: -------------------------------------------------------------------------------- 1 | #version 300 es 2 | 3 | //! Vertex shader source code for OpenGL ES 3.0 (GLSL ES 300) 4 | 5 | in vec2 vertices; 6 | in vec2 texcoords; 7 | uniform ivec2 screen_size; 8 | out vec2 v_texcoords; 9 | 10 | void main(void) 11 | { 12 | mat2 view_matrix = mat2(2.0/float(screen_size.x), 0.0, 13 | 0.0, -2.0/float(screen_size.y)); 14 | vec2 translation_vector = vec2(-1.0, 1.0); 15 | gl_Position = vec4(view_matrix * vertices + translation_vector, 0.0, 1.0); 16 | v_texcoords = texcoords; 17 | } 18 | -------------------------------------------------------------------------------- /perceptia/perceptia/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "perceptia" 3 | version = "0.5.0" 4 | authors = ["Wojciech Kluczka "] 5 | 6 | [dependencies] 7 | dharma = "0.1" 8 | timber = "0.1" 9 | cognitive-qualia = "0.1" 10 | cognitive-inputs = "0.1" 11 | cognitive-outputs = "0.1" 12 | cognitive-aesthetics = "0.1" 13 | cognitive-device-manager = "0.1" 14 | cognitive-exhibitor = "0.1" 15 | cognitive-wayland-frontend = "0.1" 16 | gears = { path = "../gears" } 17 | coordination = { path = "../coordination" } 18 | 19 | [[bin]] 20 | name = "perceptia" 21 | path = "perceptia.rs" 22 | -------------------------------------------------------------------------------- /cognitive/inputs/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "cognitive-inputs" 3 | version = "0.1.0" 4 | description = "Input related functionality for `cognitive`" 5 | documentation = "https://docs.rs/cognitive-inputs" 6 | homepage = "https://github.com/perceptia/perceptia" 7 | repository = "https://github.com/perceptia/perceptia" 8 | keywords = ["input"] 9 | license = "MPL-2.0" 10 | authors = ["Wojciech Kluczka "] 11 | 12 | [dependencies] 13 | xkbcommon = "0.2" 14 | timber = "0.1" 15 | cognitive-qualia = "0.1" 16 | 17 | [lib] 18 | name = "cognitive_inputs" 19 | path = "src/lib.rs" 20 | -------------------------------------------------------------------------------- /perceptia/perceptiactl/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "perceptiactl" 3 | version = "0.5.0" 4 | authors = ["Wojciech Kluczka "] 5 | 6 | [dependencies] 7 | clap = "2.19" 8 | egl = "0.2" 9 | gl = "0.6" 10 | nix = "0.8" 11 | libudev = "0.2" 12 | drm-rs = "0.1" 13 | image = "0.12" 14 | timber = "0.1" 15 | cognitive-graphics = "0.1" 16 | cognitive-qualia = "0.1" 17 | cognitive-device-manager = "0.1" 18 | gears = { path = "../gears" } 19 | skylane_simple_framework = { path = "../skylane_simple_framework" } 20 | 21 | [[bin]] 22 | name = "perceptiactl" 23 | path = "perceptiactl.rs" 24 | -------------------------------------------------------------------------------- /cognitive/renderer_gl/src/vertex.100.glsl: -------------------------------------------------------------------------------- 1 | #version 100 2 | 3 | //! Vertex shader source code for OpenGL ES 2.0 (GLSL ES 100) 4 | 5 | attribute vec2 vertices; 6 | attribute vec2 texcoords; 7 | uniform ivec2 screen_size; 8 | varying vec2 v_texcoords; 9 | 10 | void main(void) 11 | { 12 | mat2 view_matrix = mat2(2.0/float(screen_size.x), 0.0, 13 | 0.0, -2.0/float(screen_size.y)); 14 | vec2 translation_vector = vec2(-1.0, 1.0); 15 | gl_Position = vec4(view_matrix * vertices + translation_vector, 0.0, 1.0); 16 | v_texcoords = texcoords; 17 | } 18 | -------------------------------------------------------------------------------- /cognitive/graphics/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "cognitive-graphics" 3 | version = "0.1.0" 4 | description = "Simple tools related to hardware graphics" 5 | documentation = "https://docs.rs/cognitive-graphics" 6 | homepage = "https://github.com/perceptia/perceptia" 7 | repository = "https://github.com/perceptia/perceptia" 8 | keywords = ["gl", "egl", "gbm"] 9 | license = "MPL-2.0" 10 | authors = ["Wojciech Kluczka "] 11 | 12 | [dependencies] 13 | libc = "0.2" 14 | gbm-rs = "0.2" 15 | egl = "0.2" 16 | gl = "0.6" 17 | 18 | [lib] 19 | name = "cognitive_graphics" 20 | path = "src/lib.rs" 21 | -------------------------------------------------------------------------------- /cognitive/dharma/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "dharma" 3 | version = "0.1.0" 4 | description = "High-level framework for multi-thread applications" 5 | documentation = "https://docs.rs/dharma" 6 | homepage = "https://github.com/perceptia/perceptia" 7 | repository = "https://github.com/perceptia/perceptia" 8 | keywords = ["threads", "signals", "framework", "epoll"] 9 | license = "MPL-2.0" 10 | authors = ["Wojciech Kluczka "] 11 | 12 | [dependencies] 13 | bitflags = "0.8" 14 | timerfd = "0.2" 15 | nix = { version = "0.8", features = ["signalfd"] } 16 | 17 | [lib] 18 | name = "dharma" 19 | path = "src/dharma.rs" 20 | -------------------------------------------------------------------------------- /cognitive/wayland_frontend/src/protocol/mod.rs: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of 2 | // the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/ 3 | 4 | //! Implementation of handlers for Wayland protocol. 5 | 6 | pub mod display; 7 | pub mod registry; 8 | pub mod shm; 9 | 10 | pub mod compositor; 11 | pub mod shell; 12 | pub mod xdg_shell_v6; 13 | 14 | pub mod data_device_manager; 15 | pub mod seat; 16 | pub mod subcompositor; 17 | pub mod output; 18 | 19 | pub mod weston_screenshooter; 20 | 21 | pub mod linux_dmabuf_v1; 22 | pub mod mesa_drm; 23 | -------------------------------------------------------------------------------- /cognitive/aesthetics/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "cognitive-aesthetics" 3 | version = "0.1.0" 4 | description = "Aesthetic additions for `cognitive`" 5 | documentation = "https://docs.rs/cognitive-aesthetics" 6 | homepage = "https://github.com/perceptia/perceptia" 7 | repository = "https://github.com/perceptia/perceptia" 8 | keywords = ["cognitive"] 9 | license = "MPL-2.0" 10 | authors = ["Wojciech Kluczka "] 11 | 12 | [dependencies] 13 | chrono = "0.3" 14 | image = "0.12" 15 | font-loader = "0.2" 16 | rusttype = "0.2" 17 | timber = "0.1" 18 | cognitive-qualia = "0.1" 19 | 20 | [lib] 21 | name = "cognitive_aesthetics" 22 | path = "src/lib.rs" 23 | -------------------------------------------------------------------------------- /cognitive/renderer_gl/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "cognitive-renderer-gl" 3 | version = "0.1.0" 4 | description = "GL rendering for `cognitive`" 5 | documentation = "https://docs.rs/cognitive-renderer-gl" 6 | homepage = "https://github.com/perceptia/perceptia" 7 | repository = "https://github.com/perceptia/perceptia" 8 | keywords = ["gl", "cognitive"] 9 | license = "MPL-2.0" 10 | authors = ["Wojciech Kluczka "] 11 | 12 | [dependencies] 13 | libc = "0.2" 14 | egl = "0.2" 15 | gl = "0.6" 16 | timber = "0.1" 17 | cognitive-graphics = "0.1" 18 | cognitive-qualia = "0.1" 19 | 20 | [lib] 21 | name = "cognitive_renderer_gl" 22 | path = "src/lib.rs" 23 | -------------------------------------------------------------------------------- /cognitive/frames/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "cognitive-frames" 3 | version = "0.1.0" 4 | description = "Managing windows for `cognitive`" 5 | documentation = "https://docs.rs/cognitive-frames" 6 | homepage = "https://github.com/perceptia/perceptia" 7 | repository = "https://github.com/perceptia/perceptia" 8 | keywords = ["cognitive"] 9 | license = "MPL-2.0" 10 | authors = ["Wojciech Kluczka "] 11 | 12 | [features] 13 | testing = [] 14 | 15 | [dependencies] 16 | cognitive-qualia = "0.1" 17 | 18 | [dev-dependencies] 19 | cognitive-qualia = { version = "0.1", features = ["testing"] } 20 | 21 | [lib] 22 | name = "cognitive_frames" 23 | path = "src/lib.rs" 24 | -------------------------------------------------------------------------------- /info/authors.md: -------------------------------------------------------------------------------- 1 | Contributions 2 | ============= 3 | 4 | Developers 5 | ---------- 6 | 7 | * Wojciech Kluczka < wojciech dot kluczka at gmail dot com > 8 | 9 | Contributors 10 | ------------ 11 | 12 | No entries so far... 13 | 14 | Credits 15 | ------- 16 | 17 | * `kmscon` and `https://github.com/dvdhrm/docs` were great source of information and examples on 18 | KMS and GBM. 19 | 20 | * `weston` - the reference wayland surface compositor implementation was a great source of 21 | information about libwayland. 22 | 23 | Influences 24 | ---------- 25 | 26 | List of programs that influenced `perceptia`: 27 | 28 | * i3 29 | * awesome 30 | * dwm, ratpoison, musca 31 | * vim 32 | 33 | -------------------------------------------------------------------------------- /perceptia/skylane_simple_framework/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "skylane_simple_framework" 3 | version = "0.0.1" 4 | authors = ["Wojciech Kluczka "] 5 | 6 | [dependencies] 7 | nix = "0.8" 8 | gl = "0.6" 9 | egl = "0.2" 10 | gbm-rs = "0.2" 11 | drm-rs = "0.1" 12 | skylane = "0.1" 13 | skylane_protocols = "0.1" 14 | dharma = "0.1" 15 | timber = "0.1" 16 | cognitive-graphics = "0.1" 17 | cognitive-qualia = "0.1" 18 | 19 | [lib] 20 | name = "skylane_simple_framework" 21 | path = "src/lib.rs" 22 | 23 | [[example]] 24 | name = "simple_egl" 25 | path = "examples/simple_egl.rs" 26 | 27 | [[example]] 28 | name = "simple_dmabuf_intel" 29 | path = "examples/simple_dmabuf_intel.rs" 30 | -------------------------------------------------------------------------------- /cognitive/wayland_frontend/src/constants.rs: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of 2 | // the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/ 3 | 4 | //! This create contains constants for `wayland_frontend` crate. 5 | 6 | // ------------------------------------------------------------------------------------------------- 7 | 8 | pub const PROCESS_EVENTS: &'static str = "process_events"; 9 | pub const HANDLE_NEW_CLIENT: &'static str = "handle_new_client"; 10 | pub const TERMINATE_CLIENT: &'static str = "terminate_client"; 11 | 12 | // ------------------------------------------------------------------------------------------------- 13 | -------------------------------------------------------------------------------- /cognitive/outputs/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "cognitive-outputs" 3 | version = "0.1.0" 4 | description = "Output related functionality for `cognitive`" 5 | documentation = "https://docs.rs/cognitive-outputs" 6 | homepage = "https://github.com/perceptia/perceptia" 7 | repository = "https://github.com/perceptia/perceptia" 8 | keywords = ["drm", "cognitive"] 9 | license = "MPL-2.0" 10 | authors = ["Wojciech Kluczka "] 11 | 12 | [features] 13 | testing = [] 14 | 15 | [dependencies] 16 | libc = "0.2" 17 | drm-rs = "0.1" 18 | gbm-rs = "0.2" 19 | egl = "0.2" 20 | cognitive-graphics = "0.1" 21 | cognitive-qualia = "0.1" 22 | cognitive-renderer-gl = "0.1" 23 | 24 | [lib] 25 | name = "cognitive_outputs" 26 | path = "src/lib.rs" 27 | -------------------------------------------------------------------------------- /cognitive/aesthetics/src/lib.rs: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of 2 | // the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/ 3 | 4 | //! This crate provides aesthetic additions like setting background or default cursor theme. 5 | 6 | extern crate chrono; 7 | extern crate image; 8 | extern crate font_loader; 9 | extern crate rusttype; 10 | 11 | #[macro_use] 12 | extern crate timber; 13 | #[macro_use] 14 | extern crate cognitive_qualia as qualia; 15 | 16 | mod cursor; 17 | pub use cursor::Cursor; 18 | 19 | mod background; 20 | pub use background::Background; 21 | 22 | mod panels; 23 | pub use panels::PanelManager; 24 | 25 | mod aesthetics; 26 | pub use aesthetics::Aesthetics; 27 | -------------------------------------------------------------------------------- /cognitive/wayland_frontend/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "cognitive-wayland-frontend" 3 | version = "0.1.0" 4 | description = "Wayland frontend for `cognitive`" 5 | documentation = "https://docs.rs/cognitive-wayland-frontend" 6 | homepage = "https://github.com/perceptia/perceptia" 7 | repository = "https://github.com/perceptia/perceptia" 8 | keywords = ["wayland", "cognitive"] 9 | license = "MPL-2.0" 10 | authors = ["Wojciech Kluczka "] 11 | 12 | [dependencies] 13 | nix = "0.8" 14 | drm-rs = "0.1" 15 | skylane = "0.1" 16 | skylane_protocols = "0.1" 17 | dharma = "0.1" 18 | timber = "0.1" 19 | cognitive-graphics = "0.1" 20 | cognitive-qualia = "0.1" 21 | cognitive-inputs = "0.1" 22 | 23 | [lib] 24 | name = "cognitive_wayland_frontend" 25 | path = "src/lib.rs" 26 | -------------------------------------------------------------------------------- /perceptia/gears/lib.rs: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of 2 | // the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/ 3 | 4 | //! Bucket for general tools. 5 | 6 | extern crate libc; 7 | extern crate uinput_sys; 8 | 9 | extern crate yaml_rust; 10 | extern crate serde; 11 | extern crate serde_yaml; 12 | 13 | extern crate dharma; 14 | #[macro_use] 15 | extern crate timber; 16 | #[macro_use] 17 | extern crate cognitive_qualia as qualia; 18 | 19 | mod binding_functions; 20 | mod config_defaults; 21 | 22 | pub mod functions; 23 | 24 | pub mod config; 25 | pub use config::{Config, KeybindingsConfig}; 26 | 27 | pub mod input_manager; 28 | pub use input_manager::{InputForwarder, InputManager}; 29 | -------------------------------------------------------------------------------- /cognitive/outputs/src/lib.rs: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of 2 | // the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/ 3 | 4 | //! This crate contains code dedicated to managing output device like buffer swapping or controlling 5 | //! v-blanks. 6 | 7 | extern crate libc; 8 | extern crate egl; 9 | extern crate drm as libdrm; 10 | extern crate gbm_rs as libgbm; 11 | 12 | extern crate cognitive_graphics as graphics; 13 | extern crate cognitive_qualia as qualia; 14 | extern crate cognitive_renderer_gl as renderer_gl; 15 | 16 | mod output; 17 | pub use output::Output; 18 | 19 | mod drm_output; 20 | pub use drm_output::DrmOutput; 21 | 22 | #[cfg(feature = "testing")] 23 | pub mod output_mock; 24 | -------------------------------------------------------------------------------- /cognitive/qualia/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "cognitive-qualia" 3 | version = "0.1.0" 4 | description = "Basic definitions and traits for `cognitive`" 5 | documentation = "https://docs.rs/cognitive-qualia" 6 | homepage = "https://github.com/perceptia/perceptia" 7 | repository = "https://github.com/perceptia/perceptia" 8 | keywords = ["cognitive"] 9 | license = "MPL-2.0" 10 | authors = ["Wojciech Kluczka "] 11 | 12 | [features] 13 | testing = [] 14 | 15 | [dependencies] 16 | bitflags = "0.8" 17 | backtrace = "0.3" 18 | libc = "0.2" 19 | libudev = "0.2" 20 | nix = "0.8" 21 | time = "0.1" 22 | serde = "0.9" 23 | serde_derive = "0.9" 24 | dharma = "0.1" 25 | timber = "0.1" 26 | cognitive-graphics = "0.1" 27 | 28 | [lib] 29 | name = "cognitive_qualia" 30 | path = "src/lib.rs" 31 | -------------------------------------------------------------------------------- /cognitive/cognitive/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "cognitive" 3 | version = "0.1.0" 4 | description = "Curate package for crates related to building display compositors or window managers" 5 | documentation = "https://docs.rs/cognitive" 6 | homepage = "https://github.com/perceptia/perceptia" 7 | repository = "https://github.com/perceptia/perceptia" 8 | keywords = ["display-compositor", "window-manager", "cognitive"] 9 | license = "MPL-2.0" 10 | authors = ["Wojciech Kluczka "] 11 | 12 | [dependencies] 13 | timber = "0.1" 14 | dharma = "0.1" 15 | cognitive-graphics = "0.1" 16 | cognitive-qualia = "0.1" 17 | cognitive-renderer-gl = "0.1" 18 | cognitive-inputs = "0.1" 19 | cognitive-outputs = "0.1" 20 | cognitive-device-manager = "0.1" 21 | 22 | [lib] 23 | name = "cognitive" 24 | path = "cognitive.rs" 25 | -------------------------------------------------------------------------------- /cognitive/device_manager/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "cognitive-device-manager" 3 | version = "0.1.0" 4 | description = "Device management for `cognitive`" 5 | documentation = "https://docs.rs/cognitive-device-manager" 6 | homepage = "https://github.com/perceptia/perceptia" 7 | repository = "https://github.com/perceptia/perceptia" 8 | keywords = ["udev", "cognitive"] 9 | license = "MPL-2.0" 10 | authors = ["Wojciech Kluczka "] 11 | 12 | [dependencies] 13 | libc = "0.2" 14 | nix = "0.8" 15 | libudev-sys = "0.1" 16 | libudev = "0.2" 17 | drm-rs = "0.1" 18 | egl = "0.2" 19 | gbm-rs = "0.2" 20 | dbus = "0.5" 21 | dharma = "0.1" 22 | timber = "0.1" 23 | cognitive-graphics = "0.1" 24 | cognitive-qualia = "0.1" 25 | cognitive-inputs = "0.1" 26 | 27 | [lib] 28 | name = "cognitive_device_manager" 29 | path = "src/lib.rs" 30 | -------------------------------------------------------------------------------- /cognitive/graphics/src/lib.rs: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of 2 | // the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/ 3 | 4 | //! This create gathers common tools related to hardware graphics. 5 | //! 6 | //! It is set of loose simple tools. It should be replaced by higher-level crate. 7 | 8 | // ------------------------------------------------------------------------------------------------- 9 | 10 | extern crate libc; 11 | extern crate gbm_rs as libgbm; 12 | extern crate egl; 13 | extern crate gl; 14 | 15 | mod errors; 16 | pub use errors::GraphicsError; 17 | 18 | pub mod attributes; 19 | pub mod gbm_tools; 20 | pub mod egl_tools; 21 | pub mod gl_tools; 22 | 23 | // ------------------------------------------------------------------------------------------------- 24 | -------------------------------------------------------------------------------- /perceptia/perceptiactl/about.rs: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of 2 | // the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/ 3 | 4 | //! Printing useful information about `perceptia`. 5 | 6 | const ABOUT: &'static str = r#" 7 | Perceptia - dynamic window manager with support for Wayland 8 | 9 | Source code: 10 | https://github.com/perceptia/perceptia/ 11 | 12 | Bug tracker: 13 | https://github.com/perceptia/perceptia/issues 14 | 15 | Configuration: 16 | https://github.com/perceptia/perceptia/blob/master/info/configuration.md 17 | 18 | Contributors: 19 | https://github.com/perceptia/perceptia/blob/master/info/authors.md 20 | 21 | Mailing list: 22 | perceptia@freelists.org 23 | "#; 24 | 25 | pub fn process() { 26 | println!("{}", ABOUT); 27 | } 28 | -------------------------------------------------------------------------------- /cognitive/exhibitor/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "cognitive-exhibitor" 3 | version = "0.1.0" 4 | description = "Managing displays and compositing surfaces for `cognitive`" 5 | documentation = "https://docs.rs/cognitive-exhibitor" 6 | homepage = "https://github.com/perceptia/perceptia" 7 | repository = "https://github.com/perceptia/perceptia" 8 | keywords = ["cognitive"] 9 | license = "MPL-2.0" 10 | authors = ["Wojciech Kluczka "] 11 | 12 | [dependencies] 13 | rand = "0.3" 14 | timber = "0.1" 15 | cognitive-qualia = "0.1" 16 | cognitive-outputs = "0.1" 17 | cognitive-frames = "0.1" 18 | 19 | [dev-dependencies] 20 | cognitive-qualia = { version = "0.1", features = ["testing"] } 21 | cognitive-outputs = { version = "0.1", features = ["testing"] } 22 | cognitive-frames = { version = "0.1", features = ["testing"] } 23 | 24 | [lib] 25 | name = "cognitive_exhibitor" 26 | path = "src/lib.rs" 27 | -------------------------------------------------------------------------------- /cognitive/wayland_frontend/src/macros.rs: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of 2 | // the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/ 3 | 4 | //! This module contains common macros used in this crate. 5 | 6 | // ------------------------------------------------------------------------------------------------- 7 | 8 | /// This macro executes passed expression and in case of error logs warning about failing to send 9 | /// data. It is intended to use when posting `skylane` events to clients. 10 | #[macro_export] 11 | macro_rules! send { 12 | {$command:expr} => { 13 | ($command).unwrap_or_else ( 14 | move |err| log_warn2!("Failed to send data to client: {:?}", err) 15 | ); 16 | } 17 | } 18 | 19 | // ------------------------------------------------------------------------------------------------- 20 | -------------------------------------------------------------------------------- /cognitive/renderer_gl/src/lib.rs: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of 2 | // the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/ 3 | 4 | //! This crate contains code dedicated to managing output device like buffer swapping or controlling 5 | //! v-blanks. 6 | 7 | // ------------------------------------------------------------------------------------------------- 8 | 9 | extern crate libc; 10 | extern crate gl; 11 | extern crate egl; 12 | 13 | extern crate cognitive_graphics; 14 | 15 | // TODO: Enable logging only for debugging. 16 | #[macro_use(timber)] 17 | extern crate timber; 18 | #[macro_use] 19 | extern crate cognitive_qualia as qualia; 20 | 21 | mod cache_gl; 22 | 23 | pub mod renderer_gl; 24 | 25 | pub use renderer_gl::RendererGl; 26 | 27 | // ------------------------------------------------------------------------------------------------- 28 | -------------------------------------------------------------------------------- /cognitive/exhibitor/src/lib.rs: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of 2 | // the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/ 3 | 4 | //! This crate provides functionality for managing displays, surfaces, handle pointer movements, 5 | //! etc. - high level logic for drawing surfaces. 6 | 7 | extern crate rand; 8 | 9 | #[macro_use] 10 | extern crate timber; 11 | #[macro_use] 12 | extern crate cognitive_qualia as qualia; 13 | extern crate cognitive_outputs as outputs; 14 | extern crate cognitive_frames as frames; 15 | 16 | mod surface_history; 17 | pub use surface_history::SurfaceHistory; 18 | 19 | mod compositor; 20 | pub use compositor::Compositor; 21 | 22 | mod pointer; 23 | pub use pointer::Pointer; 24 | 25 | mod display; 26 | pub use display::Display; 27 | 28 | mod exhibitor; 29 | pub use exhibitor::Exhibitor; 30 | 31 | mod strategies; 32 | mod strategist; 33 | pub use strategist::Strategist; 34 | -------------------------------------------------------------------------------- /cognitive/exhibitor/tests/common/configurations.rs: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of 2 | // the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/ 3 | 4 | //! Default configurations for tests. 5 | 6 | use qualia::{CompositorConfig, StrategistConfig}; 7 | 8 | // ------------------------------------------------------------------------------------------------- 9 | 10 | pub fn compositor() -> CompositorConfig { 11 | CompositorConfig { 12 | move_step: 10, 13 | resize_step: 10, 14 | } 15 | } 16 | 17 | // ------------------------------------------------------------------------------------------------- 18 | 19 | pub fn strategist() -> StrategistConfig { 20 | StrategistConfig { 21 | choose_target: "always_floating".to_owned(), 22 | choose_floating: "random".to_owned(), 23 | } 24 | } 25 | 26 | // ------------------------------------------------------------------------------------------------- 27 | -------------------------------------------------------------------------------- /info/manual.perceptiactl.adoc: -------------------------------------------------------------------------------- 1 | = PERCEPTIACTL(1) 2 | :doctype: manpage 3 | 4 | == NAME 5 | 6 | perceptiactl - controls `perceptia` and provides useful information about system. 7 | 8 | == SYNOPSIS 9 | 10 | perceptiactl [] 11 | 12 | == DESCRIPTION 13 | 14 | `perceptiactl` - is simple helper and diagnostic tool for `perceptia` surface compositor. 15 | 16 | == COMMANDS 17 | 18 | about:: Prints information about `perceptia` 19 | help:: Prints general help or the help of the given subcommand(s) 20 | info:: Prints basic information about system 21 | screenshot:: Takes screenshot 22 | verify-config:: Verifies validity of configurations files(s) 23 | 24 | == ENVIRONMENT 25 | 26 | $XDG_CONFIG_HOME:: Directory for user configuration. 27 | 28 | == FILES 29 | 30 | $XDG_CONFIG_HOME/perceptia/*.{conf,yaml}:: User configuration files. 31 | 32 | /etc/perceptia/*.{conf,yaml}:: System configuration files. 33 | 34 | == BUGS 35 | 36 | Bugs should be reported to https://github.com/perceptia/perceptia/issues 37 | 38 | -------------------------------------------------------------------------------- /perceptia/coordination/lib.rs: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of 2 | // the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/ 3 | 4 | //! `coordination` keeps functionality related to memory shared between threads that requires 5 | //! synchronized access like buffers and related information for surfaces, screenshots or data 6 | //! transfers. 7 | //! 8 | //! TODO: Other crates should not use `coordination` directly but by traits provided by `qualia`. 9 | //! Ideally `coordination` should be merged with `perceptia` to prevent such use. 10 | 11 | extern crate dharma; 12 | extern crate cognitive_graphics; 13 | 14 | #[macro_use(timber)] 15 | extern crate timber; 16 | #[macro_use] 17 | extern crate cognitive_qualia as qualia; 18 | 19 | extern crate gears; 20 | 21 | mod surfaces; 22 | 23 | pub mod resource_storage; 24 | pub use resource_storage::ResourceStorage; 25 | 26 | pub mod coordinator; 27 | pub use coordinator::Coordinator; 28 | 29 | pub mod context; 30 | pub use context::Context; 31 | -------------------------------------------------------------------------------- /info/manual.perceptia.adoc: -------------------------------------------------------------------------------- 1 | = PERCEPTIA(1) 2 | :doctype: manpage 3 | 4 | == NAME 5 | 6 | perceptia - dynamic surface compositor with support for Wayland. 7 | 8 | == SYNOPSIS 9 | 10 | perceptia 11 | 12 | == DESCRIPTION 13 | 14 | `perceptia` is dynamic surface compositor with support for Wayland merging concepts from window 15 | managers like `i3`, `awesome`, `ratpoison`, `dwm` or `openbox`. `perceptia` is in very early stage 16 | of development. 17 | 18 | == ENVIRONMENT 19 | 20 | $XDG_RUNTIME_DIR:: Directory for runtime files. `perceptia` will create temporary directory in 21 | `$XDG_RUNTIME_DIR` for each instance. If variable not set it will default to `/tmp/`. 22 | 23 | $XDG_CACHE_HOME:: Directory for cache files. Currently used only for logs. 24 | 25 | $XDG_CONFIG_HOME:: Directory for user configuration. 26 | 27 | == FILES 28 | 29 | $XDG_CACHE_HOME/perceptia/*.log:: Log files. 30 | 31 | $XDG_CONFIG_HOME/perceptia/*.{conf,yaml}:: User configuration files. 32 | 33 | /etc/perceptia/*.{conf,yaml}:: System configuration files. 34 | 35 | == BUGS 36 | 37 | Bugs should be reported to https://github.com/perceptia/perceptia/issues 38 | 39 | -------------------------------------------------------------------------------- /info/license.mit.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of 4 | this software and associated documentation files (the "Software"), to deal in 5 | the Software without restriction, including without limitation the rights to 6 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 7 | of the Software, and to permit persons to whom the Software is furnished to do 8 | so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | SOFTWARE. 20 | -------------------------------------------------------------------------------- /cognitive/qualia/src/timing.rs: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of 2 | // the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/ 3 | 4 | //! This module contains functionality for storing time. 5 | 6 | use std::time::{Duration, Instant}; 7 | 8 | // ------------------------------------------------------------------------------------------------- 9 | 10 | /// This structure represents amount of time in milliseconds. 11 | #[derive(Clone, Copy, Debug, PartialEq, PartialOrd)] 12 | pub struct Milliseconds { 13 | ms: u64, 14 | } 15 | 16 | // ------------------------------------------------------------------------------------------------- 17 | 18 | impl Milliseconds { 19 | pub fn elapsed_from(instant: &Instant) -> Self { 20 | Self::from_duration(&instant.elapsed()) 21 | } 22 | 23 | pub fn from_duration(d: &Duration) -> Self { 24 | Milliseconds { ms: d.as_secs() * 1000 + d.subsec_nanos() as u64 / 1000000 } 25 | } 26 | 27 | pub fn get_value(&self) -> u64 { 28 | self.ms 29 | } 30 | } 31 | 32 | // ------------------------------------------------------------------------------------------------- 33 | -------------------------------------------------------------------------------- /cognitive/qualia/src/transfer.rs: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of 2 | // the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/ 3 | 4 | //! Data structures used for data transfers between clients (e.g. copy-paste). 5 | 6 | // ------------------------------------------------------------------------------------------------- 7 | 8 | /// Data related to transferring data. 9 | #[derive(Clone)] 10 | pub struct Transfer { 11 | pub mime_types: Vec, 12 | } 13 | 14 | // ------------------------------------------------------------------------------------------------- 15 | 16 | impl Transfer { 17 | /// Constructs new `Transfer`. 18 | pub fn new() -> Self { 19 | Transfer { mime_types: Vec::new() } 20 | } 21 | 22 | /// Adds offered mime type. 23 | pub fn add_mime_type(&mut self, mime_type: String) { 24 | self.mime_types.push(mime_type); 25 | } 26 | 27 | /// Returns list of all offered mime types. 28 | pub fn get_mime_types(&self) -> &Vec { 29 | &self.mime_types 30 | } 31 | } 32 | 33 | // ------------------------------------------------------------------------------------------------- 34 | -------------------------------------------------------------------------------- /perceptia/perceptiactl/verify_config.rs: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of 2 | // the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/ 3 | 4 | //! Verification to validity of configuration files. 5 | 6 | use qualia; 7 | use gears::Config; 8 | 9 | // ------------------------------------------------------------------------------------------------- 10 | 11 | pub fn process() { 12 | verify_config(); 13 | } 14 | 15 | // ------------------------------------------------------------------------------------------------- 16 | 17 | /// Verifies validity of configuration files. In case of success prints effective configuration. 18 | /// In case of failure prints error returned by parser. 19 | fn verify_config() { 20 | let env = qualia::env::Env::create(qualia::LogDestination::Disabled, "perceptia"); 21 | match Config::read(env.get_directories()) { 22 | Ok(config) => { 23 | println!("Config valid!"); 24 | println!("{}", config.serialize()); 25 | } 26 | Err(err) => println!("{}", err), 27 | } 28 | } 29 | 30 | // ------------------------------------------------------------------------------------------------- 31 | -------------------------------------------------------------------------------- /cognitive/device_manager/src/drivers.rs: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of 2 | // the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/ 3 | 4 | //! This module contains trait of device drivers. 5 | 6 | // ------------------------------------------------------------------------------------------------- 7 | 8 | use std::path::Path; 9 | use std::sync::{Arc, Mutex}; 10 | 11 | use qualia::{DeviceKind, Illusion, InputConfig, InputForwarding}; 12 | 13 | use device_access::RestrictedOpener; 14 | 15 | // ------------------------------------------------------------------------------------------------- 16 | 17 | /// Trait for input event devices like keyboard, mouse or touchpad. 18 | pub trait InputDriver { 19 | /// Initialize drive. Return driver instance on success or error otherwise. 20 | fn initialize_device(devnode: &Path, 21 | device_kind: DeviceKind, 22 | config: InputConfig, 23 | gateway: Arc>, 24 | ro: &RestrictedOpener) 25 | -> Result, Illusion>; 26 | } 27 | 28 | // ------------------------------------------------------------------------------------------------- 29 | -------------------------------------------------------------------------------- /cognitive/device_manager/src/lib.rs: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of 2 | // the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/ 3 | 4 | //! Provides device management functionality. 5 | 6 | #[macro_use] 7 | extern crate nix; 8 | extern crate libc; 9 | extern crate libudev_sys; 10 | extern crate libudev; 11 | extern crate egl; 12 | extern crate gbm_rs as libgbm; 13 | extern crate drm as libdrm; 14 | extern crate dbus; 15 | 16 | extern crate dharma; 17 | extern crate cognitive_graphics; 18 | 19 | #[macro_use] 20 | extern crate timber; 21 | #[macro_use] 22 | extern crate cognitive_qualia as qualia; 23 | extern crate cognitive_inputs as inputs; 24 | 25 | mod ipc; 26 | mod device_access; 27 | mod input_gateway; 28 | mod drivers; 29 | mod evdev_driver; 30 | mod pageflip; 31 | mod device_monitor; 32 | 33 | pub mod udev; 34 | pub use udev::Udev; 35 | 36 | mod input_collector; 37 | pub use input_collector::InputCollector; 38 | 39 | mod output_collector; 40 | pub use output_collector::OutputCollector; 41 | 42 | mod virtual_terminal; 43 | pub use virtual_terminal::VirtualTerminal; 44 | 45 | mod graphics_manager; 46 | pub use graphics_manager::GraphicsManager; 47 | 48 | pub mod device_manager; 49 | pub use device_manager::DeviceManager; 50 | -------------------------------------------------------------------------------- /cognitive/frames/tests/common/surface_listing_mock.rs: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of 2 | // the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/ 3 | 4 | //! This module contains mock for `SurfaceListing`. 5 | 6 | // ------------------------------------------------------------------------------------------------- 7 | 8 | use qualia::{Position, SurfaceContext, SurfaceId, SurfaceListing}; 9 | 10 | // ------------------------------------------------------------------------------------------------- 11 | 12 | /// Mock of `SurfaceListing`. 13 | pub struct SurfaceListingMock {} 14 | 15 | // ------------------------------------------------------------------------------------------------- 16 | 17 | impl SurfaceListingMock { 18 | pub fn new() -> Self { 19 | SurfaceListingMock {} 20 | } 21 | } 22 | 23 | // ------------------------------------------------------------------------------------------------- 24 | 25 | impl SurfaceListing for SurfaceListingMock { 26 | fn get_renderer_context(&self, sid: SurfaceId) -> Option> { 27 | Some(vec![SurfaceContext::new(sid, Position::default())]) 28 | } 29 | } 30 | 31 | // ------------------------------------------------------------------------------------------------- 32 | -------------------------------------------------------------------------------- /cognitive/cognitive/cognitive.rs: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of 2 | // the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/ 3 | 4 | //! Curate package for crates related to building display compositors or window managers. 5 | //! 6 | //! After crates reexported here mature they all will be moved to new repository. 7 | //! 8 | //! ## Documentation 9 | //! 10 | //! Links to sub-crates documentations: 11 | //! 12 | //! - [dharma](https://docs.rs/dharma) 13 | //! - [timber](https://docs.rs/timber) 14 | //! - [graphics](https://docs.rs/cognitive-graphics) 15 | //! - [qualia](https://docs.rs/cognitive-qualia) 16 | //! - [renderer-gl](https://docs.rs/cognitive-renderer-gl) 17 | //! - [inputs](https://docs.rs/cognitive-inputs) 18 | //! - [outputs](https://docs.rs/cognitive-outputs) 19 | //! - [device-manager](https://docs.rs/cognitive-device-manager) 20 | 21 | #![warn(missing_docs)] 22 | 23 | pub extern crate dharma; 24 | pub extern crate timber; 25 | pub extern crate cognitive_graphics as graphics; 26 | pub extern crate cognitive_qualia as qualia; 27 | pub extern crate cognitive_renderer_gl as renderer_gl; 28 | pub extern crate cognitive_inputs as inputs; 29 | pub extern crate cognitive_outputs as outputs; 30 | pub extern crate cognitive_device_manager as device_manager; 31 | -------------------------------------------------------------------------------- /cognitive/frames/tests/common/surface_access_mock.rs: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of 2 | // the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/ 3 | 4 | //! This module contains mock for `SurfaceAccess`. 5 | 6 | // ------------------------------------------------------------------------------------------------- 7 | 8 | use qualia::{SurfaceAccess, SurfaceId, Size, surface_state}; 9 | 10 | // ------------------------------------------------------------------------------------------------- 11 | 12 | /// Mock of `SurfaceAccess`. 13 | /// 14 | /// FIXME: Currently it is only stub. Test should be extended to also check `SurfaceAccess` 15 | /// functionality. 16 | pub struct SurfaceAccessMock {} 17 | 18 | // ------------------------------------------------------------------------------------------------- 19 | 20 | impl SurfaceAccessMock { 21 | pub fn new() -> Self { 22 | SurfaceAccessMock {} 23 | } 24 | } 25 | 26 | // ------------------------------------------------------------------------------------------------- 27 | 28 | impl SurfaceAccess for SurfaceAccessMock { 29 | fn reconfigure(&mut self, 30 | _sid: SurfaceId, 31 | _size: Size, 32 | _state_flags: surface_state::SurfaceState) { 33 | } 34 | } 35 | 36 | // ------------------------------------------------------------------------------------------------- 37 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [workspace] 2 | 3 | members = [ 4 | "cognitive/dharma", 5 | "cognitive/timber", 6 | "cognitive/graphics", 7 | "cognitive/qualia", 8 | "cognitive/renderer_gl", 9 | "cognitive/inputs", 10 | "cognitive/outputs", 11 | "cognitive/frames", 12 | "cognitive/aesthetics", 13 | "cognitive/device_manager", 14 | "cognitive/exhibitor", 15 | "cognitive/wayland_frontend", 16 | "cognitive/cognitive", 17 | 18 | "perceptia/gears", 19 | "perceptia/coordination", 20 | "perceptia/skylane_simple_framework", 21 | "perceptia/perceptia", 22 | "perceptia/perceptiactl", 23 | ] 24 | 25 | [replace] 26 | "dharma:0.1.0" = { path = 'cognitive/dharma' } 27 | "timber:0.1.0" = { path = 'cognitive/timber' } 28 | "cognitive-graphics:0.1.0" = { path = 'cognitive/graphics' } 29 | "cognitive-qualia:0.1.0" = { path = 'cognitive/qualia' } 30 | "cognitive-renderer-gl:0.1.0" = { path = 'cognitive/renderer_gl' } 31 | "cognitive-inputs:0.1.0" = { path = 'cognitive/inputs' } 32 | "cognitive-outputs:0.1.0" = { path = 'cognitive/outputs' } 33 | "cognitive-frames:0.1.0" = { path = 'cognitive/frames' } 34 | "cognitive-aesthetics:0.1.0" = { path = 'cognitive/aesthetics' } 35 | "cognitive-device-manager:0.1.0" = { path = 'cognitive/device_manager' } 36 | "cognitive-exhibitor:0.1.0" = { path = 'cognitive/exhibitor' } 37 | "cognitive-wayland-frontend:0.1.0" = { path = 'cognitive/wayland_frontend' } 38 | -------------------------------------------------------------------------------- /perceptia/skylane_simple_framework/src/protocol/mod.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2017 The Perceptia Project Developers 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software 4 | // and associated documentation files (the "Software"), to deal in the Software without 5 | // restriction, including without limitation the rights to use, copy, modify, merge, publish, 6 | // distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the 7 | // Software is furnished to do so, subject to the following conditions: 8 | // 9 | // The above copyright notice and this permission notice shall be included in all copies or 10 | // substantial portions of the Software. 11 | // 12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING 13 | // BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 14 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 15 | // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 16 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 17 | 18 | //! Implementation of handlers for Wayland protocol. 19 | 20 | pub mod display; 21 | pub mod callback; 22 | pub mod registry; 23 | 24 | pub mod output; 25 | pub mod shm; 26 | pub mod drm; 27 | pub mod linux_dmabuf_v1; 28 | 29 | pub mod compositor; 30 | pub mod shell; 31 | 32 | pub mod screenshooter; 33 | -------------------------------------------------------------------------------- /info/license.md: -------------------------------------------------------------------------------- 1 | License 2 | ======= 3 | 4 | Overview 5 | -------- 6 | 7 | Most source files (those with extension `.rs` or `.glsl`) are covered by Mozilla Public License 8 | version 2. Only those intended to be later published as crates are licensed on MIT license. 9 | 10 | For documentation or manuals (in particular for all files with extension `.md` and `.adoc`) any 11 | copyright is dedicated to the 12 | [Public Domain](http://creativecommons.org/publicdomain/zero/1.0/). 13 | 14 | Files describing Wayland protocols (`src/skylane_protocols/*.xml`) are borrowed from Wayland 15 | project. Original copyright applies to them (MIT license). 16 | 17 | For list of copyright holders, contributors and other credits see [authors.md](./authors.md). 18 | 19 | Rationale 20 | --------- 21 | 22 | MPL-2.0 was chosen as a license for source files because it is 23 | 24 | * popular and widely used or with strong community (according to 25 | [OSI](https://opensource.org/licenses/category)) 26 | 27 | * approved by FSF and OSI and compatible with GPL 28 | 29 | * file-level - does not impose itself on all files in repository 30 | 31 | * more business-friendly than GPL yet still copyleft 32 | 33 | References 34 | ---------- 35 | 36 | Full text of used or mentioned licenses should be provided along with this file. 37 | If not please refer to following links: 38 | [MPL-2.0](http://www.mozilla.org/MPL/2.0/), 39 | [MIT](https://opensource.org/licenses/MIT), 40 | [LGPL](https://www.gnu.org/licenses/lgpl.html), 41 | [GPL](https://www.gnu.org/licenses/gpl.html). 42 | 43 | -------------------------------------------------------------------------------- /cognitive/outputs/src/output.rs: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of 2 | // the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/ 3 | 4 | //! This module contains interface for all output devices or mocks. 5 | 6 | use qualia::{Buffer, Illusion, OutputInfo, Position, SurfaceContext, SurfaceViewer}; 7 | 8 | // ------------------------------------------------------------------------------------------------- 9 | 10 | /// `Output` is representation of physical output device. 11 | pub trait Output { 12 | /// Draws passed scene using renderer. 13 | fn draw(&mut self, 14 | layunder: &Vec, 15 | surfaces: &Vec, 16 | layover: &Vec, 17 | viewer: &SurfaceViewer) 18 | -> Result<(), Illusion>; 19 | 20 | /// Takes screenshot. Returns `Buffer` containing image data. 21 | fn take_screenshot(&self) -> Result; 22 | 23 | /// Returns info about output. 24 | fn get_info(&self) -> OutputInfo; 25 | 26 | /// Sets global position. 27 | fn set_position(&mut self, position: Position); 28 | 29 | /// Swaps buffers. 30 | fn swap_buffers(&mut self) -> Result; 31 | 32 | /// Schedules pageflip. Handler is registered by `DeviceManager`. 33 | fn schedule_pageflip(&self) -> Result<(), Illusion>; 34 | 35 | /// Reinitializes the output. 36 | fn recreate(&self) -> Result, Illusion>; 37 | } 38 | 39 | // ------------------------------------------------------------------------------------------------- 40 | -------------------------------------------------------------------------------- /info/installation.md: -------------------------------------------------------------------------------- 1 | Installation 2 | ============ 3 | 4 | Packages 5 | -------- 6 | 7 | Up to date list of downloads is available on [wiki downloads 8 | page](https://github.com/perceptia/perceptia/wiki/Downloads). 9 | 10 | Build 11 | ----- 12 | 13 | `perceptia` uses Rusts `cargo` package manager. To build `perceptia` run 14 | 15 | ``` 16 | cargo build --all --release 17 | ``` 18 | 19 | in repo root directory. Binaries will land in `target/release/`. You should be able to find there: 20 | 21 | * `perceptia` - the main display compositor 22 | * `perceptiactl` - helper diagnostic tool 23 | 24 | Dependences 25 | ----------- 26 | 27 | Required runtime dependencies: 28 | 29 | * libdbus 30 | * libdrm 31 | * libgbm 32 | * libgl, libegl 33 | * libinput 34 | * libudev 35 | * libxkbcommon 36 | 37 | Buildtime dependencies: 38 | 39 | * rustc 40 | * cargo 41 | 42 | Configuration 43 | ------------- 44 | 45 | Configuration is wider topic described in [configuration.md](./configuration.md). 46 | 47 | Run 48 | --- 49 | 50 | For GPU acceleration `perceptia` requires drivers which support KMS (Kernel Mode Setting). 51 | 52 | `perceptia` should be run as normal user. It will get access to required resources from `logind`. 53 | 54 | To run `perceptia` switch to Linux console e.g. using `ctrl+alt+F6` (make sure it's kernel console, 55 | not userspace console like `kmscon`). 56 | 57 | For list of options and environment variables you can refer to [manual page](./manual.adoc). 58 | 59 | Bugs 60 | ---- 61 | 62 | In case of **any** problems please make bug report in 63 | [bugtracker](https://github.com/perceptia/perceptia/issues). Providing logs will be helpful. They 64 | can be found in `$XDG_CACHE_HOME/perceptia/`. 65 | -------------------------------------------------------------------------------- /cognitive/wayland_frontend/src/global.rs: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of 2 | // the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/ 3 | 4 | //! This module contains functionality related to Wayland global objects. 5 | 6 | // ------------------------------------------------------------------------------------------------- 7 | 8 | use std::rc::Rc; 9 | 10 | use skylane::server as wl; 11 | 12 | use proxy::ProxyRef; 13 | 14 | // ------------------------------------------------------------------------------------------------- 15 | 16 | /// Type alias for constructor of Wayland global objects. 17 | type GlobalContructor = Fn(wl::ObjectId, u32, ProxyRef) -> Box; 18 | 19 | // ------------------------------------------------------------------------------------------------- 20 | 21 | /// Structure representing global Wayland object. 22 | // TODO: Define new type for name. 23 | #[derive(Clone)] 24 | pub struct Global { 25 | pub name: u32, 26 | pub interface: &'static str, 27 | pub version: u32, 28 | constructor: Rc, 29 | } 30 | 31 | // ------------------------------------------------------------------------------------------------- 32 | 33 | impl Global { 34 | pub fn new(interface: &'static str, version: u32, constructor: Rc) -> Self { 35 | Global { 36 | name: 0, 37 | interface: interface, 38 | version: version, 39 | constructor: constructor, 40 | } 41 | } 42 | 43 | pub fn construct(&self, id: wl::ObjectId, version: u32, proxy: ProxyRef) -> Box { 44 | (self.constructor)(id, version, proxy) 45 | } 46 | } 47 | 48 | // ------------------------------------------------------------------------------------------------- 49 | -------------------------------------------------------------------------------- /info/manifesto.md: -------------------------------------------------------------------------------- 1 | Perceptia Manifesto 2 | =================== 3 | 4 | The philosophy of `perceptia` is simplicity. **From simplicity comes power**. And this simplicity is 5 | going to be achieved from both user and developer perspective. 6 | 7 | User point of view 8 | ------------------ 9 | 10 | "Surface compositor" or "tilling window manager" may seem to be complicated concepts at first sight. 11 | While `perceptia` draws ideas from many tilling window managers and as such is meant for power 12 | users, its goal is actually to seamlessly introduce unexperienced user into tilling world. This is 13 | achieved by providing familiar settings from stacking window managers as default but putting all the 14 | other features in the range of sight. I hope `perceptia` will be simple enough for regular user but 15 | also become powerful tool in hands of experienced one while retaining all the simplicity. 16 | 17 | Developer point of view 18 | ----------------------- 19 | 20 | Code is meant to be clean. It is meant to be read and maintained. If it wasn't we would use 21 | assembler everywhere. Instead Rust - language focused on safety, speed, and concurrency - was 22 | chosen. Rust has simple, clean syntax and it helps to avoid many classes of problems. I might even 23 | say when using Rust good architecture pops up spontaneously. Once again: code is meant to be read so 24 | should be easy to understand - functions should be short and do one task, bigger parts should be 25 | solid and with well defined interface fit where needed - like blocks. And documentation! Lack of 26 | documentation is a bug! When every part of application has it own small task to do and it's know how 27 | this task fits in bigger structure - that is a good, simple design. 28 | 29 | Note that "simple" here does not mean "easy". "Simple" means "basing on or composed of some 30 | uncomplicated ideas". Such simple ideas can be then flexibly combined by user to solve the problem 31 | at hand. 32 | -------------------------------------------------------------------------------- /cognitive/qualia/src/settings.rs: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of 2 | // the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/ 3 | 4 | //! Various settings. 5 | 6 | // ------------------------------------------------------------------------------------------------- 7 | 8 | use std::sync::{Arc, RwLock}; 9 | use std::os::unix::io::RawFd; 10 | use std::path::PathBuf; 11 | 12 | // ------------------------------------------------------------------------------------------------- 13 | 14 | /// Set of paths to XDG directories. 15 | pub struct Directories { 16 | pub runtime: PathBuf, 17 | pub data: PathBuf, 18 | pub cache: PathBuf, 19 | pub user_config: Option, 20 | pub system_config: Option, 21 | } 22 | 23 | // ------------------------------------------------------------------------------------------------- 24 | 25 | /// Structure containing settings for key map. 26 | #[derive(Clone, Debug)] 27 | #[repr(C)] 28 | pub struct KeymapSettings { 29 | pub format: u32, 30 | pub size: usize, 31 | pub fd: RawFd, 32 | } 33 | 34 | // ------------------------------------------------------------------------------------------------- 35 | 36 | /// Global settings. 37 | #[derive(Clone)] 38 | pub struct Settings { 39 | keymap: Arc>, 40 | } 41 | 42 | // ------------------------------------------------------------------------------------------------- 43 | 44 | impl Settings { 45 | /// `Settings` constructor. 46 | pub fn new(keymap: KeymapSettings) -> Self { 47 | Settings { keymap: Arc::new(RwLock::new(keymap)) } 48 | } 49 | 50 | /// Get key map related settings. 51 | pub fn get_keymap(&self) -> KeymapSettings { 52 | self.keymap.read().unwrap().clone() 53 | } 54 | } 55 | 56 | // ------------------------------------------------------------------------------------------------- 57 | -------------------------------------------------------------------------------- /cognitive/graphics/src/errors.rs: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of 2 | // the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/ 3 | 4 | //! This module provides error enumerations. 5 | 6 | // ------------------------------------------------------------------------------------------------- 7 | 8 | use std; 9 | use std::error::Error; 10 | 11 | // ------------------------------------------------------------------------------------------------- 12 | 13 | /// Graphics errors. 14 | pub struct GraphicsError { 15 | /// Description. 16 | description: String, 17 | } 18 | 19 | // ------------------------------------------------------------------------------------------------- 20 | 21 | impl GraphicsError { 22 | /// Constructs new `GraphicsError` with description. 23 | pub fn new(description: String) -> GraphicsError { 24 | GraphicsError { description: description } 25 | } 26 | } 27 | 28 | // ------------------------------------------------------------------------------------------------- 29 | 30 | impl Error for GraphicsError { 31 | fn description(&self) -> &str { 32 | &self.description 33 | } 34 | 35 | fn cause(&self) -> Option<&Error> { 36 | None 37 | } 38 | } 39 | 40 | // ------------------------------------------------------------------------------------------------- 41 | 42 | impl std::fmt::Debug for GraphicsError { 43 | fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { 44 | write!(f, "{}", self.description) 45 | } 46 | } 47 | 48 | // ------------------------------------------------------------------------------------------------- 49 | 50 | impl std::fmt::Display for GraphicsError { 51 | fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { 52 | write!(f, "{}", self.description) 53 | } 54 | } 55 | 56 | // ------------------------------------------------------------------------------------------------- 57 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Perceptia 2 | ========= 3 | 4 | Do you like configurability and lightweightness of tiling window managers? Do you like cutting-edge 5 | technology and want to try a tiling window manager running on Wayland? `perceptia` is for you! 6 | `perceptia` tries to merge concepts from most popular tiling window managers like `i3`, `awesome`, 7 | `ratpoison` or `dwm` with the freshness of Wayland. 8 | 9 | For main objectives of the project see [the Perceptia Manifesto](./info/manifesto.md). 10 | 11 | Status 12 | ------ 13 | 14 | There are still many things to work on. If you are looking for a working compositor it is a bit too 15 | early to choose `perceptia`, but if you have programming skills and want to join the development team, your help will be appreciated. 16 | 17 | Backbone of every project is community. User input is especially valuable for young projects. It is 18 | the users that shape what the project will later become. Please go to 19 | [github](https://github.com/perceptia/perceptia/issues) and vote for features you want to see in 20 | `perceptia` or share your own ideas. Your input will help to decide which features should be 21 | implemented first and how they should be designed. 22 | 23 | This repository consists of: 24 | 25 | * `cognitive` - a loose set of (Rust) crates helping creating surface compositors or other low 26 | level graphic applications 27 | 28 | * `perceptia` - a dynamic (tilling or stacking) Wayland surface compositor basing on `cognitive`. 29 | 30 | Getting Started 31 | --------------- 32 | 33 | For instructions on building and running `perceptia` see [installation.md](./info/installation.md). 34 | 35 | For configuration options see [configuration.md](./info/configuration.md). 36 | 37 | If you want to see features from your favourite window manager in `perceptia` you are encouraged to 38 | contribute in brain-storming and development. For details see 39 | [contributing.md](./info/contributing.md). 40 | 41 | Contact via mailing list `perceptia@freelists.org` or directly with [authors](./info/authors.md). 42 | 43 | `perceptia` is licensed on `MPL-2.0`. For more information see [license.md](./info/license.md). 44 | -------------------------------------------------------------------------------- /perceptia/perceptiactl/perceptiactl.rs: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of 2 | // the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/ 3 | 4 | //! Controls `perceptia` and provides useful information about system. 5 | 6 | extern crate clap; 7 | extern crate nix; 8 | extern crate egl; 9 | extern crate gl; 10 | extern crate libudev; 11 | extern crate drm as libdrm; 12 | extern crate image; 13 | 14 | extern crate timber; 15 | extern crate cognitive_graphics as graphics; 16 | extern crate cognitive_qualia as qualia; 17 | extern crate cognitive_device_manager as device_manager; 18 | 19 | extern crate gears; 20 | extern crate skylane_simple_framework; 21 | 22 | mod info; 23 | mod about; 24 | mod screenshot; 25 | mod verify_config; 26 | 27 | fn main() { 28 | timber::init(std::path::Path::new("/dev/null")).unwrap(); 29 | 30 | let matches = clap::App::new("perceptiactl") 31 | .setting(clap::AppSettings::SubcommandRequired) 32 | .version("0.0.1") 33 | .author("Wojciech Kluczka ") 34 | .about("Controller for Perceptia") 35 | .subcommand(clap::SubCommand::with_name("info") 36 | .about("Prints basic information about system.")) 37 | .subcommand(clap::SubCommand::with_name("about") 38 | .about("Prints information about this program.")) 39 | .subcommand(clap::SubCommand::with_name("screenshot") 40 | .about("Takes screenshot")) 41 | .subcommand(clap::SubCommand::with_name("verify-config") 42 | .about("Verifies validity of configurations files(s)")) 43 | .get_matches(); 44 | 45 | match matches.subcommand() { 46 | ("info", Some(_)) => { 47 | info::process(); 48 | } 49 | ("about", Some(_)) => { 50 | about::process(); 51 | } 52 | ("screenshot", Some(_)) => { 53 | screenshot::process(); 54 | } 55 | ("verify-config", Some(_)) => { 56 | verify_config::process(); 57 | } 58 | _ => println!("Error during parsing arguments!"), 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /cognitive/wayland_frontend/src/protocol/weston_screenshooter.rs: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of 2 | // the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/ 3 | 4 | //! Implementations of Weston `weston_screenshooter` object. 5 | 6 | use std::rc::Rc; 7 | 8 | use skylane::server::{Bundle, Object, ObjectId, Task}; 9 | use skylane_protocols::server::Handler; 10 | use skylane_protocols::server::weston_screenshooter::weston_screenshooter; 11 | 12 | use facade::Facade; 13 | use global::Global; 14 | use proxy::ProxyRef; 15 | 16 | // ------------------------------------------------------------------------------------------------- 17 | 18 | /// Weston `weston_screenshooter` object. 19 | struct Screenshooter { 20 | proxy: ProxyRef, 21 | } 22 | 23 | // ------------------------------------------------------------------------------------------------- 24 | 25 | pub fn get_global() -> Global { 26 | Global::new(weston_screenshooter::NAME, 27 | weston_screenshooter::VERSION, 28 | Rc::new(Screenshooter::new_object)) 29 | } 30 | 31 | // ------------------------------------------------------------------------------------------------- 32 | 33 | impl Screenshooter { 34 | fn new(proxy_ref: ProxyRef) -> Self { 35 | Screenshooter { proxy: proxy_ref } 36 | } 37 | 38 | fn new_object(_oid: ObjectId, _version: u32, proxy_ref: ProxyRef) -> Box { 39 | Box::new(Handler::<_, weston_screenshooter::Dispatcher>::new(Self::new(proxy_ref))) 40 | } 41 | } 42 | 43 | // ------------------------------------------------------------------------------------------------- 44 | 45 | impl weston_screenshooter::Interface for Screenshooter { 46 | fn shoot(&mut self, 47 | this_object_id: ObjectId, 48 | _bundle: &mut Bundle, 49 | output: ObjectId, 50 | buffer: ObjectId) 51 | -> Task { 52 | self.proxy.borrow_mut().take_screenshot(this_object_id, output, buffer); 53 | Task::None 54 | } 55 | } 56 | 57 | // ------------------------------------------------------------------------------------------------- 58 | -------------------------------------------------------------------------------- /perceptia/skylane_simple_framework/src/lib.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2017 The Perceptia Project Developers 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software 4 | // and associated documentation files (the "Software"), to deal in the Software without 5 | // restriction, including without limitation the rights to use, copy, modify, merge, publish, 6 | // distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the 7 | // Software is furnished to do so, subject to the following conditions: 8 | // 9 | // The above copyright notice and this permission notice shall be included in all copies or 10 | // substantial portions of the Software. 11 | // 12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING 13 | // BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 14 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 15 | // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 16 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 17 | 18 | //! This is simple frame framework demonstrating how `skylane` crate could be used to implement 19 | //! Wayland framework. 20 | //! 21 | //! This crate is used by `perceptiactl` for taking screenshots. 22 | 23 | extern crate nix; 24 | extern crate gl; 25 | extern crate egl; 26 | extern crate gbm_rs as libgbm; 27 | extern crate drm as libdrm; 28 | 29 | extern crate skylane; 30 | extern crate skylane_protocols; 31 | 32 | extern crate dharma; 33 | extern crate cognitive_graphics; 34 | 35 | // TODO: Remove dependency from `qualia` and `timber` from `skylane_simple_framework`. 36 | #[macro_use] 37 | extern crate timber; 38 | #[macro_use] 39 | extern crate cognitive_qualia as qualia; 40 | 41 | #[macro_use] 42 | mod defs; 43 | pub use defs::OutputInfo; 44 | 45 | mod store; 46 | mod event_handler; 47 | 48 | mod listener; 49 | pub use listener::{Listener, ListenerConstructor}; 50 | 51 | mod protocol; 52 | mod common; 53 | 54 | mod controller; 55 | pub use controller::Controller; 56 | 57 | mod proxy; 58 | 59 | mod application; 60 | pub use application::Application; 61 | -------------------------------------------------------------------------------- /cognitive/wayland_frontend/src/protocol/display.rs: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of 2 | // the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/ 3 | 4 | //! Implementation of Wayland `wl_display` object. 5 | 6 | use skylane::server::{Bundle, Object, ObjectId, Task}; 7 | use skylane_protocols::server::Handler; 8 | use skylane_protocols::server::wayland::wl_display; 9 | use skylane_protocols::server::wayland::wl_callback; 10 | 11 | use proxy::ProxyRef; 12 | use protocol::registry::Registry; 13 | 14 | // ------------------------------------------------------------------------------------------------- 15 | 16 | /// Wayland `wl_display` object. 17 | pub struct Display { 18 | proxy: ProxyRef, 19 | } 20 | 21 | // ------------------------------------------------------------------------------------------------- 22 | 23 | impl Display { 24 | fn new(proxy: ProxyRef) -> Self { 25 | Display { proxy: proxy } 26 | } 27 | 28 | pub fn new_object(proxy_ref: ProxyRef) -> Box { 29 | Box::new(Handler::<_, wl_display::Dispatcher>::new(Self::new(proxy_ref))) 30 | } 31 | } 32 | 33 | // ------------------------------------------------------------------------------------------------- 34 | 35 | impl wl_display::Interface for Display { 36 | fn sync(&mut self, this_object_id: ObjectId, bundle: &mut Bundle, callback: ObjectId) -> Task { 37 | let serial = bundle.get_socket().get_next_serial(); 38 | send!(wl_callback::done(&bundle.get_socket(), callback, serial)); 39 | send!(wl_display::delete_id(&bundle.get_socket(), this_object_id, callback.get_value())); 40 | Task::None 41 | } 42 | 43 | fn get_registry(&mut self, 44 | _this_object_id: ObjectId, 45 | _bundle: &mut Bundle, 46 | new_registry_id: ObjectId) 47 | -> Task { 48 | let registry = Registry::new_object(new_registry_id, self.proxy.clone()); 49 | Task::Create { 50 | id: new_registry_id, 51 | object: registry, 52 | } 53 | } 54 | } 55 | 56 | // ------------------------------------------------------------------------------------------------- 57 | -------------------------------------------------------------------------------- /cognitive/dharma/src/timer.rs: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of 2 | // the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/ 3 | 4 | //! This module contains helper functionality for handling system signals. 5 | 6 | // ------------------------------------------------------------------------------------------------- 7 | 8 | use std::os::unix::io::{RawFd, AsRawFd}; 9 | use std::time::Duration; 10 | 11 | use timerfd::{TimerFd, TimerState}; 12 | 13 | use dispatcher::{EventHandler, EventKind, event_kind}; 14 | 15 | // ------------------------------------------------------------------------------------------------- 16 | 17 | /// General purpose timer implementing `EventHandler`. 18 | pub struct Timer 19 | where F: FnMut() -> () 20 | { 21 | /// Callback function called every time timer expires. 22 | callback: F, 23 | 24 | /// TimerFd. 25 | timer_fd: TimerFd, 26 | } 27 | 28 | // ------------------------------------------------------------------------------------------------- 29 | 30 | impl Timer 31 | where F: FnMut() -> () 32 | { 33 | /// Constructs new `Timer` expiring periodically with given interval and calling given 34 | /// `callback`. 35 | pub fn new(interval: Duration, callback: F) -> Result { 36 | if let Ok(mut timer_fd) = TimerFd::new_custom(false, true, true) { 37 | timer_fd.set_state(TimerState::Periodic { 38 | current: interval, 39 | interval: interval, 40 | }); 41 | Ok(Timer { 42 | callback: callback, 43 | timer_fd: timer_fd, 44 | }) 45 | } else { 46 | Err(()) 47 | } 48 | } 49 | } 50 | 51 | // ------------------------------------------------------------------------------------------------- 52 | 53 | impl EventHandler for Timer 54 | where F: FnMut() -> () 55 | { 56 | fn get_fd(&self) -> RawFd { 57 | self.timer_fd.as_raw_fd() 58 | } 59 | 60 | fn process_event(&mut self, event_kind: EventKind) { 61 | if event_kind.intersects(event_kind::READ) { 62 | self.timer_fd.read(); 63 | (self.callback)(); 64 | } 65 | } 66 | } 67 | 68 | // ------------------------------------------------------------------------------------------------- 69 | -------------------------------------------------------------------------------- /cognitive/graphics/src/gbm_tools.rs: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of 2 | // the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/ 3 | 4 | //! This module contains common GBM-related tools. 5 | 6 | // ------------------------------------------------------------------------------------------------- 7 | 8 | use std::os::unix::io::RawFd; 9 | use libgbm; 10 | 11 | use errors::GraphicsError; 12 | 13 | // ------------------------------------------------------------------------------------------------- 14 | 15 | /// This structure collects GBM-related data. 16 | pub struct GbmBucket { 17 | /// GBM device. 18 | pub device: libgbm::Device, 19 | 20 | /// GBM surface. 21 | pub surface: libgbm::Surface, 22 | } 23 | 24 | // ------------------------------------------------------------------------------------------------- 25 | 26 | /// Helper function for getting device. 27 | pub fn get_device(fd: RawFd) -> Result { 28 | if let Some(device) = libgbm::Device::from_fd(fd) { 29 | Ok(device) 30 | } else { 31 | Err(GraphicsError::new(format!("Failed to create GBM device"))) 32 | } 33 | } 34 | // ------------------------------------------------------------------------------------------------- 35 | 36 | impl GbmBucket { 37 | /// `GbmBucket` constructor. 38 | pub fn new(fd: RawFd, width: u32, height: u32) -> Result { 39 | // Create device 40 | let device = self::get_device(fd)?; 41 | 42 | // Create surface 43 | let surface = if let Some(surface) = libgbm::Surface::new(&device, 44 | width, 45 | height, 46 | libgbm::format::XRGB8888, 47 | libgbm::USE_SCANOUT | 48 | libgbm::USE_RENDERING) { 49 | surface 50 | } else { 51 | return Err(GraphicsError::new(format!("Failed to create GBM surface"))); 52 | }; 53 | 54 | 55 | Ok(GbmBucket { 56 | device: device, 57 | surface: surface, 58 | }) 59 | } 60 | } 61 | 62 | // ------------------------------------------------------------------------------------------------- 63 | -------------------------------------------------------------------------------- /cognitive/frames/src/lib.rs: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of 2 | // the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/ 3 | 4 | //! Defines data structures and functionality used to build and manipulate space-like and time-like 5 | //! relations between surfaces. 6 | //! 7 | //! ## Structure 8 | //! 9 | //! Frames are organized in tree-like structure with one root. Children of every branch have two 10 | //! orders: 11 | //! 12 | //! - *time-like* - describing the order of use of frames in given branch 13 | //! - *space-like* - describing placement order as drawn on screen 14 | //! 15 | //! ## Manipulations 16 | //! 17 | //! Basic manipulation in the tree is to *append*, *prepend* or *join* frames in spatial order. 18 | //! Using these manipulations added frame always becomes last in time order. To become first in 19 | //! time order the frame must be *pop*-ed. 20 | //! 21 | //! ## Extensions 22 | //! 23 | //! Extensions to basic functionality are implemented by traits first to clearly separate 24 | //! functionalities, secondly to make files shorter by breaking code to different modules. 25 | //! 26 | //! - `searching` - gives more advance or common ways to find specified frames 27 | //! - `settle` - implements common ways of adding or moving frames 28 | //! 29 | //! ## Implementation 30 | //! 31 | //! Frame tree is cyclic graph with each node optionally pointing to: 32 | //! 33 | //! - parent 34 | //! - next sibling in time order 35 | //! - previous sibling in time order 36 | //! - first child in time order 37 | //! - last child in time order 38 | //! - next sibling in space order 39 | //! - previous sibling in space order 40 | //! - first child in space order 41 | //! - last child in space order 42 | //! 43 | //! Current implementation uses unsafe raw pointers. This make implementation faster and simpler 44 | //! than with other more idiomatic ways, but loses Rusts guaranties. Runtime safety is ensured by 45 | //! unit tests. 46 | 47 | extern crate cognitive_qualia as qualia; 48 | 49 | mod frame; 50 | pub use frame::{Frame, FrameSpaceIterator, FrameTimeIterator, Side, Parameters}; 51 | pub use frame::{Geometry, Mobility, Mode}; 52 | 53 | mod converting; 54 | pub use converting::Converting; 55 | 56 | mod packing; 57 | pub use packing::Packing; 58 | 59 | mod searching; 60 | pub use searching::Searching; 61 | 62 | mod settling; 63 | pub use settling::Settling; 64 | 65 | #[cfg(feature = "testing")] 66 | pub mod representation; 67 | -------------------------------------------------------------------------------- /perceptia/skylane_simple_framework/src/protocol/screenshooter.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2017 The Perceptia Project Developers 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software 4 | // and associated documentation files (the "Software"), to deal in the Software without 5 | // restriction, including without limitation the rights to use, copy, modify, merge, publish, 6 | // distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the 7 | // Software is furnished to do so, subject to the following conditions: 8 | // 9 | // The above copyright notice and this permission notice shall be included in all copies or 10 | // substantial portions of the Software. 11 | // 12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING 13 | // BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 14 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 15 | // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 16 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 17 | 18 | //! Implementation of Wayland `weston_screenshooter` object. 19 | 20 | use skylane::client::{Bundle, Object, ObjectId, Task}; 21 | use skylane_protocols::client::Handler; 22 | use skylane_protocols::client::weston_screenshooter::weston_screenshooter; 23 | 24 | use proxy::ProxyRef; 25 | 26 | // ------------------------------------------------------------------------------------------------- 27 | 28 | /// Weston `weston_screenshooter` object. 29 | pub struct Screenshooter { 30 | proxy: ProxyRef, 31 | } 32 | 33 | // ------------------------------------------------------------------------------------------------- 34 | 35 | impl Screenshooter { 36 | fn new(proxy: ProxyRef) -> Self { 37 | Screenshooter { proxy: proxy } 38 | } 39 | 40 | pub fn new_object(proxy: ProxyRef) -> Box { 41 | Box::new(Handler::<_, weston_screenshooter::Dispatcher>::new(Self::new(proxy))) 42 | } 43 | } 44 | 45 | // ------------------------------------------------------------------------------------------------- 46 | 47 | impl weston_screenshooter::Interface for Screenshooter { 48 | fn done(&mut self, _this_object_id: ObjectId, _bundle: &mut Bundle) -> Task { 49 | self.proxy.borrow_mut().screenshot_done(); 50 | Task::None 51 | } 52 | } 53 | 54 | // ------------------------------------------------------------------------------------------------- 55 | -------------------------------------------------------------------------------- /cognitive/wayland_frontend/src/lib.rs: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of 2 | // the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/ 3 | 4 | //! This crate implements Wayland functionality. 5 | //! 6 | //! # Sketch of architecture 7 | //! 8 | //! The piece of code running all the business is `Engine`. It sets up everything and handles 9 | //! requests from clients as well as the rests of application. Upon client connection `Engine` 10 | //! creates new 11 | //! 12 | //! - `skylane::Client`, structure registering handlers (representing Wayland objects) and 13 | //! dispatching client requests to them and 14 | //! - `wayland_frontend::Proxy`, structure used for sharing information between handlers, a state 15 | //! of client. 16 | //! 17 | //! `Proxy` is shared between handlers as `RefCell`. 18 | //! 19 | //! Two interfaces were introduced: 20 | //! 21 | //! - `Facade`, for requests from clients (downward?) which is implemented by `Proxy` and 22 | //! - `Gateway`, for requests from application (upward?) which is implemented by `Engine` 23 | //! (dispatching request to correct `Proxy`s) and `Proxy` (making actual request to client). 24 | //! 25 | //! So one `Engine` holds many `Client`s holding many (cell) references to `Proxy`, but at some 26 | //! point `Engine` must be informed that client created surface. For this purpose `Engine` and all 27 | //! `Proxy`s hold (cell) reference to single `Mediator`. 28 | //! 29 | //! Details of threading are left for application. `wayland_frontend` may be configured to receive 30 | //! in one thread and send in other or do everything in one thread. What is however sure accepting 31 | //! new client can not be done in `DisplayEventHandler` and handling requests can not be done in 32 | //! `ClientEventHandler` as it may require mutating `dharma::Dispatcher`, so handling is decoupled 33 | //! from processing using `dharma::DirectSender`. 34 | 35 | // TODO: Move common DRM functionality to module. 36 | extern crate drm as libdrm; 37 | extern crate nix; 38 | 39 | extern crate skylane; 40 | extern crate skylane_protocols; 41 | 42 | extern crate dharma; 43 | extern crate cognitive_graphics; 44 | 45 | #[macro_use] 46 | extern crate timber; 47 | #[macro_use] 48 | extern crate cognitive_qualia as qualia; 49 | extern crate cognitive_inputs as inputs; 50 | 51 | pub mod constants; 52 | 53 | #[macro_use] 54 | mod macros; 55 | mod mediator; 56 | mod global; 57 | mod facade; 58 | mod gateway; 59 | mod proxy; 60 | mod event_handlers; 61 | 62 | mod protocol; 63 | 64 | pub mod engine; 65 | 66 | pub use engine::Engine; 67 | pub use gateway::Gateway; 68 | -------------------------------------------------------------------------------- /cognitive/outputs/src/output_mock.rs: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of 2 | // the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/ 3 | 4 | //! This module contains mock for `Output`. 5 | 6 | use std::cell::RefCell; 7 | use std::rc::Rc; 8 | 9 | use qualia::{Buffer, Illusion, OutputInfo, Position, SurfaceContext, SurfaceViewer}; 10 | 11 | use output::Output; 12 | 13 | // ------------------------------------------------------------------------------------------------- 14 | 15 | /// Mock of `Output`. 16 | pub struct InnerOutputMock { 17 | info: OutputInfo, 18 | } 19 | 20 | // ------------------------------------------------------------------------------------------------- 21 | 22 | impl InnerOutputMock { 23 | pub fn new(info: OutputInfo) -> Self { 24 | InnerOutputMock { info: info } 25 | } 26 | } 27 | 28 | // ------------------------------------------------------------------------------------------------- 29 | 30 | /// Mock of `Output`. 31 | #[derive(Clone)] 32 | pub struct OutputMock { 33 | mock: Rc>, 34 | } 35 | 36 | // ------------------------------------------------------------------------------------------------- 37 | 38 | impl OutputMock { 39 | pub fn new(info: OutputInfo) -> Self { 40 | OutputMock { mock: Rc::new(RefCell::new(InnerOutputMock::new(info))) } 41 | } 42 | } 43 | 44 | // ------------------------------------------------------------------------------------------------- 45 | 46 | #[allow(unused_variables)] 47 | impl Output for OutputMock { 48 | fn draw(&mut self, 49 | layunder: &Vec, 50 | surfaces: &Vec, 51 | layover: &Vec, 52 | viewer: &SurfaceViewer) 53 | -> Result<(), Illusion> { 54 | Ok(()) 55 | } 56 | 57 | fn take_screenshot(&self) -> Result { 58 | panic!("Taking screenshot not supported in unit test"); 59 | } 60 | 61 | fn get_info(&self) -> OutputInfo { 62 | let mine = self.mock.borrow(); 63 | mine.info.clone() 64 | } 65 | 66 | fn set_position(&mut self, _position: Position) {} 67 | 68 | fn swap_buffers(&mut self) -> Result { 69 | Ok(u32::default()) 70 | } 71 | 72 | fn schedule_pageflip(&self) -> Result<(), Illusion> { 73 | Ok(()) 74 | } 75 | 76 | fn recreate(&self) -> Result, Illusion> { 77 | panic!("Recreating not supported in unit test"); 78 | } 79 | } 80 | 81 | // ------------------------------------------------------------------------------------------------- 82 | -------------------------------------------------------------------------------- /perceptia/skylane_simple_framework/src/defs.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2017 The Perceptia Project Developers 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software 4 | // and associated documentation files (the "Software"), to deal in the Software without 5 | // restriction, including without limitation the rights to use, copy, modify, merge, publish, 6 | // distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the 7 | // Software is furnished to do so, subject to the following conditions: 8 | // 9 | // The above copyright notice and this permission notice shall be included in all copies or 10 | // substantial portions of the Software. 11 | // 12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING 13 | // BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 14 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 15 | // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 16 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 17 | 18 | //! Various definitions used around `skylane_simple_framework`. 19 | 20 | // ------------------------------------------------------------------------------------------------- 21 | 22 | #[derive(Clone, Debug)] 23 | pub struct OutputInfo { 24 | pub x: isize, 25 | pub y: isize, 26 | pub width: usize, 27 | pub height: usize, 28 | pub make: String, 29 | pub model: String, 30 | pub id: u32, 31 | } 32 | 33 | // ------------------------------------------------------------------------------------------------- 34 | 35 | impl OutputInfo { 36 | /// Constructs new `OutputInfo`. 37 | pub fn new(x: isize, 38 | y: isize, 39 | width: usize, 40 | height: usize, 41 | make: String, 42 | model: String, 43 | id: u32) 44 | -> Self { 45 | OutputInfo { 46 | x: x, 47 | y: y, 48 | width: width, 49 | height: height, 50 | make: make, 51 | model: model, 52 | id: id, 53 | } 54 | } 55 | } 56 | 57 | // ------------------------------------------------------------------------------------------------- 58 | 59 | /// This macro executes passed expression and in case of error logs warning about failing to send 60 | /// data. It is intended to use when posting `skylane` requests to server. 61 | #[macro_export] 62 | macro_rules! send { 63 | {$command:expr} => { 64 | ($command).expect("Sending message to display server"); 65 | } 66 | } 67 | 68 | // ------------------------------------------------------------------------------------------------- 69 | -------------------------------------------------------------------------------- /perceptia/gears/functions.rs: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of 2 | // the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/ 3 | 4 | //! This module contains global functions. 5 | 6 | // ------------------------------------------------------------------------------------------------- 7 | 8 | use libc; 9 | use std; 10 | 11 | use qualia; 12 | 13 | // ------------------------------------------------------------------------------------------------- 14 | 15 | const UNKNOWN_MESSAGE: &'static str = ""; 16 | 17 | // ------------------------------------------------------------------------------------------------- 18 | 19 | /// Shuts down the application by sending `SIGTERM` to itself. 20 | pub fn quit() { 21 | log_info1!("QUIT!"); 22 | unsafe { libc::kill(libc::getpid(), libc::SIGTERM) }; 23 | } 24 | 25 | // ------------------------------------------------------------------------------------------------- 26 | 27 | /// Hook function for panics. 28 | /// 29 | /// Logs panic message and location and quits application. 30 | pub fn panic_hook(info: &std::panic::PanicInfo) { 31 | // Retrieve payload 32 | let payload = info.payload(); 33 | let message: String = if std::any::Any::is::(payload) { 34 | if let Some(message) = payload.downcast_ref::() { 35 | message.clone() 36 | } else { 37 | UNKNOWN_MESSAGE.to_owned() 38 | } 39 | } else if std::any::Any::is::<&str>(payload) { 40 | if let Some(message) = payload.downcast_ref::<&str>() { 41 | message.to_string() 42 | } else { 43 | UNKNOWN_MESSAGE.to_owned() 44 | } 45 | } else { 46 | UNKNOWN_MESSAGE.to_owned() 47 | }; 48 | 49 | // Log panic 50 | log_error!("One of threads panicked with message '{}'", message); 51 | if let Some(location) = info.location() { 52 | log_error!("Panic occurred in line {}, file '{}'", location.line(), location.file()); 53 | qualia::log::backtrace(); 54 | } 55 | 56 | // Quit application 57 | quit(); 58 | } 59 | 60 | // ------------------------------------------------------------------------------------------------- 61 | 62 | /// Spawns new process. 63 | pub fn spawn_process(command: &Vec) { 64 | if command.len() > 0 { 65 | let mut builder = std::process::Command::new(&command[0]); 66 | for arg in command.iter().skip(1) { 67 | builder.arg(&arg); 68 | } 69 | match builder.spawn() { 70 | Ok(_) => log_info1!("Spawned '{}' process", command[0]), 71 | Err(err) => log_error!("Failed to spawn process ({:?}): {}", command, err), 72 | } 73 | } 74 | } 75 | 76 | // ------------------------------------------------------------------------------------------------- 77 | -------------------------------------------------------------------------------- /cognitive/wayland_frontend/src/gateway.rs: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of 2 | // the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/ 3 | 4 | //! This module provides interface for requests from the rest of application to clients. 5 | 6 | // ------------------------------------------------------------------------------------------------- 7 | 8 | use std::os::unix::io::RawFd; 9 | 10 | use qualia::{Axis, Button, DrmBundle, Key, Milliseconds, OutputInfo, Position, Size}; 11 | use qualia::{SurfaceId, surface_state}; 12 | use inputs::KeyMods; 13 | 14 | // ------------------------------------------------------------------------------------------------- 15 | 16 | pub trait Gateway { 17 | /// Notifies output was found. 18 | fn on_output_found(&mut self, bundle: DrmBundle); 19 | 20 | /// Notifies display was created. 21 | fn on_display_created(&mut self, output_info: OutputInfo); 22 | 23 | /// Notifies keyboard key was pressed. 24 | fn on_keyboard_input(&mut self, key: Key, mods: Option); 25 | 26 | /// Notifies about redrawing surface. 27 | fn on_surface_frame(&mut self, sid: SurfaceId, milliseconds: Milliseconds); 28 | 29 | /// Notifies that pointer was moved from above one surface above another. 30 | fn on_pointer_focus_changed(&self, 31 | old_sid: SurfaceId, 32 | new_sid: SurfaceId, 33 | position: Position); 34 | 35 | /// Notifies that pointer moved. 36 | fn on_pointer_relative_motion(&self, 37 | sid: SurfaceId, 38 | position: Position, 39 | milliseconds: Milliseconds); 40 | 41 | /// Notifies mouse or touchpad button was pressed. 42 | fn on_pointer_button(&self, btn: Button); 43 | 44 | /// Notifies about pointer move. 45 | fn on_pointer_axis(&self, axis: Axis); 46 | 47 | /// Notifies about keyboard focus change. 48 | fn on_keyboard_focus_changed(&mut self, old_sid: SurfaceId, new_sid: SurfaceId); 49 | 50 | /// Handles change of offered transfer data. 51 | fn on_transfer_offered(&mut self); 52 | 53 | /// Handles data transfer request to requesting client. 54 | fn on_transfer_requested(&mut self, mime_type: String, fd: RawFd); 55 | 56 | /// Notifies about change of size or state of surface. 57 | fn on_surface_reconfigured(&self, 58 | sid: SurfaceId, 59 | size: Size, 60 | state_flags: surface_state::SurfaceState); 61 | 62 | /// Notifies that screenshot data are ready. 63 | fn on_screenshot_done(&mut self); 64 | } 65 | 66 | // ------------------------------------------------------------------------------------------------- 67 | -------------------------------------------------------------------------------- /cognitive/dharma/src/dharma.rs: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of 2 | // the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/ 3 | 4 | //! `dharma` crate provides high-level multi-threading support. 5 | //! 6 | //! ### `bridge` module 7 | //! 8 | //! `bridge` module provides similar functionality as standard `spmc` but instead of producing 9 | //! fixed pairs `Sender`-`Receiver` it allows to connect them freely, so we can have many one 10 | //! `Sender` sending to many `Receivers` and one `Receiver` listening to many senders in flexible, 11 | //! configurable way. 12 | //! 13 | //! ### `signaler` module 14 | //! 15 | //! On to of that we add `Signaler` which can subscribe receivers for signals (application defined 16 | //! events) creating notification mechanism. 17 | //! 18 | //! ### `event_loop` module 19 | //! 20 | //! On top of `Signaler` we add `EventLoop`, which is event queue assigned to thread. `EventLoop` 21 | //! has assigned `Module`s constituting separate application components. `Module`s can be assigned 22 | //! to `EventLoop`s in flexible way making it easy to control tasks processed in threads. `Module`s 23 | //! do not share memory and communicate with signals. 24 | //! 25 | //! ### `dispatcher` module 26 | //! 27 | //! Every threading framework should provide mechanism for listening on system events. `Dispatcher` 28 | //! allows to register `EventHandler`s (wrapping file descriptors) and invokes them when system 29 | //! events they are assigned are ready to be processed. 30 | //! 31 | //! ### `system` module 32 | //! 33 | //! Last module contains helper code for and handling system signals. 34 | 35 | #![warn(missing_docs)] 36 | 37 | #[macro_use] 38 | extern crate bitflags; 39 | extern crate timerfd; 40 | extern crate nix; 41 | 42 | /// Communication between two endpoints in different threads. 43 | /// 44 | pub mod bridge; 45 | pub use bridge::{connect, direct_connect}; 46 | pub use bridge::{DirectSender, Sender, Receiver, ReceiveResult, SignalId, SpecialCommand}; 47 | 48 | /// Notification sender. 49 | /// 50 | pub mod signaler; 51 | pub use signaler::Signaler; 52 | 53 | /// Implementation of main thread loop with notification listening. 54 | /// 55 | pub mod event_loop; 56 | pub use event_loop::{EventLoop, EventLoopInfo, ServiceInfo}; 57 | pub use event_loop::{Module, ModuleConstructor, Service, ServiceConstructor}; 58 | 59 | /// Handling system events (`epoll` wrapper). 60 | /// 61 | pub mod dispatcher; 62 | pub use dispatcher::{Dispatcher, DispatcherController, LocalDispatcher, LocalDispatcherController}; 63 | pub use dispatcher::{EventHandler, EventHandlerId, EventKind, event_kind}; 64 | 65 | /// System signal handling. 66 | /// 67 | pub mod system; 68 | pub use system::{block_signals, unblock_signals, SignalEventHandler}; 69 | 70 | /// Timer functionality 71 | /// 72 | pub mod timer; 73 | pub use timer::Timer; 74 | -------------------------------------------------------------------------------- /cognitive/qualia/src/lib.rs: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of 2 | // the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/ 3 | 4 | //! `qualia` is crate containing enumerations, macros and definitions common to all the crates of 5 | //! `cognitive` and traits used to decouple `cognitive` creates one from another. 6 | 7 | extern crate backtrace; 8 | extern crate libc; 9 | extern crate libudev; // for implementation of `From` in `errors`. 10 | extern crate nix; 11 | extern crate time; 12 | #[macro_use] 13 | extern crate bitflags; 14 | 15 | #[macro_use] 16 | extern crate serde_derive; 17 | 18 | #[macro_use(timber)] 19 | extern crate timber; 20 | extern crate dharma; 21 | extern crate cognitive_graphics as graphics; 22 | 23 | pub mod enums; 24 | pub use enums::{DeviceKind, KeyState, Action, Direction, InteractionMode}; 25 | 26 | pub mod errors; 27 | pub use errors::Illusion; 28 | 29 | #[macro_use] 30 | pub mod macros; 31 | 32 | pub mod timing; 33 | pub use timing::Milliseconds; 34 | 35 | pub mod defs; 36 | pub use defs::{Area, Point, Position, OptionalPosition, Size, Slide, Vector}; 37 | pub use defs::{Command, OutputInfo, DrmBundle, WorkspaceState, WorkspaceInfo}; 38 | pub use defs::{DmabufId, EglImageId, MemoryPoolId, MemoryViewId, SignalId}; 39 | 40 | pub mod input; 41 | pub use input::{Axis, Button, Binding, Key, CatchResult, InputCode, InputValue, modifier}; 42 | pub use input::{InputForwarding, InputHandling}; 43 | 44 | pub mod image; 45 | pub use image::{Image, Pixmap, PixelFormat}; 46 | 47 | pub mod memory; 48 | pub use memory::{Buffer, Memory, MemoryPool, MemoryView}; 49 | 50 | pub mod configuration; 51 | pub use configuration::{AestheticsConfig, CompositorConfig, ExhibitorConfig}; 52 | pub use configuration::{KeyboardConfig, InputConfig, StrategistConfig}; 53 | 54 | pub mod surface; 55 | pub use surface::{SurfaceContext, SurfaceId, SurfaceIdType, SurfaceInfo, DataSource}; 56 | pub use surface::{SurfaceManagement, SurfaceControl, SurfaceViewer}; 57 | pub use surface::{SurfaceAccess, SurfaceListing, SurfaceFocusing}; 58 | pub use surface::{show_reason, surface_state}; 59 | 60 | pub mod transfer; 61 | pub use transfer::Transfer; 62 | 63 | pub mod perceptron; 64 | pub use perceptron::Perceptron; 65 | 66 | pub mod traits; 67 | pub use traits::{AppearanceManagement, DataTransferring, EventHandling, StatePublishing}; 68 | pub use traits::{Screenshooting, MemoryManagement, HwGraphics, WindowManagement}; 69 | pub use traits::GraphicsManagement; 70 | pub use traits::{AestheticsCoordinationTrait, ExhibitorCoordinationTrait}; 71 | pub use traits::FrontendsCoordinationTrait; 72 | 73 | pub mod settings; 74 | pub use settings::{Settings, Directories, KeymapSettings}; 75 | 76 | #[macro_use] 77 | pub mod log; 78 | pub use log::level; 79 | 80 | pub mod env; 81 | pub use env::{Env, LogDestination}; 82 | 83 | #[cfg(feature = "testing")] 84 | pub mod coordinator_mock; 85 | -------------------------------------------------------------------------------- /cognitive/qualia/src/configuration.rs: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of 2 | // the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/ 3 | 4 | //! Default configuration for `cognitive` entities. 5 | 6 | use std::path::PathBuf; 7 | 8 | // ------------------------------------------------------------------------------------------------- 9 | 10 | /// Configuration of aesthetics. 11 | #[derive(Clone, Debug, Serialize)] 12 | pub struct AestheticsConfig { 13 | /// Path to background image. 14 | pub background_path: Option, 15 | } 16 | 17 | // ------------------------------------------------------------------------------------------------- 18 | 19 | /// Configuration of compositor. 20 | #[derive(Clone, Debug, Serialize)] 21 | pub struct CompositorConfig { 22 | /// Distance in pixels by which frames are moved by `move` command. 23 | pub move_step: u32, 24 | 25 | /// Distance in pixels by which frames are resized by `resize` command. 26 | pub resize_step: u32, 27 | } 28 | 29 | // ------------------------------------------------------------------------------------------------- 30 | 31 | /// Configuration of exhibitor. 32 | #[derive(Clone, Debug, Serialize)] 33 | pub struct ExhibitorConfig { 34 | /// Configuration of compositor. 35 | pub compositor: CompositorConfig, 36 | 37 | /// Configuration of strategist. 38 | pub strategist: StrategistConfig, 39 | } 40 | 41 | // ------------------------------------------------------------------------------------------------- 42 | 43 | /// Configuration of input devices. 44 | #[derive(Clone, Debug, Serialize)] 45 | pub struct InputConfig { 46 | /// Scale for touchpad event position values. 47 | /// In future will be replaced by non-linear scale per dimension. 48 | pub touchpad_scale: f32, 49 | 50 | /// Threshold value for touchpad pressure below which move events will be ignored. 51 | pub touchpad_pressure_threshold: i32, 52 | 53 | /// Scale for mouse event motion values. 54 | /// In future will be replaced by non-linear scale per dimension. 55 | pub mouse_scale: f32, 56 | } 57 | 58 | // ------------------------------------------------------------------------------------------------- 59 | 60 | /// Configuration of keyboard. 61 | #[derive(Clone, Debug, Serialize)] 62 | pub struct KeyboardConfig { 63 | pub layout: String, 64 | pub variant: String, 65 | } 66 | 67 | // ------------------------------------------------------------------------------------------------- 68 | 69 | /// Configuration of strategist. 70 | #[derive(Clone, Debug, Serialize)] 71 | pub struct StrategistConfig { 72 | /// Strategy used to decide where and how new surface should be placed. 73 | pub choose_target: String, 74 | 75 | /// Strategy used to decide position and size of floating surface (new or deanchorized). 76 | pub choose_floating: String, 77 | } 78 | 79 | // ------------------------------------------------------------------------------------------------- 80 | -------------------------------------------------------------------------------- /cognitive/qualia/src/errors.rs: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of 2 | // the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/ 3 | 4 | //! This module provides error enumerations. 5 | 6 | // ------------------------------------------------------------------------------------------------- 7 | 8 | use std; 9 | use std::error::Error; 10 | 11 | use libudev; 12 | use graphics; 13 | 14 | // ------------------------------------------------------------------------------------------------- 15 | 16 | /// Generic application-wide error. 17 | /// 18 | /// This enum could not be named `Error`. This is `cognitive` error, hence `Illusion`. 19 | #[derive(Debug)] 20 | pub enum Illusion { 21 | Permissions(String), 22 | InvalidArgument(String), 23 | General(String), 24 | Graphics(String), 25 | Config(std::path::PathBuf, String), 26 | IO(String), 27 | Unknown(String), 28 | } 29 | 30 | // ------------------------------------------------------------------------------------------------- 31 | 32 | impl std::fmt::Display for Illusion { 33 | fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { 34 | match *self { 35 | Illusion::Permissions(ref s) => write!(f, "Wrong permissions: {}", s), 36 | Illusion::InvalidArgument(ref s) => write!(f, "Invalid argument: {}", s), 37 | Illusion::General(ref s) => write!(f, "{}", s), 38 | Illusion::Graphics(ref s) => write!(f, "{}", s), 39 | Illusion::Config(ref path, ref s) => write!(f, "Config error ({:?}): {}", path, s), 40 | Illusion::IO(ref s) => write!(f, "IO error: {}", s), 41 | Illusion::Unknown(ref s) => write!(f, "Unknown error: {}", s), 42 | } 43 | } 44 | } 45 | 46 | // ------------------------------------------------------------------------------------------------- 47 | 48 | impl std::convert::From for Illusion { 49 | fn from(error: std::io::Error) -> Self { 50 | Illusion::IO(error.description().to_owned()) 51 | } 52 | } 53 | 54 | // ------------------------------------------------------------------------------------------------- 55 | 56 | impl std::convert::From for Illusion { 57 | fn from(error: libudev::Error) -> Self { 58 | Illusion::General(error.description().to_owned()) 59 | } 60 | } 61 | 62 | // ------------------------------------------------------------------------------------------------- 63 | 64 | impl std::convert::From for Illusion { 65 | fn from(error: graphics::GraphicsError) -> Self { 66 | Illusion::Graphics(error.description().to_owned()) 67 | } 68 | } 69 | 70 | // ------------------------------------------------------------------------------------------------- 71 | 72 | impl std::convert::From for Illusion { 73 | fn from(error: String) -> Self { 74 | Illusion::General(error) 75 | } 76 | } 77 | 78 | // ------------------------------------------------------------------------------------------------- 79 | -------------------------------------------------------------------------------- /perceptia/skylane_simple_framework/src/listener.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2017 The Perceptia Project Developers 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software 4 | // and associated documentation files (the "Software"), to deal in the Software without 5 | // restriction, including without limitation the rights to use, copy, modify, merge, publish, 6 | // distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the 7 | // Software is furnished to do so, subject to the following conditions: 8 | // 9 | // The above copyright notice and this permission notice shall be included in all copies or 10 | // substantial portions of the Software. 11 | // 12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING 13 | // BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 14 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 15 | // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 16 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 17 | 18 | //! Interface for implementing listening to events in applications. 19 | 20 | use std::collections::HashSet; 21 | 22 | use defs::OutputInfo; 23 | use controller::Controller; 24 | 25 | // ------------------------------------------------------------------------------------------------- 26 | 27 | pub trait Listener { 28 | /// Called after all globals were received during initialization. 29 | /// 30 | /// List of globals advertised by server is passed. If needed interface is not supported 31 | /// application can now warn and exit. 32 | fn globals_done(&mut self, _globals: HashSet) {} 33 | 34 | /// Called when list of available outputs was updated. 35 | fn outputs_done(&mut self, _outputs: Vec) {} 36 | 37 | /// Called after all requests after all request send to server durring initialization were 38 | /// handled. 39 | fn init_done(&mut self) {} 40 | 41 | /// Called after authorization of DRM device by server successed. 42 | fn graphics_done(&mut self, _device_name: String) {} 43 | 44 | /// Called after authorization of DRM device by server failed. 45 | fn graphics_failed(&mut self) {} 46 | 47 | /// Called when screenshot request ended successfully. 48 | fn screenshot_done(&mut self, _buffer: Vec) {} 49 | 50 | /// Called when screenshot request failed. 51 | fn screenshot_failed(&mut self) {} 52 | } 53 | 54 | // ------------------------------------------------------------------------------------------------- 55 | 56 | pub trait ListenerConstructor { 57 | type Listener: Listener + 'static; 58 | 59 | fn construct(&self, controller: Controller) -> Box; 60 | } 61 | 62 | // ------------------------------------------------------------------------------------------------- 63 | 64 | pub struct Dummy {} 65 | impl Listener for Dummy {} 66 | 67 | // ------------------------------------------------------------------------------------------------- 68 | -------------------------------------------------------------------------------- /perceptia/skylane_simple_framework/src/protocol/display.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2017 The Perceptia Project Developers 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software 4 | // and associated documentation files (the "Software"), to deal in the Software without 5 | // restriction, including without limitation the rights to use, copy, modify, merge, publish, 6 | // distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the 7 | // Software is furnished to do so, subject to the following conditions: 8 | // 9 | // The above copyright notice and this permission notice shall be included in all copies or 10 | // substantial portions of the Software. 11 | // 12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING 13 | // BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 14 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 15 | // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 16 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 17 | 18 | //! Implementation of Wayland `wl_display` object. 19 | 20 | use skylane::client as wl; 21 | use skylane::client::{Bundle, Object, ObjectId, Task}; 22 | use skylane_protocols::client::Handler; 23 | use skylane_protocols::client::wayland::wl_display; 24 | 25 | use proxy::{Action, ProxyRef}; 26 | use protocol::callback; 27 | 28 | // ------------------------------------------------------------------------------------------------- 29 | 30 | /// Wayland `wl_display` object. 31 | pub struct Display {} 32 | 33 | // ------------------------------------------------------------------------------------------------- 34 | 35 | impl Display { 36 | fn new(_proxy: ProxyRef) -> Self { 37 | Display {} 38 | } 39 | 40 | pub fn new_object(proxy: ProxyRef) -> Box { 41 | Box::new(Handler::<_, wl_display::Dispatcher>::new(Self::new(proxy))) 42 | } 43 | 44 | pub fn synchronize(proxy_ref: ProxyRef, callback_id: ObjectId, action: Action) -> Box { 45 | let proxy = proxy_ref.borrow_mut(); 46 | let socket = proxy.get_socket(); 47 | let callback_object = callback::Callback::new_object(proxy_ref.clone(), action); 48 | send!(wl_display::sync(&socket, wl::DISPLAY_ID, callback_id)); 49 | callback_object 50 | } 51 | } 52 | 53 | // ------------------------------------------------------------------------------------------------- 54 | 55 | impl wl_display::Interface for Display { 56 | fn error(&mut self, 57 | _this_object_id: ObjectId, 58 | _bundle: &mut Bundle, 59 | _object_id: ObjectId, 60 | code: u32, 61 | message: String) 62 | -> Task { 63 | println!("Server Error ({}): {}", code, message); 64 | Task::None 65 | } 66 | 67 | fn delete_id(&mut self, _this_object_id: ObjectId, _bundle: &mut Bundle, id: u32) -> Task { 68 | Task::Destroy { id: ObjectId::new(id) } 69 | } 70 | } 71 | 72 | // ------------------------------------------------------------------------------------------------- 73 | -------------------------------------------------------------------------------- /cognitive/frames/tests/test_frame_converting.rs: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of 2 | // the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/ 3 | 4 | //! Tests for displaying `Frame` functionality. 5 | 6 | #![cfg_attr(rustfmt, rustfmt_skip)] 7 | 8 | // ------------------------------------------------------------------------------------------------- 9 | 10 | extern crate cognitive_qualia as qualia; 11 | extern crate cognitive_frames as frames; 12 | 13 | mod common; 14 | 15 | use qualia::{Position, SurfaceContext, SurfaceId, WorkspaceInfo, WorkspaceState}; 16 | use frames::Converting; 17 | use common::layouts; 18 | use common::surface_listing_mock::SurfaceListingMock; 19 | 20 | // ------------------------------------------------------------------------------------------------- 21 | 22 | /// Checks if only one workspace will be visible on display. 23 | #[test] 24 | fn test_converting_two_workspaces_to_array() { 25 | let (r, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _) = 26 | layouts::make_positioned_for_displaying(); 27 | 28 | let surface_listing = SurfaceListingMock::new(); 29 | 30 | let array = r.to_array(Position::new(1, 2), &surface_listing); 31 | let expected = vec![ 32 | SurfaceContext::new(SurfaceId::new(101), Position::new(1, 2)), 33 | SurfaceContext::new(SurfaceId::new(102), Position::new(1, 102)), 34 | SurfaceContext::new(SurfaceId::new(1), Position::new(101, 102)), 35 | SurfaceContext::new(SurfaceId::new(2), Position::new(101, 102)), 36 | SurfaceContext::new(SurfaceId::new(3), Position::new(101, 102)), 37 | SurfaceContext::new(SurfaceId::new(4), Position::new(101, 102)), 38 | SurfaceContext::new(SurfaceId::new(5), Position::new(101, 202)), 39 | SurfaceContext::new(SurfaceId::new(6), Position::new(101, 302)), 40 | ]; 41 | 42 | assert_eq!(array.len(), expected.len()); 43 | 44 | for (context, expected_context) in array.iter().zip(expected) { 45 | assert_eq!(*context, expected_context); 46 | } 47 | 48 | r.destroy(); 49 | } 50 | 51 | // ------------------------------------------------------------------------------------------------- 52 | 53 | /// Checks if frames are correctly converted to `WorkspaceState` structure. 54 | /// 55 | /// - workspaces which are not direct children on display should be included 56 | /// - workspaces under other workspaces should be ignored 57 | /// - activeness should be preserved 58 | #[test] 59 | fn test_converting_to_workspaces() { 60 | let (r, _, _, _, _, _, _, _, _) = layouts::make_simple_with_workspaces(); 61 | 62 | let mut expected = WorkspaceState::empty(); 63 | expected.workspaces.insert(1, vec![WorkspaceInfo::new("11".to_string(), true), 64 | WorkspaceInfo::new("12".to_string(), false)]); 65 | expected.workspaces.insert(2, vec![WorkspaceInfo::new("21".to_string(), true), 66 | WorkspaceInfo::new("22".to_string(), false)]); 67 | 68 | assert_eq!(expected, r.to_workspace_state()); 69 | 70 | r.destroy(); 71 | } 72 | 73 | // ------------------------------------------------------------------------------------------------- 74 | -------------------------------------------------------------------------------- /perceptia/skylane_simple_framework/src/protocol/callback.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2017 The Perceptia Project Developers 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software 4 | // and associated documentation files (the "Software"), to deal in the Software without 5 | // restriction, including without limitation the rights to use, copy, modify, merge, publish, 6 | // distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the 7 | // Software is furnished to do so, subject to the following conditions: 8 | // 9 | // The above copyright notice and this permission notice shall be included in all copies or 10 | // substantial portions of the Software. 11 | // 12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING 13 | // BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 14 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 15 | // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 16 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 17 | 18 | //! Implementation of Wayland `wl_callback` object. 19 | 20 | use skylane::client::{Bundle, Object, ObjectId, Task}; 21 | use skylane_protocols::client::Handler; 22 | use skylane_protocols::client::wayland::wl_callback; 23 | 24 | use proxy::{Action, ProxyRef}; 25 | use protocol::display::Display; 26 | 27 | // ------------------------------------------------------------------------------------------------- 28 | 29 | /// Wayland `wl_callback` object. 30 | pub struct Callback { 31 | action: Action, 32 | proxy: ProxyRef, 33 | } 34 | 35 | // ------------------------------------------------------------------------------------------------- 36 | 37 | impl Callback { 38 | fn new(proxy: ProxyRef, action: Action) -> Self { 39 | Callback { 40 | action: action, 41 | proxy: proxy, 42 | } 43 | } 44 | 45 | pub fn new_object(proxy: ProxyRef, action: Action) -> Box { 46 | Box::new(Handler::<_, wl_callback::Dispatcher>::new(Self::new(proxy, action))) 47 | } 48 | } 49 | 50 | // ------------------------------------------------------------------------------------------------- 51 | 52 | impl wl_callback::Interface for Callback { 53 | fn done(&mut self, 54 | _this_object_id: ObjectId, 55 | bundle: &mut Bundle, 56 | _callback_data: u32) 57 | -> Task { 58 | match self.action { 59 | Action::GlobalsDone => { 60 | self.proxy.borrow_mut().globals_done(); 61 | let id = bundle.get_next_available_client_object_id(); 62 | let object = Display::synchronize(self.proxy.clone(), id, Action::InitDone); 63 | Task::Create { 64 | id: id, 65 | object: object, 66 | } 67 | } 68 | Action::InitDone => { 69 | self.proxy.borrow_mut().init_done(); 70 | Task::None 71 | } 72 | } 73 | } 74 | } 75 | 76 | // ------------------------------------------------------------------------------------------------- 77 | -------------------------------------------------------------------------------- /perceptia/skylane_simple_framework/src/event_handler.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2017 The Perceptia Project Developers 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software 4 | // and associated documentation files (the "Software"), to deal in the Software without 5 | // restriction, including without limitation the rights to use, copy, modify, merge, publish, 6 | // distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the 7 | // Software is furnished to do so, subject to the following conditions: 8 | // 9 | // The above copyright notice and this permission notice shall be included in all copies or 10 | // substantial portions of the Software. 11 | // 12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING 13 | // BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 14 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 15 | // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 16 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 17 | 18 | //! `dharma` event handlers. 19 | 20 | // ------------------------------------------------------------------------------------------------- 21 | 22 | use std::os::unix::io::RawFd; 23 | 24 | use skylane::client as wl; 25 | 26 | use dharma; 27 | 28 | // ------------------------------------------------------------------------------------------------- 29 | 30 | /// Implementation of `dharma::EventHandler` for server socket. 31 | pub struct DisplayEventHandler { 32 | id: dharma::EventHandlerId, 33 | connection: wl::Connection, 34 | dispatcher: dharma::LocalDispatcherController, 35 | } 36 | 37 | // ------------------------------------------------------------------------------------------------- 38 | 39 | impl DisplayEventHandler { 40 | /// Constructs new `DisplayEventHandler`. 41 | pub fn new(connection: wl::Connection, dispatcher: dharma::LocalDispatcherController) -> Self { 42 | DisplayEventHandler { 43 | // No `Option` used here as `Dispatcher` will for sure set this data and we would 44 | // `expect` it anyway. 45 | id: 0, 46 | connection: connection, 47 | dispatcher: dispatcher, 48 | } 49 | } 50 | } 51 | 52 | // ------------------------------------------------------------------------------------------------- 53 | 54 | impl dharma::EventHandler for DisplayEventHandler { 55 | fn get_fd(&self) -> RawFd { 56 | self.connection.get_socket().get_fd() 57 | } 58 | 59 | fn process_event(&mut self, event_kind: dharma::EventKind) { 60 | if event_kind.intersects(dharma::event_kind::HANGUP) { 61 | println!("Server hung the connection up"); 62 | self.dispatcher.stop(); 63 | } else if event_kind.intersects(dharma::event_kind::READ) { 64 | self.connection.process_events().expect("Processing Wayland events"); 65 | } 66 | } 67 | 68 | fn set_id(&mut self, id: dharma::EventHandlerId) { 69 | self.id = id; 70 | } 71 | } 72 | 73 | // ------------------------------------------------------------------------------------------------- 74 | -------------------------------------------------------------------------------- /cognitive/wayland_frontend/src/protocol/output.rs: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of 2 | // the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/ 3 | 4 | //! Implementations of Wayland `wl_output` object. 5 | 6 | use std::rc::Rc; 7 | 8 | use skylane::server::{Bundle, Object, ObjectId, Task}; 9 | use skylane_protocols::server::Handler; 10 | use skylane_protocols::server::wayland::wl_output; 11 | 12 | use qualia::OutputInfo; 13 | 14 | use global::Global; 15 | use proxy::ProxyRef; 16 | use facade::Facade; 17 | 18 | // ------------------------------------------------------------------------------------------------- 19 | 20 | /// Wayland `wl_output` object. 21 | struct Output {} 22 | 23 | // ------------------------------------------------------------------------------------------------- 24 | 25 | pub fn get_global(info: OutputInfo) -> Global { 26 | Global::new(wl_output::NAME, 27 | wl_output::VERSION, 28 | Rc::new(move |oid, _version, proxy| Output::new_object(oid, proxy, info.clone()))) 29 | } 30 | 31 | // ------------------------------------------------------------------------------------------------- 32 | 33 | impl Output { 34 | fn new(oid: ObjectId, proxy_ref: ProxyRef, info: OutputInfo) -> Self { 35 | { 36 | let mut proxy = proxy_ref.borrow_mut(); 37 | let socket = proxy.get_socket(); 38 | send!(wl_output::geometry(&socket, 39 | oid, 40 | info.area.pos.x as i32, 41 | info.area.pos.y as i32, 42 | info.physical_size.width as i32, 43 | info.physical_size.height as i32, 44 | wl_output::subpixel::UNKNOWN as i32, 45 | &info.make, 46 | &info.model, 47 | wl_output::transform::NORMAL as i32)); 48 | 49 | send!(wl_output::mode(&socket, 50 | oid, 51 | wl_output::mode::CURRENT as u32, 52 | info.area.size.width as i32, 53 | info.area.size.height as i32, 54 | info.refresh_rate as i32)); 55 | 56 | send!(wl_output::scale(&socket, oid, 1)); 57 | send!(wl_output::done(&socket, oid)); 58 | 59 | proxy.relate_output_oid_with_id(oid, info.id); 60 | } 61 | 62 | Output {} 63 | } 64 | 65 | fn new_object(oid: ObjectId, proxy_ref: ProxyRef, info: OutputInfo) -> Box { 66 | Box::new(Handler::<_, wl_output::Dispatcher>::new(Self::new(oid, proxy_ref, info))) 67 | } 68 | } 69 | 70 | // ------------------------------------------------------------------------------------------------- 71 | 72 | impl wl_output::Interface for Output { 73 | fn release(&mut self, this_object_id: ObjectId, _bundle: &mut Bundle) -> Task { 74 | Task::Destroy { id: this_object_id } 75 | } 76 | } 77 | 78 | // ------------------------------------------------------------------------------------------------- 79 | -------------------------------------------------------------------------------- /perceptia/coordination/context.rs: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of 2 | // the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/ 3 | 4 | //! This module contains application context used to share data between threads. 5 | 6 | // ------------------------------------------------------------------------------------------------- 7 | 8 | use std::time::Instant; 9 | 10 | use dharma::{DispatcherController, EventHandler, EventKind, Signaler, SignalId}; 11 | 12 | use qualia::{Settings, Perceptron}; 13 | use gears::Config; 14 | 15 | use coordinator::Coordinator; 16 | 17 | // ------------------------------------------------------------------------------------------------- 18 | 19 | /// Application `Context` lets `Module`s communicate with other `Module`s by mean of signals. 20 | #[derive(Clone)] 21 | pub struct Context { 22 | config: Config, 23 | settings: Settings, 24 | signaler: Signaler, 25 | dispatcher: DispatcherController, 26 | coordinator: Coordinator, 27 | reference_time: Instant, 28 | } 29 | 30 | // ------------------------------------------------------------------------------------------------- 31 | 32 | impl Context { 33 | /// Context constructor. 34 | pub fn new(config: Config, 35 | settings: Settings, 36 | signaler: Signaler, 37 | dispatcher: DispatcherController, 38 | coordinator: Coordinator) 39 | -> Self { 40 | Context { 41 | config: config, 42 | settings: settings, 43 | signaler: signaler, 44 | dispatcher: dispatcher, 45 | coordinator: coordinator, 46 | reference_time: Instant::now(), 47 | } 48 | } 49 | 50 | /// Emits signal with given `id` and `package` data. 51 | pub fn emit(&mut self, id: SignalId, package: Perceptron) { 52 | self.signaler.emit(id, package); 53 | } 54 | 55 | /// Adds new event handler. 56 | pub fn add_event_handler(&mut self, 57 | event_handler: Box, 58 | event_kind: EventKind) { 59 | self.dispatcher.add_source(event_handler, event_kind); 60 | } 61 | 62 | /// Returns global configuration. 63 | pub fn get_config(&self) -> &Config { 64 | &self.config 65 | } 66 | 67 | /// Returns global settings. 68 | pub fn get_settings(&self) -> &Settings { 69 | &self.settings 70 | } 71 | 72 | /// Returns reference to `Signaler`. 73 | pub fn get_signaler(&mut self) -> &mut Signaler { 74 | &mut self.signaler 75 | } 76 | 77 | /// Returns reference to `DispatcherController`. 78 | pub fn get_dispatcher(&mut self) -> &mut DispatcherController { 79 | &mut self.dispatcher 80 | } 81 | 82 | /// Returns reference to `Coordinator`. 83 | pub fn get_coordinator(&mut self) -> &mut Coordinator { 84 | &mut self.coordinator 85 | } 86 | 87 | /// Returns `Instant` created during construction used as reference time for obtaining 88 | /// timestamps for events. 89 | pub fn get_reference_time(&self) -> Instant { 90 | self.reference_time 91 | } 92 | } 93 | 94 | // ------------------------------------------------------------------------------------------------- 95 | -------------------------------------------------------------------------------- /perceptia/skylane_simple_framework/src/protocol/compositor.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2017 The Perceptia Project Developers 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software 4 | // and associated documentation files (the "Software"), to deal in the Software without 5 | // restriction, including without limitation the rights to use, copy, modify, merge, publish, 6 | // distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the 7 | // Software is furnished to do so, subject to the following conditions: 8 | // 9 | // The above copyright notice and this permission notice shall be included in all copies or 10 | // substantial portions of the Software. 11 | // 12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING 13 | // BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 14 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 15 | // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 16 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 17 | 18 | //! Implementation of Wayland `wl_compositor` object. 19 | 20 | use skylane::client::{Bundle, Object, ObjectId, Task}; 21 | use skylane_protocols::client::Handler; 22 | use skylane_protocols::client::wayland::{wl_compositor, wl_surface}; 23 | 24 | use proxy::ProxyRef; 25 | 26 | // ------------------------------------------------------------------------------------------------- 27 | 28 | /// Wayland `wl_compositor` object. 29 | pub struct Compositor {} 30 | 31 | // ------------------------------------------------------------------------------------------------- 32 | 33 | impl Compositor { 34 | fn new() -> Self { 35 | Compositor {} 36 | } 37 | 38 | pub fn new_object() -> Box { 39 | Box::new(Handler::<_, wl_compositor::Dispatcher>::new(Self::new())) 40 | } 41 | } 42 | 43 | // ------------------------------------------------------------------------------------------------- 44 | 45 | impl wl_compositor::Interface for Compositor {} 46 | 47 | // ------------------------------------------------------------------------------------------------- 48 | 49 | /// Wayland `wl_surface` object. 50 | pub struct Surface { 51 | _proxy: ProxyRef, 52 | } 53 | 54 | // ------------------------------------------------------------------------------------------------- 55 | 56 | impl Surface { 57 | fn new(proxy: ProxyRef) -> Self { 58 | Surface { _proxy: proxy } 59 | } 60 | 61 | pub fn new_object(proxy: ProxyRef) -> Box { 62 | Box::new(Handler::<_, wl_surface::Dispatcher>::new(Self::new(proxy))) 63 | } 64 | } 65 | 66 | // ------------------------------------------------------------------------------------------------- 67 | 68 | impl wl_surface::Interface for Surface { 69 | fn enter(&mut self, 70 | _this_object_id: ObjectId, 71 | _bundle: &mut Bundle, 72 | _output: ObjectId) 73 | -> Task { 74 | // Nothing to do so far 75 | Task::None 76 | } 77 | 78 | fn leave(&mut self, 79 | _this_object_id: ObjectId, 80 | _bundle: &mut Bundle, 81 | _output: ObjectId) 82 | -> Task { 83 | // Nothing to do so far 84 | Task::None 85 | } 86 | } 87 | 88 | // ------------------------------------------------------------------------------------------------- 89 | -------------------------------------------------------------------------------- /cognitive/device_manager/src/pageflip.rs: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of 2 | // the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/ 3 | 4 | //! This module implements helper functionality for handling pageflips. 5 | 6 | // ------------------------------------------------------------------------------------------------- 7 | 8 | use std::os::unix::io; 9 | use libdrm::drm; 10 | 11 | use dharma::{EventHandler, EventKind, event_kind}; 12 | use qualia::StatePublishing; 13 | 14 | // ------------------------------------------------------------------------------------------------- 15 | 16 | /// Context passed ti libdrm to handle page flips. 17 | struct PageFlipContext

18 | where P: StatePublishing 19 | { 20 | state_publisher: P, 21 | } 22 | 23 | // ------------------------------------------------------------------------------------------------- 24 | 25 | impl

PageFlipContext

26 | where P: StatePublishing 27 | { 28 | /// `PageFlipContext` constructor. 29 | pub fn new(state_publisher: P) -> Self { 30 | PageFlipContext { state_publisher: state_publisher } 31 | } 32 | } 33 | 34 | // ------------------------------------------------------------------------------------------------- 35 | 36 | impl

drm::EventContext for PageFlipContext

37 | where P: StatePublishing 38 | { 39 | #[allow(unused_variables)] 40 | fn vblank_handler(&mut self, fd: io::RawFd, sequence: u32, sec: u32, usec: u32, data: i32) { 41 | self.state_publisher.emit_vblank(data); 42 | } 43 | 44 | #[allow(unused_variables)] 45 | fn page_flip_handler(&mut self, fd: io::RawFd, sequence: u32, sec: u32, usec: u32, data: i32) { 46 | self.state_publisher.emit_page_flip(data); 47 | } 48 | } 49 | 50 | // ------------------------------------------------------------------------------------------------- 51 | 52 | /// `dharma` event handler for pageflip events. 53 | pub struct PageFlipEventHandler

54 | where P: StatePublishing 55 | { 56 | drm_fd: io::RawFd, 57 | state_publisher: P, 58 | } 59 | 60 | // ------------------------------------------------------------------------------------------------- 61 | 62 | impl

PageFlipEventHandler

63 | where P: StatePublishing 64 | { 65 | /// `PageFlipEventHandler` constructor. 66 | pub fn new(fd: io::RawFd, state_publisher: P) -> Self { 67 | PageFlipEventHandler { 68 | drm_fd: fd, 69 | state_publisher: state_publisher, 70 | } 71 | } 72 | } 73 | 74 | // ------------------------------------------------------------------------------------------------- 75 | 76 | /// This code executes in main dispatchers thread. 77 | impl

EventHandler for PageFlipEventHandler

78 | where P: 'static + StatePublishing + Send + Clone 79 | { 80 | fn get_fd(&self) -> io::RawFd { 81 | self.drm_fd 82 | } 83 | 84 | fn process_event(&mut self, event_kind: EventKind) { 85 | if event_kind.intersects(event_kind::READ) { 86 | let ctx = Box::new(PageFlipContext::new(self.state_publisher.clone())); 87 | drm::handle_event(self.drm_fd, ctx); 88 | } else if event_kind.intersects(event_kind::HANGUP) { 89 | // It seems that DRM devices do not hang-up during virtual terminal switch and after 90 | // application regains access they are ready to use. 91 | } 92 | } 93 | } 94 | 95 | // ------------------------------------------------------------------------------------------------- 96 | -------------------------------------------------------------------------------- /cognitive/inputs/src/keymap.rs: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of 2 | // the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/ 3 | 4 | //! This module contains functionality related to key maps. 5 | 6 | // ------------------------------------------------------------------------------------------------- 7 | 8 | use std; 9 | use std::os::unix::io::AsRawFd; 10 | use std::io::Write; 11 | use xkbcommon::xkb; 12 | 13 | use qualia::{Illusion, KeyboardConfig, KeymapSettings, env}; 14 | 15 | // ------------------------------------------------------------------------------------------------- 16 | 17 | const DEFAULT_FORMAT: u32 = xkb::KEYMAP_FORMAT_TEXT_V1; 18 | 19 | // ------------------------------------------------------------------------------------------------- 20 | 21 | /// Wrapper for `xkb` context and keymap. 22 | pub struct XkbKeymap { 23 | pub context: xkb::Context, 24 | pub keymap: xkb::Keymap, 25 | } 26 | 27 | // ------------------------------------------------------------------------------------------------- 28 | 29 | impl XkbKeymap { 30 | /// Constructs new `XkbKeymap`. 31 | pub fn new(config: &KeyboardConfig) -> Option { 32 | let rules = "evdev".to_owned(); 33 | let model = "evdev".to_owned(); 34 | let layout = &config.layout; 35 | let variant = &config.variant; 36 | 37 | let context = xkb::Context::new(xkb::CONTEXT_NO_FLAGS); 38 | let k = xkb::Keymap::new_from_names(&context, &rules, &model, layout, variant, None, 0x0); 39 | if let Some(keymap) = k { 40 | Some(XkbKeymap { 41 | context: context, 42 | keymap: keymap, 43 | }) 44 | } else { 45 | None 46 | } 47 | } 48 | } 49 | 50 | // ------------------------------------------------------------------------------------------------- 51 | 52 | /// This structure handles creation of file used for communicating clients current keymap using 53 | /// xkbcommon. 54 | pub struct Keymap { 55 | settings: KeymapSettings, 56 | 57 | /// Keymap file. It is not referenced here but must be kept open because we will pass file 58 | /// descriptor to clients. 59 | _file: std::fs::File, 60 | } 61 | 62 | // ------------------------------------------------------------------------------------------------- 63 | 64 | impl Keymap { 65 | /// `Keymap` constructor. 66 | pub fn new(env: &env::Env, config: &KeyboardConfig) -> Result { 67 | let xkb_keymap = if let Some(xkb_keymap) = XkbKeymap::new(config) { 68 | xkb_keymap 69 | } else { 70 | return Err(Illusion::General(format!("Failed to create key map"))); 71 | }; 72 | 73 | // Save keymap to file 74 | let file_name = "keymap".to_owned(); 75 | let keymap_str = xkb_keymap.keymap.get_as_string(DEFAULT_FORMAT); 76 | let mut file = env.open_file(file_name, env::Directory::Runtime)?; 77 | file.write_all(keymap_str.as_bytes())?; 78 | file.write_all("\0".as_bytes())?; 79 | 80 | Ok(Keymap { 81 | settings: KeymapSettings { 82 | format: DEFAULT_FORMAT, 83 | size: keymap_str.len() + 1, 84 | fd: file.as_raw_fd(), 85 | }, 86 | _file: file, 87 | }) 88 | } 89 | 90 | /// Return key map settings. 91 | pub fn get_settings(&self) -> KeymapSettings { 92 | self.settings.clone() 93 | } 94 | } 95 | 96 | // ------------------------------------------------------------------------------------------------- 97 | -------------------------------------------------------------------------------- /cognitive/device_manager/src/graphics_manager.rs: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of 2 | // the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/ 3 | 4 | //! This module contains implementation of `GraphicsManager`. 5 | //! 6 | //! TODO: Rewrite `GraphicsManager` after `gbm_tools` have support for off-screen GBM and remove 7 | //! direct dependency from `egl` and `libgbm`. 8 | 9 | // ------------------------------------------------------------------------------------------------- 10 | 11 | use std::os::unix::io::RawFd; 12 | 13 | use egl; 14 | use libgbm; 15 | 16 | use cognitive_graphics::attributes::{DmabufAttributes, EglAttributes}; 17 | use cognitive_graphics::{gbm_tools, egl_tools}; 18 | use qualia::{GraphicsManagement, Illusion}; 19 | 20 | 21 | // ------------------------------------------------------------------------------------------------- 22 | 23 | /// Graphics manager provides basic access to GPU for non-rendering components. 24 | pub struct GraphicsManager { 25 | /// GBM device. 26 | _device: libgbm::Device, 27 | 28 | /// EGL display. 29 | display: egl::EGLDisplay, 30 | } 31 | 32 | /// `GraphicsManager` contains only pointers. It is `Send` but not `Sync`. 33 | unsafe impl Send for GraphicsManager {} 34 | 35 | // ------------------------------------------------------------------------------------------------- 36 | 37 | impl GraphicsManager { 38 | /// Constructs new `GraphicsManager`. 39 | pub fn new(fd: RawFd) -> Result { 40 | // Create device and display 41 | let device = gbm_tools::get_device(fd)?; 42 | let display = egl_tools::get_gbm_display(device.c_struct() as egl::EGLNativeDisplayType)?; 43 | 44 | // Initialize EGL 45 | let mut major = 0; 46 | let mut minor = 0; 47 | if !egl::initialize(display, &mut major, &mut minor) { 48 | return Err(Illusion::General(format!("Failed to initialize EGL"))); 49 | }; 50 | 51 | if !egl::bind_api(egl::EGL_OPENGL_ES_API) { 52 | return Err(Illusion::General(format!("Failed to bind EGL API"))); 53 | }; 54 | 55 | // Check for image base extension and related functions 56 | if egl_tools::has_extension(display, egl_tools::ext::IMAGE_BASE_EXT) { 57 | if egl_tools::get_proc_addr_of_create_image_khr().is_none() { 58 | return Err(Illusion::General(format!("Failed to get function address"))); 59 | } 60 | } else { 61 | return Err(Illusion::General(format!("No {} extension", 62 | egl_tools::ext::IMAGE_BASE_EXT))); 63 | } 64 | 65 | Ok(GraphicsManager { 66 | _device: device, 67 | display: display, 68 | }) 69 | } 70 | } 71 | 72 | // ------------------------------------------------------------------------------------------------- 73 | 74 | impl GraphicsManagement for GraphicsManager { 75 | /// Creates EGL image from given parameters. 76 | fn create_egl_image(&mut self, attrs: &EglAttributes) -> Option { 77 | egl_tools::create_image(self.display, attrs) 78 | } 79 | 80 | /// Imports dmabuf as EGL image. 81 | fn import_dmabuf(&mut self, attrs: &DmabufAttributes) -> Option { 82 | egl_tools::import_dmabuf(self.display, attrs) 83 | } 84 | 85 | /// Destroys given hardware image. 86 | fn destroy_hw_image(&mut self, image: egl_tools::HwImage) -> Result<(), ()> { 87 | egl_tools::destroy_image(self.display, image) 88 | } 89 | } 90 | 91 | // ------------------------------------------------------------------------------------------------- 92 | -------------------------------------------------------------------------------- /cognitive/wayland_frontend/src/mediator.rs: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of 2 | // the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/ 3 | 4 | //! This module contains code used for madiating information between `Proxy`s and `Engine`. 5 | 6 | // ------------------------------------------------------------------------------------------------- 7 | 8 | use std; 9 | use std::collections::HashMap; 10 | use std::os::unix::io::RawFd; 11 | use std::path::PathBuf; 12 | 13 | use libdrm; 14 | 15 | use dharma; 16 | 17 | use qualia::SurfaceId; 18 | 19 | // ------------------------------------------------------------------------------------------------- 20 | 21 | /// `Mediator` stores information about which surface was created by which client. 22 | /// 23 | /// For information about its place among other structures see crate-level documentation. 24 | pub struct Mediator { 25 | sid_to_cid_dictionary: HashMap, 26 | transfer_offerer: Option, 27 | screenshoter_cid: Option, 28 | drm_device_path: Option, 29 | drm_device_fd: Option, 30 | } 31 | 32 | define_ref!(struct Mediator as MediatorRef); 33 | 34 | // ------------------------------------------------------------------------------------------------- 35 | 36 | impl Mediator { 37 | pub fn new() -> Self { 38 | Mediator { 39 | sid_to_cid_dictionary: HashMap::new(), 40 | transfer_offerer: None, 41 | screenshoter_cid: None, 42 | drm_device_fd: None, 43 | drm_device_path: None, 44 | } 45 | } 46 | } 47 | 48 | // ------------------------------------------------------------------------------------------------- 49 | 50 | impl Mediator { 51 | pub fn relate_sid_to_client(&mut self, sid: SurfaceId, cid: dharma::EventHandlerId) { 52 | self.sid_to_cid_dictionary.insert(sid, cid); 53 | } 54 | 55 | pub fn get_client_for_sid(&self, sid: SurfaceId) -> Option<&dharma::EventHandlerId> { 56 | self.sid_to_cid_dictionary.get(&sid) 57 | } 58 | 59 | pub fn remove(&mut self, sid: SurfaceId) { 60 | self.sid_to_cid_dictionary.remove(&sid); 61 | } 62 | 63 | pub fn register_transfer_offerer(&mut self, transfer_offerer: Option) { 64 | self.transfer_offerer = transfer_offerer; 65 | } 66 | 67 | pub fn get_transfer_offerer(&self) -> Option { 68 | self.transfer_offerer 69 | } 70 | 71 | pub fn register_screenshoter(&mut self, cid: Option) { 72 | self.screenshoter_cid = cid; 73 | } 74 | 75 | pub fn get_screenshooter(&self) -> Option { 76 | self.screenshoter_cid 77 | } 78 | 79 | pub fn set_drm_device(&mut self, fd: RawFd, path: PathBuf) { 80 | self.drm_device_fd = Some(fd); 81 | self.drm_device_path = Some(path); 82 | } 83 | 84 | pub fn get_drm_device_path(&self) -> Option { 85 | self.drm_device_path.clone() 86 | } 87 | 88 | pub fn authenticate_drm_device(&self, magic: u32) { 89 | if let Some(fd) = self.drm_device_fd { 90 | // TODO: Add safe `drmAuthMagic` to lidrm bindings. 91 | let result = unsafe { libdrm::ffi::xf86drm::drmAuthMagic(fd, magic) }; 92 | if result != 0 { 93 | log_warn3!("Failed to authenticate clients DRM device"); 94 | } 95 | } 96 | } 97 | } 98 | 99 | // ------------------------------------------------------------------------------------------------- 100 | -------------------------------------------------------------------------------- /perceptia/skylane_simple_framework/src/protocol/shell.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2017 The Perceptia Project Developers 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software 4 | // and associated documentation files (the "Software"), to deal in the Software without 5 | // restriction, including without limitation the rights to use, copy, modify, merge, publish, 6 | // distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the 7 | // Software is furnished to do so, subject to the following conditions: 8 | // 9 | // The above copyright notice and this permission notice shall be included in all copies or 10 | // substantial portions of the Software. 11 | // 12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING 13 | // BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 14 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 15 | // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 16 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 17 | 18 | //! Implementation of Wayland `wl_shell` object. 19 | 20 | use skylane::client::{Bundle, Object, ObjectId, Task}; 21 | use skylane_protocols::client::Handler; 22 | use skylane_protocols::client::wayland::{wl_shell, wl_shell_surface}; 23 | 24 | use proxy::ProxyRef; 25 | 26 | // ------------------------------------------------------------------------------------------------- 27 | 28 | /// Wayland `wl_shell` object. 29 | pub struct Shell { 30 | _proxy: ProxyRef, 31 | } 32 | 33 | // ------------------------------------------------------------------------------------------------- 34 | 35 | impl Shell { 36 | fn new(proxy: ProxyRef) -> Self { 37 | Shell { _proxy: proxy } 38 | } 39 | 40 | pub fn new_object(proxy: ProxyRef) -> Box { 41 | Box::new(Handler::<_, wl_shell::Dispatcher>::new(Self::new(proxy))) 42 | } 43 | } 44 | 45 | // ------------------------------------------------------------------------------------------------- 46 | 47 | impl wl_shell::Interface for Shell {} 48 | 49 | // ------------------------------------------------------------------------------------------------- 50 | 51 | /// Wayland `wl_shell_surface` object. 52 | pub struct ShellSurface { 53 | _proxy: ProxyRef, 54 | } 55 | 56 | // ------------------------------------------------------------------------------------------------- 57 | 58 | impl ShellSurface { 59 | fn new(proxy: ProxyRef) -> Self { 60 | ShellSurface { _proxy: proxy } 61 | } 62 | 63 | pub fn new_object(proxy: ProxyRef) -> Box { 64 | Box::new(Handler::<_, wl_shell_surface::Dispatcher>::new(Self::new(proxy))) 65 | } 66 | } 67 | 68 | // ------------------------------------------------------------------------------------------------- 69 | 70 | impl wl_shell_surface::Interface for ShellSurface { 71 | fn ping(&mut self, _this_object_id: ObjectId, _bundle: &mut Bundle, _serial: u32) -> Task { 72 | // Nothing to do so far 73 | Task::None 74 | } 75 | 76 | fn configure(&mut self, 77 | _this_object_id: ObjectId, 78 | _bundle: &mut Bundle, 79 | _edges: u32, 80 | _width: i32, 81 | _height: i32) 82 | -> Task { 83 | // Nothing to do so far 84 | Task::None 85 | } 86 | 87 | fn popup_done(&mut self, _this_object_id: ObjectId, _bundle: &mut Bundle) -> Task { 88 | // Nothing to do so far 89 | Task::None 90 | } 91 | } 92 | 93 | // ------------------------------------------------------------------------------------------------- 94 | -------------------------------------------------------------------------------- /cognitive/aesthetics/src/aesthetics.rs: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of 2 | // the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/ 3 | 4 | //! `Aesthetics` manages tasks related to visual appearance. It uses the same API as exposed to 5 | //! client frontends (i.e. it only provides surfaces that `Exhibitor` will draw). 6 | 7 | // ------------------------------------------------------------------------------------------------- 8 | 9 | use qualia::{SurfaceId, AestheticsConfig, AestheticsCoordinationTrait, OutputInfo}; 10 | 11 | use cursor::Cursor; 12 | use background::Background; 13 | use panels::PanelManager; 14 | 15 | // ------------------------------------------------------------------------------------------------- 16 | 17 | /// `Aesthetics` manages tasks related to visual appearance. It uses the same API as exposed to 18 | /// client frontends. 19 | pub struct Aesthetics<'a, C> 20 | where C: AestheticsCoordinationTrait 21 | { 22 | cursor: Cursor, 23 | background: Background, 24 | panels: PanelManager<'a, C>, 25 | coordinator: C, 26 | } 27 | 28 | // ------------------------------------------------------------------------------------------------- 29 | 30 | /// General methods. 31 | impl<'a, C> Aesthetics<'a, C> 32 | where C: AestheticsCoordinationTrait + Clone 33 | { 34 | /// Constructs new `Aesthetics`. 35 | pub fn new(coordinator: C, config: AestheticsConfig) -> Self { 36 | Aesthetics { 37 | cursor: Cursor::new(coordinator.clone()), 38 | background: Background::new(coordinator.clone(), config.clone()), 39 | panels: PanelManager::new(coordinator.get_workspace_state(), coordinator.clone()), 40 | coordinator: coordinator, 41 | } 42 | } 43 | } 44 | 45 | // ------------------------------------------------------------------------------------------------- 46 | 47 | /// Notification handlers. 48 | /// 49 | /// TODO: Don't use "on_" on method names of `Background` and `Cursor`. 50 | impl<'a, C> Aesthetics<'a, C> 51 | where C: AestheticsCoordinationTrait + Clone 52 | { 53 | /// This method is called when changing cursor surface was requested. 54 | pub fn on_cursor_surface_change(&mut self, sid: SurfaceId) { 55 | self.cursor.on_surface_change(sid); 56 | } 57 | 58 | /// This method is called when changing background surface was requested. 59 | pub fn on_background_surface_change(&mut self, sid: SurfaceId) { 60 | self.background.on_surface_change(sid); 61 | } 62 | 63 | /// This method is called when pointer focus changed. 64 | pub fn on_pointer_focus_changed(&mut self, old_pfsid: SurfaceId, new_pfsid: SurfaceId) { 65 | self.cursor.on_focus_changed(old_pfsid, new_pfsid); 66 | } 67 | 68 | /// This method is called when surface was destroyed. 69 | pub fn on_surface_destroyed(&mut self, sid: SurfaceId) { 70 | self.cursor.on_surface_destroyed(sid); 71 | } 72 | 73 | /// This method is called when new display was created. 74 | pub fn on_display_created(&mut self, output: &OutputInfo) { 75 | self.cursor.on_display_created(); 76 | self.background.on_display_created(); 77 | self.panels.create_new_panel(output); 78 | } 79 | 80 | /// This method is called when state of workspaces changed. 81 | pub fn on_workspace_state_changed(&mut self) { 82 | self.panels.update_workspace_state(self.coordinator.get_workspace_state()) 83 | } 84 | 85 | /// Handles 500 millisecond timer for redrawing panels. 86 | pub fn on_timer_500(&mut self) { 87 | self.panels.redraw_all(); 88 | } 89 | } 90 | 91 | // ------------------------------------------------------------------------------------------------- 92 | -------------------------------------------------------------------------------- /cognitive/frames/src/converting.rs: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of 2 | // the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/ 3 | 4 | //! This module contains extra functionality for converting `frames::Frame` to different 5 | //! collections. 6 | 7 | // ------------------------------------------------------------------------------------------------- 8 | 9 | use std::collections::HashMap; 10 | 11 | use frame::{Frame, Mode}; 12 | 13 | use qualia::{Position, SurfaceListing, SurfaceContext, WorkspaceInfo, WorkspaceState}; 14 | 15 | // ------------------------------------------------------------------------------------------------- 16 | 17 | /// Extension trait for `Frame` adding more displaying functionality. 18 | pub trait Converting { 19 | /// Converts frame three to list of `SurfaceContext` suitable for drawing by renderer. 20 | fn to_array(&self, 21 | relative_position: Position, 22 | listing: &SurfaceListing) 23 | -> Vec; 24 | 25 | /// Converts frame tree to structure describing state of workspaces. 26 | fn to_workspace_state(&self) -> WorkspaceState; 27 | } 28 | 29 | // ------------------------------------------------------------------------------------------------- 30 | 31 | impl Converting for Frame { 32 | // TODO: Maybe make generic over `SurfaceListing`? 33 | // TODO: Do not allocate so much. Make benchmarks? 34 | fn to_array(&self, 35 | relative_position: Position, 36 | listing: &SurfaceListing) 37 | -> Vec { 38 | let mut result = Vec::new(); 39 | for frame in self.time_iter() { 40 | if let Mode::Workspace { is_active } = frame.get_mode() { 41 | if !is_active { 42 | continue; 43 | } 44 | } 45 | 46 | let pos = relative_position + frame.get_position(); 47 | if frame.get_sid().is_valid() { 48 | if let Some(ref mut array) = listing.get_renderer_context(frame.get_sid()) { 49 | for ref mut c in array.iter().rev() { 50 | result.push(c.moved(pos)); 51 | } 52 | } 53 | } else { 54 | result.append(&mut frame.to_array(pos, listing)); 55 | } 56 | } 57 | result 58 | } 59 | 60 | fn to_workspace_state(&self) -> WorkspaceState { 61 | let mut state = WorkspaceState::empty(); 62 | root_to_displays(self, &mut state.workspaces); 63 | state 64 | } 65 | } 66 | 67 | // ------------------------------------------------------------------------------------------------- 68 | 69 | fn root_to_displays(frame: &Frame, displays: &mut HashMap>) { 70 | if let Mode::Display { id } = frame.get_mode() { 71 | let mut workspaces = Vec::new(); 72 | display_to_workspaces(frame, &mut workspaces); 73 | workspaces.sort(); 74 | displays.insert(id, workspaces); 75 | } else { 76 | for subframe in frame.space_iter() { 77 | root_to_displays(&subframe, displays); 78 | } 79 | } 80 | } 81 | 82 | // ------------------------------------------------------------------------------------------------- 83 | 84 | fn display_to_workspaces(frame: &Frame, workspaces: &mut Vec) { 85 | if let Mode::Workspace { is_active } = frame.get_mode() { 86 | workspaces.push(WorkspaceInfo::new(frame.get_title(), is_active)); 87 | } else { 88 | for subframe in frame.space_iter() { 89 | display_to_workspaces(&subframe, workspaces); 90 | } 91 | } 92 | } 93 | 94 | // ------------------------------------------------------------------------------------------------- 95 | -------------------------------------------------------------------------------- /perceptia/perceptia/perceptia.rs: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of 2 | // the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/ 3 | 4 | #![cfg_attr(not(test), allow(unused_variables))] 5 | 6 | extern crate dharma; 7 | #[macro_use] 8 | extern crate timber; 9 | #[macro_use] 10 | extern crate cognitive_qualia as qualia; 11 | extern crate cognitive_inputs as inputs; 12 | extern crate cognitive_outputs as outputs; 13 | 14 | extern crate cognitive_aesthetics as aesthetics; 15 | extern crate cognitive_device_manager as device_manager; 16 | extern crate cognitive_exhibitor as exhibitor; 17 | extern crate cognitive_wayland_frontend as wayland_frontend; 18 | 19 | extern crate gears; 20 | extern crate coordination; 21 | 22 | mod aesthetics_module; 23 | mod device_manager_module; 24 | mod exhibitor_module; 25 | mod wayland_service; 26 | 27 | use dharma::{EventLoopInfo, Dispatcher, ServiceInfo, Signaler}; 28 | use coordination::{Context, Coordinator}; 29 | 30 | use aesthetics_module::AestheticsModuleConstructor; 31 | use device_manager_module::DeviceManagerModuleConstructor; 32 | use exhibitor_module::ExhibitorModuleConstructor; 33 | use wayland_service::WaylandServiceConstructor; 34 | 35 | fn main() { 36 | // Set panic hook: log the panic and quit application - we want to exit when one of threads 37 | // panics. 38 | std::panic::set_hook(Box::new(|info| gears::functions::panic_hook(info))); 39 | 40 | // Prepare tools 41 | let env = qualia::Env::create(qualia::LogDestination::LogFile, "perceptia"); 42 | let config = gears::Config::read_or_default(env.get_directories()); 43 | let keymap = inputs::Keymap::new(&env, config.get_keyboard_config()).unwrap(); 44 | let settings = qualia::Settings::new(keymap.get_settings()); 45 | 46 | // Prepare state 47 | let signaler = Signaler::new(); 48 | let mut dispatcher = Dispatcher::new(); 49 | let dispatcher_controller = dispatcher.get_controller(); 50 | let coordinator = Coordinator::new(signaler.clone(), dispatcher_controller.clone()); 51 | let context = Context::new(config.clone(), 52 | settings.clone(), 53 | signaler.clone(), 54 | dispatcher_controller.clone(), 55 | coordinator.clone()); 56 | 57 | // Create modules and services 58 | let aesthetics_module = AestheticsModuleConstructor::new(); 59 | let device_manager_module = DeviceManagerModuleConstructor::new(); 60 | let exhibitor_module = ExhibitorModuleConstructor::new(); 61 | let wayland_service = WaylandServiceConstructor::new(context.clone()); 62 | 63 | // Create loops 64 | let mut utils_info = 65 | EventLoopInfo::new("p:utils".to_owned(), signaler.clone(), context.clone()); 66 | 67 | let mut exhibitor_info = 68 | EventLoopInfo::new("p:exhibitor".to_owned(), signaler.clone(), context.clone()); 69 | 70 | let wayland_info = ServiceInfo::new("p:wayland".to_owned(), wayland_service); 71 | 72 | // Assign modules to threads 73 | utils_info.add_module(device_manager_module); 74 | utils_info.add_module(aesthetics_module); 75 | exhibitor_info.add_module(exhibitor_module); 76 | 77 | // Start threads 78 | let mut join_handles = std::collections::VecDeque::new(); 79 | join_handles.push_back(utils_info.start().unwrap()); 80 | join_handles.push_back(exhibitor_info.start().unwrap()); 81 | join_handles.push_back(wayland_info.start().unwrap()); 82 | 83 | // Start main loop 84 | dispatcher.run(); 85 | log_info1!("Stopped dispatcher!"); 86 | 87 | // Join threads 88 | while join_handles.len() > 0 { 89 | if join_handles.pop_front().unwrap().join().is_err() { 90 | log_warn2!("Error while joining thread"); 91 | } 92 | } 93 | log_info1!("Joined all threads!"); 94 | } 95 | -------------------------------------------------------------------------------- /cognitive/inputs/src/keyboard_state.rs: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of 2 | // the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/ 3 | 4 | //! This module contains functionality allowing to keep track of state of keyboard. 5 | 6 | // ------------------------------------------------------------------------------------------------- 7 | 8 | use xkbcommon::xkb; 9 | 10 | use qualia::{Illusion, KeyboardConfig, InputCode, InputValue}; 11 | 12 | use keymap::XkbKeymap; 13 | 14 | // ------------------------------------------------------------------------------------------------- 15 | 16 | /// This struct represents state of keyboard modifiers (shift, ctrl, etc...). 17 | #[derive(Clone, Copy, Debug, Eq, PartialEq)] 18 | pub struct KeyMods { 19 | pub depressed: u32, 20 | pub latched: u32, 21 | pub locked: u32, 22 | pub effective: u32, 23 | } 24 | 25 | // ------------------------------------------------------------------------------------------------- 26 | 27 | impl KeyMods { 28 | /// Constructs default `KeyMods`. 29 | pub fn default() -> Self { 30 | KeyMods { 31 | depressed: 0, 32 | latched: 0, 33 | locked: 0, 34 | effective: 0, 35 | } 36 | } 37 | 38 | /// Constructs `KeyMods` from given modifiers. 39 | pub fn new(depressed: u32, latched: u32, locked: u32, effective: u32) -> Self { 40 | KeyMods { 41 | depressed: depressed, 42 | latched: latched, 43 | locked: locked, 44 | effective: effective, 45 | } 46 | } 47 | } 48 | 49 | // ------------------------------------------------------------------------------------------------- 50 | 51 | /// Represents state of keyboard. 52 | pub struct KeyboardState { 53 | xkb_state: xkb::State, 54 | mods: KeyMods, 55 | } 56 | 57 | // ------------------------------------------------------------------------------------------------- 58 | 59 | impl KeyboardState { 60 | /// Constructs new `KeyboardState`. 61 | pub fn new(config: &KeyboardConfig) -> Result { 62 | let xkb_keymap = if let Some(xkb_keymap) = XkbKeymap::new(config) { 63 | xkb_keymap 64 | } else { 65 | return Err(Illusion::General(format!("Failed to create key map"))); 66 | }; 67 | 68 | Ok(KeyboardState { 69 | xkb_state: xkb::State::new(&xkb_keymap.keymap), 70 | mods: KeyMods::default(), 71 | }) 72 | } 73 | 74 | /// Updates state with given key. Returns `true` when modifiers changed, false otherwise. 75 | pub fn update(&mut self, code: InputCode, value: InputValue) -> bool { 76 | let direction = if value == 0 { 77 | xkb::KeyDirection::Up 78 | } else { 79 | xkb::KeyDirection::Down 80 | }; 81 | 82 | // Offset the key code by 8, as the evdev XKB rules reflect X's 83 | // broken key code system, which starts at 8. 84 | self.xkb_state.update_key(code as u32 + 8, direction); 85 | let mods = KeyMods::new(self.xkb_state.serialize_mods(xkb::STATE_MODS_DEPRESSED), 86 | self.xkb_state.serialize_mods(xkb::STATE_MODS_LATCHED), 87 | self.xkb_state.serialize_mods(xkb::STATE_MODS_LOCKED), 88 | self.xkb_state.serialize_mods(xkb::STATE_MODS_EFFECTIVE)); 89 | 90 | if mods != self.mods { 91 | self.mods = mods; 92 | true 93 | } else { 94 | false 95 | } 96 | } 97 | 98 | /// Returns state of modifiers. 99 | pub fn get_mods(&self) -> KeyMods { 100 | self.mods 101 | } 102 | } 103 | 104 | // ------------------------------------------------------------------------------------------------- 105 | -------------------------------------------------------------------------------- /perceptia/skylane_simple_framework/src/protocol/shm.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2017 The Perceptia Project Developers 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software 4 | // and associated documentation files (the "Software"), to deal in the Software without 5 | // restriction, including without limitation the rights to use, copy, modify, merge, publish, 6 | // distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the 7 | // Software is furnished to do so, subject to the following conditions: 8 | // 9 | // The above copyright notice and this permission notice shall be included in all copies or 10 | // substantial portions of the Software. 11 | // 12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING 13 | // BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 14 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 15 | // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 16 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 17 | 18 | //! Implementation of Wayland `wl_shm`, `wl_shm_pool` and `wl_buffer` objects. 19 | 20 | use skylane::client::{Bundle, Object, ObjectId, Task}; 21 | use skylane_protocols::client::Handler; 22 | use skylane_protocols::client::wayland::{wl_shm, wl_shm_pool, wl_buffer}; 23 | 24 | use proxy::ProxyRef; 25 | 26 | // ------------------------------------------------------------------------------------------------- 27 | 28 | /// Wayland `wl_shm` object. 29 | pub struct Shm {} 30 | 31 | // ------------------------------------------------------------------------------------------------- 32 | 33 | impl Shm { 34 | fn new(_proxy: ProxyRef) -> Self { 35 | Shm {} 36 | } 37 | 38 | pub fn new_object(proxy: ProxyRef) -> Box { 39 | Box::new(Handler::<_, wl_shm::Dispatcher>::new(Self::new(proxy))) 40 | } 41 | } 42 | 43 | // ------------------------------------------------------------------------------------------------- 44 | 45 | impl wl_shm::Interface for Shm { 46 | fn format(&mut self, _this_object_id: ObjectId, _bundle: &mut Bundle, _format: u32) -> Task { 47 | Task::None 48 | } 49 | } 50 | 51 | // ------------------------------------------------------------------------------------------------- 52 | 53 | /// Wayland `wl_shm_pool` object. 54 | pub struct ShmPool {} 55 | 56 | // ------------------------------------------------------------------------------------------------- 57 | 58 | impl ShmPool { 59 | fn new(_proxy: ProxyRef) -> Self { 60 | ShmPool {} 61 | } 62 | 63 | pub fn new_object(proxy: ProxyRef) -> Box { 64 | Box::new(Handler::<_, wl_shm_pool::Dispatcher>::new(Self::new(proxy))) 65 | } 66 | } 67 | 68 | // ------------------------------------------------------------------------------------------------- 69 | 70 | impl wl_shm_pool::Interface for ShmPool {} 71 | 72 | // ------------------------------------------------------------------------------------------------- 73 | 74 | /// Wayland `wl_buffer` object. 75 | pub struct ShmBuffer {} 76 | 77 | // ------------------------------------------------------------------------------------------------- 78 | 79 | impl ShmBuffer { 80 | fn new(_proxy: ProxyRef) -> Self { 81 | ShmBuffer {} 82 | } 83 | 84 | pub fn new_object(proxy: ProxyRef) -> Box { 85 | Box::new(Handler::<_, wl_buffer::Dispatcher>::new(Self::new(proxy))) 86 | } 87 | } 88 | 89 | // ------------------------------------------------------------------------------------------------- 90 | 91 | impl wl_buffer::Interface for ShmBuffer { 92 | fn release(&mut self, _this_object_id: ObjectId, _bundle: &mut Bundle) -> Task { 93 | Task::None 94 | } 95 | } 96 | 97 | // ------------------------------------------------------------------------------------------------- 98 | -------------------------------------------------------------------------------- /info/concepts.md: -------------------------------------------------------------------------------- 1 | Concepts 2 | ======== 3 | 4 | Nomenclature and key concepts needed for new-coming developers to dive in easier: 5 | 6 | * **surface** - a window (in Wayland language) 7 | 8 | * **sid** - in `perceptia` every surface have ID, `sid` is a Surface ID 9 | 10 | * **frame** - tree-like structure containing information about position and size of surface. Set of 11 | all frames is similar concept to `i3`'s tree 12 | 13 | * **selection** - currently selected frame. Selection may include many surfaces. It is guaranteed 14 | there always exists a selection 15 | 16 | * **anchored frame** - frame which is under automatic management. `perceptia` will take care about 17 | resizing or moving it 18 | 19 | * **floating frame** - any frame which is not anchored 20 | 21 | * frame layouts: 22 | 23 | - **horizontal** - frames are places aside another horizontally (on the right or left of each 24 | other) 25 | 26 | - **vertical** - frames are places aside another vertically (above or below of each other) 27 | 28 | - **stacked** - frames have the same size and position; only one frame is visible at a time 29 | 30 | * **exhibitor** - logical part of program which take care about compositing, drawing, frame 31 | management, input handling (if you wanted make `perceptia` an X compositor you would probably 32 | remove everything except exhibitor) 33 | 34 | * **output** - monitor understood as physical object 35 | 36 | * **display** - monitor understood as abstract concept (e.g. a drawing thread) 37 | 38 | * **workspace** - special frame containing all surfaces exhibited on given display. There may be 39 | other workspaces on the same displays but will be invisible. 40 | 41 | * **root frame** - a single frame containing all known frames 42 | 43 | * **global coordinates** - coordinates describing position of display 44 | 45 | * **workspace coordinates** - coordinates of surfaces within given display (workspace) 46 | 47 | * **key modes** - concept similar to `vim` modes which in basics allows to change set of active key 48 | bindings. 49 | 50 | - **insert mode** - (default mode) most keys are passed to clients, rare key bindings should 51 | containt `[meta]` or `[alt]` key. 52 | 53 | - **normal mode** - provides fast, composable bindings in `vim` style. For example depending on 54 | configuration `[j] [right]` could make focused surface jump to the right, `[w] [1]` focus 55 | worspace `1` or `[f] [down] [down]` focus surface two frames below currently focused one. Keys 56 | pressed in normal mode are not passed to clients. 57 | 58 | * **config** - not mutable user configuration (compiled in or read from text file) 59 | 60 | * **settings** - not mutable information gathered from system (wayland socket, environment 61 | variables, program arguments) 62 | 63 | Framing 64 | ------- 65 | 66 | Framing in `perceptia` mostly resembles concepts that can be found in `i3`. All frames are placed in 67 | one tree-like structure where frames can be organized in horizontal, vertical or stacked layouts. 68 | 69 | In future per-workspace strategies will be added to allow more automatic management like in 70 | `Awesome`. 71 | 72 | Exhibitor provides commands composed of action, direction and magnitude. Some available actions are: 73 | 74 | * **jumping** - jumping over neighbouring frame 75 | 76 | * **diving** - incorporating one frame into another 77 | 78 | * **focusing** - changing focus of frames 79 | 80 | Some available directions are: 81 | 82 | * north (up, above), east (right), south (down, below), west (left) - to perform actions in 83 | output plane 84 | 85 | * backward (back in time, most recently used), forward (forward in time, the oldest used) - to 86 | perform actions in history order 87 | 88 | * begin (start, head), end (finish, tail) - to perform actions perpendicular to output plane (for 89 | example **ramification** and **exaltation** is jumping to begin and end respectively) 90 | 91 | --- 92 | 93 | Now you know theory. For implementation details you can refer to code. 94 | 95 | -------------------------------------------------------------------------------- /cognitive/wayland_frontend/src/protocol/registry.rs: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of 2 | // the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/ 3 | 4 | //! Implementation of Wayland `wl_registry` object. 5 | 6 | use skylane::server as wl; 7 | use skylane::server::{Bundle, Object, ObjectId, Task}; 8 | use skylane_protocols::server::Handler; 9 | use skylane_protocols::server::wayland::wl_display; 10 | use skylane_protocols::server::wayland::wl_registry; 11 | 12 | use proxy::ProxyRef; 13 | 14 | // ------------------------------------------------------------------------------------------------- 15 | 16 | /// Wayland `wl_registry` object. 17 | pub struct Registry { 18 | proxy: ProxyRef, 19 | } 20 | 21 | // ------------------------------------------------------------------------------------------------- 22 | 23 | impl Registry { 24 | /// Creates new `Registry` and posts current globals. 25 | fn new(oid: ObjectId, proxy_ref: ProxyRef) -> Self { 26 | { 27 | let proxy = proxy_ref.borrow(); 28 | let socket = proxy.get_socket(); 29 | for (name, global) in proxy.get_globals() { 30 | send!(wl_registry::global(&socket, oid, *name, global.interface, global.version)); 31 | } 32 | } 33 | 34 | Registry { proxy: proxy_ref } 35 | } 36 | 37 | pub fn new_object(oid: ObjectId, proxy_ref: ProxyRef) -> Box { 38 | Box::new(Handler::<_, wl_registry::Dispatcher>::new(Self::new(oid, proxy_ref))) 39 | } 40 | } 41 | 42 | // ------------------------------------------------------------------------------------------------- 43 | 44 | impl wl_registry::Interface for Registry { 45 | fn bind(&mut self, 46 | this_object_id: ObjectId, 47 | bundle: &mut Bundle, 48 | name: u32, 49 | interface: String, 50 | version: u32, 51 | new_object_id: ObjectId) 52 | -> Task { 53 | let result = { 54 | let proxy = self.proxy.borrow(); 55 | if let Some(global) = proxy.get_globals().get(&name) { 56 | if global.interface != interface { 57 | Err(format!("Interface names do not match. Expected '{}', received: '{}'.", 58 | global.interface, 59 | interface)) 60 | } else if version == 0 { 61 | Err(format!("Invalid version for global '{}': 0 is not valid version.", 62 | interface)) 63 | } else if global.version < version { 64 | Err(format!("Invalid version for global '{}': \ 65 | server has: {}, client wanted: {}.", 66 | interface, 67 | global.version, 68 | version)) 69 | } else { 70 | Ok(global.clone()) 71 | } 72 | } else { 73 | Err(format!("Requested for not registered global '{}' ({})", interface, name)) 74 | } 75 | }; 76 | 77 | match result { 78 | Ok(global) => { 79 | let object = global.construct(new_object_id, version, self.proxy.clone()); 80 | Task::Create { 81 | id: new_object_id, 82 | object: object, 83 | } 84 | } 85 | Err(msg) => { 86 | log_warn1!("{}", msg); 87 | send!(wl_display::error(&bundle.get_socket(), 88 | wl::DISPLAY_ID, 89 | this_object_id, 90 | name, 91 | &msg)); 92 | Task::None 93 | } 94 | } 95 | } 96 | } 97 | 98 | // ------------------------------------------------------------------------------------------------- 99 | -------------------------------------------------------------------------------- /cognitive/device_manager/src/device_access.rs: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of 2 | // the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/ 3 | 4 | //! This module contains functionality required for accessing devices. 5 | 6 | // ------------------------------------------------------------------------------------------------- 7 | 8 | use std::cell::RefCell; 9 | use std::collections::BTreeSet; 10 | use std::path::Path; 11 | use std::os::unix::io; 12 | 13 | use nix::{self, Errno}; 14 | use nix::fcntl::{open, OFlag}; 15 | use nix::sys::stat::{Mode, stat}; 16 | 17 | use qualia::Illusion; 18 | 19 | use ipc::Logind; 20 | 21 | // ------------------------------------------------------------------------------------------------- 22 | 23 | /// Opener of devices with restricted access. 24 | /// 25 | /// If application does not have enough permissions to open device `RestrictedOpener` asks `logind` 26 | /// to open it for him. Communication is done via `dbus`. 27 | /// 28 | /// `logind` allows to take device only once, and further tries will fail. `RestrictedOpener` 29 | /// handles IDs of open devices and releases them before next take. 30 | pub struct RestrictedOpener { 31 | logind: Logind, 32 | taken_devices: RefCell>, 33 | } 34 | 35 | // ------------------------------------------------------------------------------------------------- 36 | 37 | impl RestrictedOpener { 38 | /// Constructs new `RestrictedOpener`. 39 | pub fn new() -> Self { 40 | RestrictedOpener { 41 | logind: Logind::new(), 42 | taken_devices: RefCell::new(BTreeSet::new()), 43 | } 44 | } 45 | 46 | /// Tries to open device. If we have insufficient permissions asks `logind` to do it for us. 47 | pub fn open(&self, path: &Path, oflag: OFlag, mode: Mode) -> Result { 48 | match open(path, oflag, mode) { 49 | Ok(fd) => Ok(fd), 50 | Err(nix::Error::Sys(errno)) => { 51 | if (errno == Errno::EPERM) || (errno == Errno::EACCES) { 52 | self.take_device(path) 53 | } else { 54 | Err(Illusion::InvalidArgument(errno.desc().to_owned())) 55 | } 56 | } 57 | Err(nix::Error::InvalidPath) => { 58 | Err(Illusion::InvalidArgument(format!("Path '{:?}' does not exist!", path))) 59 | } 60 | } 61 | } 62 | 63 | /// Initialize connection to `logind`. 64 | pub fn initialize_ipc(&mut self) -> Result<(), Illusion> { 65 | self.logind.initialize() 66 | } 67 | } 68 | 69 | // ------------------------------------------------------------------------------------------------- 70 | 71 | impl RestrictedOpener { 72 | /// Takes device from `logind` via `dbus`. 73 | fn take_device(&self, path: &Path) -> Result { 74 | match stat(path) { 75 | Ok(st) => { 76 | let rdev = st.st_rdev as u64; 77 | 78 | // If device is taken - release it first 79 | let contains = self.taken_devices.borrow().contains(&rdev); 80 | if contains { 81 | if self.logind.release_device(rdev).is_ok() { 82 | self.taken_devices.borrow_mut().remove(&rdev); 83 | } 84 | } 85 | 86 | // Take the device 87 | let result = self.logind.take_device(rdev); 88 | if result.is_ok() { 89 | self.taken_devices.borrow_mut().insert(rdev); 90 | } 91 | result 92 | } 93 | Err(err) => { 94 | Err(Illusion::General(format!("Could not stat file '{:?}': {:?}", path, err))) 95 | } 96 | } 97 | } 98 | } 99 | 100 | // ------------------------------------------------------------------------------------------------- 101 | -------------------------------------------------------------------------------- /perceptia/skylane_simple_framework/src/protocol/drm.rs: -------------------------------------------------------------------------------- 1 | // Copyright 2017 The Perceptia Project Developers 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software 4 | // and associated documentation files (the "Software"), to deal in the Software without 5 | // restriction, including without limitation the rights to use, copy, modify, merge, publish, 6 | // distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the 7 | // Software is furnished to do so, subject to the following conditions: 8 | // 9 | // The above copyright notice and this permission notice shall be included in all copies or 10 | // substantial portions of the Software. 11 | // 12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING 13 | // BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 14 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 15 | // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 16 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 17 | 18 | //! Implementation of Wayland `wl_drm` object. 19 | 20 | use skylane::client::{Bundle, Object, ObjectId, Task}; 21 | use skylane_protocols::client::Handler; 22 | use skylane_protocols::client::drm::wl_drm; 23 | use skylane_protocols::client::wayland::wl_buffer; 24 | 25 | use proxy::ProxyRef; 26 | 27 | // ------------------------------------------------------------------------------------------------- 28 | 29 | /// Wayland `wl_drm` object. 30 | pub struct Drm { 31 | proxy: ProxyRef, 32 | } 33 | 34 | // ------------------------------------------------------------------------------------------------- 35 | 36 | impl Drm { 37 | fn new(proxy: ProxyRef) -> Self { 38 | Drm { proxy: proxy } 39 | } 40 | 41 | pub fn new_object(proxy: ProxyRef) -> Box { 42 | Box::new(Handler::<_, wl_drm::Dispatcher>::new(Self::new(proxy))) 43 | } 44 | } 45 | 46 | // ------------------------------------------------------------------------------------------------- 47 | 48 | impl wl_drm::Interface for Drm { 49 | fn device(&mut self, _this_object_id: ObjectId, _bundle: &mut Bundle, name: String) -> Task { 50 | self.proxy.borrow_mut().set_drm_device_name(name); 51 | Task::None 52 | } 53 | 54 | fn format(&mut self, _this_object_id: ObjectId, _bundle: &mut Bundle, _format: u32) -> Task { 55 | // Nothing to do so far 56 | Task::None 57 | } 58 | 59 | fn authenticated(&mut self, _this_object_id: ObjectId, _bundle: &mut Bundle) -> Task { 60 | self.proxy.borrow_mut().drm_authenticated(); 61 | Task::None 62 | } 63 | 64 | fn capabilities(&mut self, 65 | _this_object_id: ObjectId, 66 | _bundle: &mut Bundle, 67 | _value: u32) 68 | -> Task { 69 | // Nothing to do so far 70 | Task::None 71 | } 72 | } 73 | 74 | // ------------------------------------------------------------------------------------------------- 75 | 76 | /// Wayland `wl_buffer` object. 77 | pub struct DrmBuffer {} 78 | 79 | // ------------------------------------------------------------------------------------------------- 80 | 81 | impl DrmBuffer { 82 | fn new(_proxy: ProxyRef) -> Self { 83 | DrmBuffer {} 84 | } 85 | 86 | pub fn new_object(proxy: ProxyRef) -> Box { 87 | Box::new(Handler::<_, wl_buffer::Dispatcher>::new(Self::new(proxy))) 88 | } 89 | } 90 | 91 | // ------------------------------------------------------------------------------------------------- 92 | 93 | impl wl_buffer::Interface for DrmBuffer { 94 | fn release(&mut self, _this_object_id: ObjectId, _bundle: &mut Bundle) -> Task { 95 | Task::None 96 | } 97 | } 98 | 99 | // ------------------------------------------------------------------------------------------------- 100 | -------------------------------------------------------------------------------- /perceptia/perceptia/aesthetics_module.rs: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of 2 | // the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/ 3 | 4 | //! Implementation of `dharma::Module` for Aesthetics. 5 | 6 | // ------------------------------------------------------------------------------------------------- 7 | 8 | use dharma::{Module, ModuleConstructor, SignalId}; 9 | use qualia::{perceptron, Perceptron}; 10 | use coordination::{Context, Coordinator}; 11 | use aesthetics::Aesthetics; 12 | 13 | // ------------------------------------------------------------------------------------------------- 14 | 15 | /// Implementation of `dharma::Module` for Aesthetics. 16 | pub struct AestheticsModule<'a> { 17 | aesthetics: Aesthetics<'a, Coordinator>, 18 | } 19 | 20 | // ------------------------------------------------------------------------------------------------- 21 | 22 | impl<'a> AestheticsModule<'a> { 23 | /// Constructs new `AestheticsModule`. 24 | pub fn new(context: &mut Context) -> Self { 25 | AestheticsModule { 26 | aesthetics: Aesthetics::new(context.get_coordinator().clone(), 27 | context.get_config().get_aesthetics_config().clone()), 28 | } 29 | } 30 | } 31 | 32 | // ------------------------------------------------------------------------------------------------- 33 | 34 | impl<'a> Module for AestheticsModule<'a> { 35 | type T = Perceptron; 36 | type C = Context; 37 | 38 | fn get_signals(&self) -> Vec { 39 | vec![perceptron::DISPLAY_CREATED, 40 | perceptron::CURSOR_SURFACE_CHANGE, 41 | perceptron::BACKGROUND_SURFACE_CHANGE, 42 | perceptron::POINTER_FOCUS_CHANGED, 43 | perceptron::SURFACE_DESTROYED, 44 | perceptron::WORKSPACE_STATE_CHANGED, 45 | perceptron::TIMER_500] 46 | } 47 | 48 | fn initialize(&mut self) { 49 | log_info1!("Aesthetics module initialized"); 50 | } 51 | 52 | fn execute(&mut self, package: &Self::T) { 53 | match *package { 54 | Perceptron::CursorSurfaceChange(sid) => self.aesthetics.on_cursor_surface_change(sid), 55 | Perceptron::PointerFocusChanged(old_pfsid, new_pfsid, _) => { 56 | self.aesthetics.on_pointer_focus_changed(old_pfsid, new_pfsid); 57 | } 58 | Perceptron::WorkspaceStateChanged => self.aesthetics.on_workspace_state_changed(), 59 | Perceptron::SurfaceDestroyed(sid) => self.aesthetics.on_surface_destroyed(sid), 60 | Perceptron::DisplayCreated(ref output) => self.aesthetics.on_display_created(output), 61 | Perceptron::BackgroundSurfaceChange(sid) => { 62 | self.aesthetics.on_background_surface_change(sid); 63 | } 64 | Perceptron::Timer500 => self.aesthetics.on_timer_500(), 65 | _ => {} 66 | } 67 | } 68 | 69 | fn finalize(&mut self) { 70 | log_info1!("Aesthetics module finalized"); 71 | } 72 | } 73 | 74 | // ------------------------------------------------------------------------------------------------- 75 | 76 | pub struct AestheticsModuleConstructor {} 77 | 78 | // ------------------------------------------------------------------------------------------------- 79 | 80 | impl AestheticsModuleConstructor { 81 | /// Constructs new `AestheticsModuleConstructor`. 82 | pub fn new() -> Box> { 83 | Box::new(AestheticsModuleConstructor {}) 84 | } 85 | } 86 | 87 | // ------------------------------------------------------------------------------------------------- 88 | 89 | impl ModuleConstructor for AestheticsModuleConstructor { 90 | type T = Perceptron; 91 | type C = Context; 92 | 93 | fn construct(&self, context: &mut Self::C) -> Box> { 94 | Box::new(AestheticsModule::new(context)) 95 | } 96 | } 97 | 98 | // ------------------------------------------------------------------------------------------------- 99 | -------------------------------------------------------------------------------- /cognitive/aesthetics/src/background.rs: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of 2 | // the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/ 3 | 4 | //! This module contains functionality related to background image. 5 | 6 | // ------------------------------------------------------------------------------------------------- 7 | 8 | use std::path::PathBuf; 9 | 10 | use image; 11 | 12 | use qualia::{AestheticsConfig, Buffer, PixelFormat, SurfaceId, AestheticsCoordinationTrait}; 13 | 14 | // ------------------------------------------------------------------------------------------------- 15 | 16 | /// State of the background. 17 | pub struct Background 18 | where C: AestheticsCoordinationTrait 19 | { 20 | /// Surface ID of the background. 21 | background_sid: SurfaceId, 22 | 23 | /// Path to background image from configuration. 24 | background_path: Option, 25 | 26 | /// Buffer for the background image. 27 | buffer: Buffer, 28 | 29 | /// Coordinator. 30 | coordinator: C, 31 | } 32 | 33 | // ------------------------------------------------------------------------------------------------- 34 | 35 | impl Background 36 | where C: AestheticsCoordinationTrait 37 | { 38 | /// Constructs new `Background`. 39 | pub fn new(coordinator: C, config: AestheticsConfig) -> Self { 40 | Background { 41 | background_sid: SurfaceId::invalid(), 42 | background_path: config.background_path, 43 | buffer: Buffer::empty(), 44 | coordinator: coordinator, 45 | } 46 | } 47 | 48 | /// Reads in background image file and creates surface to be displayed as background. 49 | /// 50 | /// TODO: Background currently is placed at top left corner. Make it configurable to be 51 | /// centred, stretched, etc... 52 | /// 53 | /// NOTE: `image::open` spawns four threads when opening JPEG images and does not close them. 54 | pub fn set_background(&mut self) { 55 | if let Some(ref path) = self.background_path { 56 | match image::open(&path) { 57 | Ok(img) => { 58 | let rgba = img.to_rgba(); 59 | let f = PixelFormat::ABGR8888; 60 | let w = rgba.width() as usize; 61 | let h = rgba.height() as usize; 62 | let s = w * f.get_size(); 63 | let d = rgba.into_raw(); 64 | 65 | self.buffer = Buffer::new(f, w, h, s, d); 66 | 67 | let memory = unsafe { self.buffer.as_memory() }; 68 | let background_sid = self.coordinator.create_surface(); 69 | let bid = self.coordinator.create_memory_pool(memory); 70 | 71 | if let Some(mvid) = self.coordinator.create_memory_view(bid, f, 0, w, h, s) { 72 | self.coordinator.attach_shm(mvid, background_sid); 73 | self.coordinator.commit_surface(background_sid); 74 | self.coordinator.set_surface_as_background(background_sid); 75 | } else { 76 | log_warn1!("Failed to create memory view for background"); 77 | } 78 | } 79 | Err(err) => log_warn1!("Failed to open background file: {:?}", err), 80 | } 81 | } 82 | } 83 | } 84 | 85 | // ------------------------------------------------------------------------------------------------- 86 | 87 | impl Background 88 | where C: AestheticsCoordinationTrait 89 | { 90 | /// Handles background surface change request. 91 | pub fn on_surface_change(&mut self, sid: SurfaceId) { 92 | self.background_sid = sid; 93 | } 94 | 95 | /// Handles creation of display. 96 | pub fn on_display_created(&mut self) { 97 | if !self.background_sid.is_valid() { 98 | self.set_background(); 99 | } 100 | } 101 | } 102 | 103 | // ------------------------------------------------------------------------------------------------- 104 | -------------------------------------------------------------------------------- /cognitive/qualia/src/macros.rs: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of 2 | // the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/ 3 | 4 | //! This module contains commonly used macros. 5 | 6 | // ------------------------------------------------------------------------------------------------- 7 | 8 | /// This macro helps define structure being `Rc` for another structure and implements 9 | /// methods for borrowing it. Borrowing it when already borrowed mutably is program logic error 10 | /// and suitable warning is logged in such case. 11 | #[macro_export] 12 | macro_rules! define_ref { 13 | (struct $name:ty as $ref_name:ident) => { 14 | #[derive(Clone)] 15 | pub struct $ref_name (std::rc::Rc>); 16 | 17 | #[allow(dead_code)] 18 | impl $ref_name { 19 | define_ref!(_impl_ $name as $ref_name); 20 | } 21 | }; 22 | 23 | (trait $name:ty as $ref_name:ident) => { 24 | #[derive(Clone)] 25 | pub struct $ref_name (std::rc::Rc>) where T: $name; 26 | 27 | #[allow(dead_code)] 28 | impl $ref_name where T: $name { 29 | define_ref!(_impl_ T as $ref_name); 30 | } 31 | }; 32 | 33 | (_impl_ $name:ty as $ref_name:ident) => { 34 | pub fn new(obj: $name) -> Self { 35 | $ref_name(std::rc::Rc::new(std::cell::RefCell::new(obj))) 36 | } 37 | 38 | pub fn transform(obj: std::rc::Rc>) -> Self { 39 | $ref_name(obj) 40 | } 41 | 42 | pub fn borrow(&self) -> std::cell::Ref<$name> { 43 | match self.0.try_borrow() { 44 | Ok(obj) => { 45 | obj 46 | } 47 | Err(err) => { 48 | let msg = format!("Failed to borrow {}! \ 49 | This is fail of programs internal logic. {:?}", 50 | stringify!($name), err); 51 | log_fatal!("{}", msg); 52 | panic!(msg); 53 | } 54 | } 55 | } 56 | 57 | pub fn borrow_mut(&self) -> std::cell::RefMut<$name> { 58 | match self.0.try_borrow_mut() { 59 | Ok(obj) => { 60 | obj 61 | } 62 | Err(err) => { 63 | let msg = format!("Failed to borrow {} mutably! \ 64 | This is fail of programs internal logic. {:?}", 65 | stringify!($name), err); 66 | log_fatal!("{}", msg); 67 | panic!(msg); 68 | } 69 | } 70 | } 71 | 72 | pub fn downgrade(&self) -> std::rc::Weak> { 73 | std::rc::Rc::downgrade(&self.0) 74 | } 75 | }; 76 | } 77 | 78 | // ------------------------------------------------------------------------------------------------- 79 | 80 | /// This macro helps implement ID type. 81 | #[macro_export] 82 | macro_rules! define_id { 83 | ($name:ident: $ty:ty) => { 84 | #[derive(Clone, Copy, Eq, PartialEq, Hash, Debug)] 85 | pub struct $name($ty); 86 | define_id!{_impl_ $name} 87 | }; 88 | 89 | (pub $name:ident: $ty:ty) => { 90 | #[derive(Clone, Copy, Eq, PartialEq, Hash, Debug)] 91 | pub struct $name($ty); 92 | define_id!{_impl_ $name} 93 | }; 94 | 95 | {_impl_ $name:ident} => { 96 | impl $name { 97 | pub fn initial() -> Self { 98 | $name(1) 99 | } 100 | 101 | pub fn incremented(id: &Self) -> Self { 102 | $name(id.0 + 1) 103 | } 104 | 105 | pub fn increment(&mut self) -> Self { 106 | self.0 += 1; 107 | *self 108 | } 109 | } 110 | }; 111 | } 112 | 113 | // ------------------------------------------------------------------------------------------------- 114 | -------------------------------------------------------------------------------- /cognitive/exhibitor/src/surface_history.rs: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of 2 | // the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/ 3 | 4 | //! This module define surface history functionality. 5 | 6 | // TODO: Add unit tests. 7 | 8 | // ------------------------------------------------------------------------------------------------- 9 | 10 | // TODO: Check what is better: VecDeque or LinkedList. 11 | use std::collections::VecDeque as Ordering; 12 | 13 | use qualia::SurfaceId; 14 | 15 | // ------------------------------------------------------------------------------------------------- 16 | 17 | mod magic { 18 | pub const AVARAGE_NUM_SURFACES: usize = 10; 19 | pub const PEEK_TO_AVARAGE_RATIO: usize = 3; 20 | pub const OPTIMAL_TO_AVARAGE_RATIO: usize = 2; 21 | } 22 | 23 | // ------------------------------------------------------------------------------------------------- 24 | 25 | /// Provides functionality to manage surface history as resizable list. 26 | pub struct SurfaceHistory { 27 | history: Ordering, 28 | } 29 | 30 | // ------------------------------------------------------------------------------------------------- 31 | 32 | impl SurfaceHistory { 33 | /// `SurfaceHistory` constructor. 34 | pub fn new() -> Self { 35 | SurfaceHistory { history: Ordering::with_capacity(magic::AVARAGE_NUM_SURFACES) } 36 | } 37 | 38 | /// Add surface as the latest in history. 39 | pub fn add(&mut self, sid: SurfaceId) { 40 | self.history.push_front(sid); 41 | } 42 | 43 | /// Return `n`th element from begin. If `n` is negative, return `n`th element from end. 44 | pub fn get_nth(&self, n: isize) -> Option { 45 | if n < 0 { 46 | let m = -n as usize; 47 | self.history.get(self.history.len() - m).cloned() 48 | } else { 49 | self.history.get(n as usize).cloned() 50 | } 51 | } 52 | 53 | /// Make given surface the latest in history. 54 | pub fn pop(&mut self, sid: SurfaceId) { 55 | self.simple_remove(sid); 56 | self.add(sid); 57 | } 58 | 59 | /// Remove surface. Shrink underlying memory pool if needed. 60 | pub fn remove(&mut self, sid: SurfaceId) { 61 | self.simple_remove(sid); 62 | 63 | let len = self.history.len(); 64 | let capacity = self.history.capacity(); 65 | if (len > magic::AVARAGE_NUM_SURFACES) && 66 | ((magic::PEEK_TO_AVARAGE_RATIO * len) > capacity) { 67 | self.history.truncate(magic::OPTIMAL_TO_AVARAGE_RATIO * len); 68 | } 69 | } 70 | 71 | /// Remove surface without shrinking memory pool. 72 | fn simple_remove(&mut self, sid: SurfaceId) { 73 | let len = self.history.len(); 74 | for i in 0..len { 75 | if *self.history.get(i).unwrap() == sid { 76 | self.history.remove(i); 77 | break; 78 | } 79 | } 80 | } 81 | 82 | /// Return iterator for `SurfaceHistory`. 83 | pub fn iter(&self) -> Iter { 84 | Iter::new(self) 85 | } 86 | } 87 | 88 | // ------------------------------------------------------------------------------------------------- 89 | 90 | pub struct Iter<'a> { 91 | history: &'a SurfaceHistory, 92 | pos: isize, 93 | } 94 | 95 | // ------------------------------------------------------------------------------------------------- 96 | 97 | impl<'a> Iter<'a> { 98 | /// `Iter` constructor. 99 | fn new(history: &'a SurfaceHistory) -> Self { 100 | Iter { 101 | history: history, 102 | pos: -1, 103 | } 104 | } 105 | } 106 | 107 | // ------------------------------------------------------------------------------------------------- 108 | 109 | impl<'a> Iterator for Iter<'a> { 110 | type Item = SurfaceId; 111 | 112 | fn next(&mut self) -> Option { 113 | self.pos += 1; 114 | self.history.get_nth(self.pos) 115 | } 116 | } 117 | 118 | // ------------------------------------------------------------------------------------------------- 119 | -------------------------------------------------------------------------------- /cognitive/dharma/src/system.rs: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of 2 | // the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/ 3 | 4 | //! This module contains helper functionality for handling system signals. 5 | 6 | // ------------------------------------------------------------------------------------------------- 7 | 8 | use std::os::unix::io::{RawFd, AsRawFd}; 9 | use nix::sys::{signal, signalfd}; 10 | 11 | use dispatcher::{DispatcherController, EventHandler, EventKind}; 12 | use signaler::Signaler; 13 | 14 | // ------------------------------------------------------------------------------------------------- 15 | 16 | /// Blocks signals `SIGINT`, `SIGTERM`, `SIGUSR1` and `SIGUSR2` for current thread. 17 | pub fn block_signals() { 18 | let mut mask = signal::SigSet::empty(); 19 | mask.add(signal::SIGINT); 20 | mask.add(signal::SIGTERM); 21 | mask.add(signal::SIGUSR1); 22 | mask.add(signal::SIGUSR2); 23 | mask.thread_block().unwrap(); 24 | } 25 | 26 | // ------------------------------------------------------------------------------------------------- 27 | 28 | /// Unblocks signals `SIGINT`, `SIGTERM`, `SIGUSR1` and `SIGUSR2` for current thread. 29 | pub fn unblock_signals() { 30 | let mut mask = signal::SigSet::empty(); 31 | mask.add(signal::SIGINT); 32 | mask.add(signal::SIGTERM); 33 | mask.add(signal::SIGUSR1); 34 | mask.add(signal::SIGUSR2); 35 | mask.thread_unblock().unwrap(); 36 | } 37 | 38 | // ------------------------------------------------------------------------------------------------- 39 | 40 | /// Implementation of `dharma::EventHandler` for handling system signals synchronously. For this to 41 | /// work receiving of signals `SIGINT` and `SIGTERM` must be blocked in all threads in application. 42 | /// Otherwise non-blocking threads will catch all signals. 43 | pub struct SignalEventHandler

44 | where P: Clone + Send + 'static 45 | { 46 | fd: signalfd::SignalFd, 47 | dispatcher: DispatcherController, 48 | signaler: Signaler

, 49 | } 50 | 51 | // ------------------------------------------------------------------------------------------------- 52 | 53 | impl

SignalEventHandler

54 | where P: Clone + Send + 'static 55 | { 56 | /// `SignalEventHandler` constructor. Creates `SignalEventHandler` ready for handling `SIGINT` 57 | /// and `SIGTERM` signals. 58 | pub fn new(dispatcher: DispatcherController, signaler: Signaler

) -> Self { 59 | let mut mask = signal::SigSet::empty(); 60 | mask.add(signal::SIGINT); 61 | mask.add(signal::SIGTERM); 62 | SignalEventHandler { 63 | fd: signalfd::SignalFd::new(&mask).unwrap(), 64 | dispatcher: dispatcher, 65 | signaler: signaler, 66 | } 67 | } 68 | } 69 | 70 | // ------------------------------------------------------------------------------------------------- 71 | 72 | impl

EventHandler for SignalEventHandler

73 | where P: Clone + Send + 'static 74 | { 75 | fn get_fd(&self) -> RawFd { 76 | self.fd.as_raw_fd() 77 | } 78 | 79 | fn process_event(&mut self, _: EventKind) { 80 | match self.fd.read_signal() { 81 | Ok(ossi) => { 82 | match ossi { 83 | Some(ssi) => { 84 | // FIXME: Do signals have correct type in `nix`? 85 | if (ssi.ssi_signo == signal::SIGINT as u32) || 86 | (ssi.ssi_signo == signal::SIGTERM as u32) { 87 | self.dispatcher.stop(); 88 | self.signaler.terminate(); 89 | } 90 | } 91 | None => { 92 | panic!("Received invalid siginfo!"); 93 | } 94 | } 95 | } 96 | Err(err) => { 97 | panic!("Error occurred during processing signal! ({:?})", err); 98 | } 99 | } 100 | } 101 | } 102 | 103 | // ------------------------------------------------------------------------------------------------- 104 | -------------------------------------------------------------------------------- /perceptia/perceptia/device_manager_module.rs: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of 2 | // the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/ 3 | 4 | //! Implementation of `dharma::Module` for Device Manager. 5 | 6 | // ------------------------------------------------------------------------------------------------- 7 | 8 | use dharma::{Module, ModuleConstructor, SignalId}; 9 | use qualia::{Perceptron, perceptron}; 10 | use coordination::{Context, Coordinator}; 11 | use gears::{InputManager, InputForwarder}; 12 | use device_manager::DeviceManager; 13 | 14 | // ------------------------------------------------------------------------------------------------- 15 | 16 | pub struct DeviceManagerModule { 17 | manager: DeviceManager, 18 | } 19 | 20 | // ------------------------------------------------------------------------------------------------- 21 | 22 | impl DeviceManagerModule { 23 | /// `DeviceManagerModule` constructor. 24 | pub fn new(context: &mut Context) -> Self { 25 | let coordinator = context.get_coordinator().clone(); 26 | let signaler = context.get_signaler().clone(); 27 | let config = context.get_config(); 28 | 29 | // Construct `InputManager` implementing `InputHandling`. 30 | let input_manager = InputManager::new(config.get_keybindings_config(), signaler.clone()); 31 | 32 | // Construct `InputForwarder` implementing `InputForwarding`. 33 | let input_forwarder = InputForwarder::new(signaler, context.get_reference_time()); 34 | 35 | // Construct the module. 36 | DeviceManagerModule { 37 | manager: DeviceManager::new(Box::new(input_manager), 38 | Box::new(input_forwarder), 39 | config.get_input_config().clone(), 40 | coordinator), 41 | } 42 | } 43 | } 44 | 45 | // ------------------------------------------------------------------------------------------------- 46 | 47 | impl Module for DeviceManagerModule { 48 | type T = Perceptron; 49 | type C = Context; 50 | 51 | fn get_signals(&self) -> Vec { 52 | vec![perceptron::SUSPEND, 53 | perceptron::WAKEUP, 54 | perceptron::INPUTS_CHANGED, 55 | perceptron::OUTPUTS_CHANGED] 56 | } 57 | 58 | fn initialize(&mut self) { 59 | log_info1!("Device Manager module initialized"); 60 | } 61 | 62 | // FIXME: Finnish handling signals in `DeviceManagerModule`. 63 | fn execute(&mut self, package: &Self::T) { 64 | match *package { 65 | Perceptron::Suspend => self.manager.on_suspend(), 66 | Perceptron::WakeUp => self.manager.on_wakeup(), 67 | Perceptron::InputsChanged => self.manager.on_inputs_changed(), 68 | Perceptron::OutputsChanged => self.manager.on_outputs_changed(), 69 | _ => {} 70 | } 71 | } 72 | 73 | fn finalize(&mut self) { 74 | log_info1!("Device Manager module finalized"); 75 | } 76 | } 77 | 78 | // ------------------------------------------------------------------------------------------------- 79 | 80 | pub struct DeviceManagerModuleConstructor {} 81 | 82 | // ------------------------------------------------------------------------------------------------- 83 | 84 | impl DeviceManagerModuleConstructor { 85 | /// Constructs new `DeviceManagerModuleConstructor`. 86 | pub fn new() -> Box> { 87 | Box::new(DeviceManagerModuleConstructor {}) 88 | } 89 | } 90 | 91 | // ------------------------------------------------------------------------------------------------- 92 | 93 | impl ModuleConstructor for DeviceManagerModuleConstructor { 94 | type T = Perceptron; 95 | type C = Context; 96 | 97 | fn construct(&self, context: &mut Self::C) -> Box> { 98 | Box::new(DeviceManagerModule::new(context)) 99 | } 100 | } 101 | 102 | // ------------------------------------------------------------------------------------------------- 103 | -------------------------------------------------------------------------------- /cognitive/aesthetics/src/cursor.rs: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of 2 | // the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/ 3 | 4 | //! This module contains functionality related appearance of default cursor. 5 | 6 | // ------------------------------------------------------------------------------------------------- 7 | 8 | use qualia::{Buffer, PixelFormat, SurfaceId, AestheticsCoordinationTrait}; 9 | 10 | // ------------------------------------------------------------------------------------------------- 11 | 12 | const CURSOR_SIZE: usize = 15; 13 | 14 | // ------------------------------------------------------------------------------------------------- 15 | 16 | /// State of the cursor. 17 | pub struct Cursor 18 | where C: AestheticsCoordinationTrait 19 | { 20 | /// Surface ID of cursor surface. 21 | csid: SurfaceId, 22 | 23 | /// Default surface ID of cursor surface. 24 | default_csid: SurfaceId, 25 | 26 | /// Buffer for the default cursor surface. 27 | buffer: Buffer, 28 | 29 | /// Coordinator. 30 | coordinator: C, 31 | } 32 | 33 | // ------------------------------------------------------------------------------------------------- 34 | 35 | impl Cursor 36 | where C: AestheticsCoordinationTrait 37 | { 38 | /// Constructs new `Cursor`. 39 | pub fn new(coordinator: C) -> Self { 40 | Cursor { 41 | csid: SurfaceId::invalid(), 42 | default_csid: SurfaceId::invalid(), 43 | coordinator: coordinator, 44 | buffer: Buffer::empty(), 45 | } 46 | } 47 | 48 | /// Initializes default cursor buffer. 49 | /// 50 | /// Sets default cursor to be white semitransparent rectangle. 51 | pub fn initialize(&mut self) { 52 | let w = CURSOR_SIZE; 53 | let h = CURSOR_SIZE; 54 | let format = PixelFormat::ABGR8888; 55 | let pixel_size = format.get_size(); 56 | let stride = w * pixel_size; 57 | let mut data = vec![200; stride * h]; 58 | for z in 0..(w * h) { 59 | data[pixel_size * z + 3] = 100; 60 | } 61 | 62 | self.default_csid = self.coordinator.create_surface(); 63 | self.buffer = Buffer::new(format, w, h, stride, data); 64 | let bid = self.coordinator.create_memory_pool(unsafe { self.buffer.as_memory() }); 65 | if let Some(mvid) = self.coordinator.create_memory_view(bid, format, 0, w, h, stride) { 66 | self.coordinator.attach_shm(mvid, self.default_csid); 67 | self.coordinator.commit_surface(self.default_csid); 68 | self.coordinator.set_surface_as_cursor(self.default_csid); 69 | } 70 | } 71 | } 72 | 73 | // ------------------------------------------------------------------------------------------------- 74 | 75 | impl Cursor 76 | where C: AestheticsCoordinationTrait 77 | { 78 | /// Handles cursor surface change notification. 79 | pub fn on_surface_change(&mut self, sid: SurfaceId) { 80 | self.csid = sid; 81 | } 82 | 83 | /// Handles pointer focus change. If no surface is focussed pointer cursor surface must be set 84 | /// to default. 85 | pub fn on_focus_changed(&mut self, _old_pfsid: SurfaceId, new_pfsid: SurfaceId) { 86 | if !new_pfsid.is_valid() { 87 | self.coordinator.set_surface_as_cursor(self.default_csid); 88 | } 89 | } 90 | 91 | /// Handles destruction of surface. If current cursor surface was destroyed it must be reset to 92 | /// default. 93 | pub fn on_surface_destroyed(&mut self, sid: SurfaceId) { 94 | if self.csid == sid { 95 | self.coordinator.set_surface_as_cursor(self.default_csid); 96 | } 97 | } 98 | 99 | /// Handles creation of display. 100 | /// 101 | /// Here we have sure `Exhibitor` is initialized so we can initialize cursor buffer. 102 | pub fn on_display_created(&mut self) { 103 | if !self.default_csid.is_valid() { 104 | self.initialize(); 105 | } 106 | } 107 | } 108 | 109 | // ------------------------------------------------------------------------------------------------- 110 | -------------------------------------------------------------------------------- /cognitive/qualia/src/image.rs: -------------------------------------------------------------------------------- 1 | // This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of 2 | // the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/ 3 | 4 | //! This create gathers some functionality related to images and access to them. 5 | 6 | use graphics::egl_tools::HwImage; 7 | use graphics::attributes::{EglAttributes, DmabufAttributes}; 8 | 9 | use defs::Size; 10 | 11 | // ------------------------------------------------------------------------------------------------- 12 | 13 | /// Format of a pixel. 14 | #[derive(Clone, Copy, Debug)] 15 | pub enum PixelFormat { 16 | XRGB8888, 17 | ARGB8888, 18 | XBGR8888, 19 | ABGR8888, 20 | } 21 | 22 | // ------------------------------------------------------------------------------------------------- 23 | 24 | impl PixelFormat { 25 | /// Returns size in bytes of pixel encoded in given format. 26 | pub fn get_size(&self) -> usize { 27 | match *self { 28 | PixelFormat::XBGR8888 => 3, 29 | PixelFormat::ABGR8888 => 4, 30 | PixelFormat::XRGB8888 => 3, 31 | PixelFormat::ARGB8888 => 4, 32 | } 33 | } 34 | } 35 | 36 | // ------------------------------------------------------------------------------------------------- 37 | 38 | /// Trait providing interface for image storing objects. 39 | pub trait Image { 40 | /// Get width and height of the image. 41 | fn get_size(&self) -> Size; 42 | 43 | /// Return width of the image. 44 | fn get_width(&self) -> usize; 45 | 46 | /// Returns height of the image. 47 | fn get_height(&self) -> usize; 48 | } 49 | 50 | // ------------------------------------------------------------------------------------------------- 51 | 52 | /// Trait providing interface for pixmap storing objects. 53 | pub trait Pixmap: Image { 54 | /// Returns pixel format of the pixmap. 55 | fn get_format(&self) -> PixelFormat; 56 | 57 | /// Return stride (width in bytes or one row) of the pixmap. 58 | fn get_stride(&self) -> usize; 59 | 60 | /// Returns data as slice. 61 | fn as_slice(&self) -> &[u8]; 62 | 63 | /// Returns data as mutable slice. 64 | fn as_mut_slice(&mut self) -> &mut [u8]; 65 | 66 | /// Returns data as pointer to `u8`. 67 | unsafe fn as_ptr(&self) -> *const u8; 68 | } 69 | 70 | // ------------------------------------------------------------------------------------------------- 71 | 72 | impl Image for HwImage { 73 | /// Returns width and height of the image. 74 | fn get_size(&self) -> Size { 75 | Size::new(self.get_width(), self.get_height()) 76 | } 77 | 78 | /// Returns width of the image. 79 | fn get_width(&self) -> usize { 80 | self.get_width() 81 | } 82 | 83 | /// Returns height of the image. 84 | fn get_height(&self) -> usize { 85 | self.get_height() 86 | } 87 | } 88 | 89 | // ------------------------------------------------------------------------------------------------- 90 | 91 | impl Image for EglAttributes { 92 | /// Get width and height of the underlying hardware image. 93 | fn get_size(&self) -> Size { 94 | Size::new(self.width as usize, self.height as usize) 95 | } 96 | 97 | /// Return width of the underlying hardware image. 98 | fn get_width(&self) -> usize { 99 | self.width as usize 100 | } 101 | 102 | /// Returns height of the underlying hardware image. 103 | fn get_height(&self) -> usize { 104 | self.height as usize 105 | } 106 | } 107 | 108 | // ------------------------------------------------------------------------------------------------- 109 | 110 | impl Image for DmabufAttributes { 111 | /// Get width and height of the underlying hardware image. 112 | fn get_size(&self) -> Size { 113 | Size::new(self.width as usize, self.height as usize) 114 | } 115 | 116 | /// Return width of the underlying hardware image. 117 | fn get_width(&self) -> usize { 118 | self.width as usize 119 | } 120 | 121 | /// Returns height of the underlying hardware image. 122 | fn get_height(&self) -> usize { 123 | self.height as usize 124 | } 125 | } 126 | 127 | // ------------------------------------------------------------------------------------------------- 128 | --------------------------------------------------------------------------------