screenruster_saver/
lib.rs1#![feature(type_ascription)]
16
17use std::io;
18use std::env;
19
20#[cfg(feature = "renderer")]
21pub use gl;
22#[cfg(feature = "renderer")]
23pub use picto;
24
25pub use json;
26pub use log::{debug, error, info, log, log_enabled, trace, warn};
27
28#[macro_use]
29mod util;
30
31mod error;
32pub use error::{Result, Error};
33
34mod state;
35pub use state::State;
36
37mod safety;
38pub use safety::Safety;
39
40mod password;
41pub use password::Password;
42
43pub mod pointer;
44pub use pointer::Pointer;
45
46mod channel;
47pub use channel::{Request, Response, Channel};
48
49#[cfg(feature = "renderer")]
50mod saver;
51#[cfg(feature = "renderer")]
52pub use saver::Saver;
53
54#[cfg(feature = "renderer")]
55mod renderer;
56#[cfg(feature = "renderer")]
57pub use renderer::Renderer;
58
59#[cfg(feature = "renderer")]
60mod display;
61#[cfg(feature = "renderer")]
62pub use display::Display;
63
64
65pub fn init() -> Result<Channel> {
67 use std::io::Write;
68
69 {
71 let mut builder = env_logger::Builder::new();
72 let pid = unsafe { libc::getpid() };
73
74 builder.format(move |buf, record| {
75 writeln!(buf, "{}:{}:{}: {}", record.level(), pid, record.module_path().unwrap_or("unknown"), record.args())
76 });
77
78 if let Ok(log) = env::var("RUST_LOG") {
79 builder.parse_filters(&log);
80 }
81
82 builder.init();
83 }
84
85 Channel::open(io::stdin(), io::stdout())
86}
87
88#[cfg(feature = "renderer")]
90pub fn run<S: Saver + Send + 'static>(mut saver: S) -> Result<()> {
91 macro_rules! exit {
92 ($body:expr) => (
93 if let Ok(value) = $body {
94 value
95 }
96 else {
97 break;
98 }
99 );
100 }
101
102 use crossbeam_channel::select;
103
104 let channel = init()?;
105
106 if let Ok(Request::Config(config)) = channel.recv() {
107 saver.config(config);
108 }
109 else {
110 return Err(Error::Protocol);
111 }
112
113 let renderer = if let Ok(Request::Target { display, screen, window }) = channel.recv() {
114 Renderer::new(display, screen, window, saver)
115 }
116 else {
117 return Err(Error::Protocol);
118 };
119
120 'main: loop {
121 select! {
122 recv(channel.as_ref()) -> message => {
123 match exit!(message) {
124 channel::Request::Target { .. } | channel::Request::Config(..) => {
125 unreachable!();
126 }
127
128 channel::Request::Resize { width, height } => {
129 renderer.resize(width, height).unwrap();
130 }
131
132 channel::Request::Throttle(value) => {
133 renderer.throttle(value).unwrap();
134 }
135
136 channel::Request::Blank(value) => {
137 renderer.blank(value).unwrap();
138 }
139
140 channel::Request::Safety(value) => {
141 renderer.safety(value).unwrap();
142 }
143
144 channel::Request::Pointer(pointer) => {
145 renderer.pointer(pointer).unwrap();
146 }
147
148 channel::Request::Password(password) => {
149 renderer.password(password).unwrap();
150 }
151
152 channel::Request::Start => {
153 renderer.start().unwrap();
154 }
155
156 channel::Request::Lock => {
157 renderer.lock().unwrap();
158 }
159
160 channel::Request::Stop => {
161 renderer.stop().unwrap();
162 }
163 }
164 },
165
166 recv(renderer.as_ref()) -> message => {
167 match exit!(message) {
168 renderer::Response::Initialized => {
169 channel.send(channel::Response::Initialized).unwrap();
170 }
171
172 renderer::Response::Started => {
173 channel.send(channel::Response::Started).unwrap();
174 }
175
176 renderer::Response::Stopped => {
177 break 'main;
178 }
179 }
180 }
181 }
182 }
183
184 channel.send(channel::Response::Stopped).unwrap();
185
186 Ok(())
187}