Switch to Failure-based error handling
Getty Ritter
6 years ago
| 1 | 1 | # This file is automatically @generated by Cargo. |
| 2 | 2 | # It is not intended for manual editing. |
| 3 | [[package]] | |
| 4 | name = "autocfg" | |
| 5 | version = "0.1.2" | |
| 6 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
| 7 | ||
| 8 | [[package]] | |
| 9 | name = "backtrace" | |
| 10 | version = "0.3.14" | |
| 11 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
| 12 | dependencies = [ | |
| 13 | "autocfg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", | |
| 14 | "backtrace-sys 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", | |
| 15 | "cfg-if 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", | |
| 16 | "libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)", | |
| 17 | "rustc-demangle 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)", | |
| 18 | "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", | |
| 19 | ] | |
| 20 | ||
| 21 | [[package]] | |
| 22 | name = "backtrace-sys" | |
| 23 | version = "0.1.28" | |
| 24 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
| 25 | dependencies = [ | |
| 26 | "cc 1.0.31 (registry+https://github.com/rust-lang/crates.io-index)", | |
| 27 | "libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)", | |
| 28 | ] | |
| 29 | ||
| 3 | 30 | [[package]] |
| 4 | 31 | name = "bitflags" |
| 5 | 32 | version = "1.0.4" |
| 31 | 58 | ] |
| 32 | 59 | |
| 33 | 60 | [[package]] |
| 61 | name = "cc" | |
| 62 | version = "1.0.31" | |
| 63 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
| 64 | ||
| 65 | [[package]] | |
| 66 | name = "cfg-if" | |
| 67 | version = "0.1.7" | |
| 68 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
| 69 | ||
| 70 | [[package]] | |
| 34 | 71 | name = "chrono" |
| 35 | 72 | version = "0.4.6" |
| 36 | 73 | source = "registry+https://github.com/rust-lang/crates.io-index" |
| 41 | 78 | ] |
| 42 | 79 | |
| 43 | 80 | [[package]] |
| 81 | name = "failure" | |
| 82 | version = "0.1.5" | |
| 83 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
| 84 | dependencies = [ | |
| 85 | "backtrace 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", | |
| 86 | "failure_derive 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", | |
| 87 | ] | |
| 88 | ||
| 89 | [[package]] | |
| 90 | name = "failure_derive" | |
| 91 | version = "0.1.5" | |
| 92 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
| 93 | dependencies = [ | |
| 94 | "proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)", | |
| 95 | "quote 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)", | |
| 96 | "syn 0.15.29 (registry+https://github.com/rust-lang/crates.io-index)", | |
| 97 | "synstructure 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)", | |
| 98 | ] | |
| 99 | ||
| 100 | [[package]] | |
| 44 | 101 | name = "glib" |
| 45 | 102 | version = "0.7.1" |
| 46 | 103 | source = "registry+https://github.com/rust-lang/crates.io-index" |
| 78 | 135 | "cairo-rs 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", |
| 79 | 136 | "cairo-sys-rs 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", |
| 80 | 137 | "chrono 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", |
| 138 | "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", | |
| 81 | 139 | "libc 0.2.50 (registry+https://github.com/rust-lang/crates.io-index)", |
| 82 | 140 | "pango 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", |
| 83 | 141 | "pangocairo 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", |
| 167 | 225 | source = "registry+https://github.com/rust-lang/crates.io-index" |
| 168 | 226 | |
| 169 | 227 | [[package]] |
| 228 | name = "proc-macro2" | |
| 229 | version = "0.4.27" | |
| 230 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
| 231 | dependencies = [ | |
| 232 | "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", | |
| 233 | ] | |
| 234 | ||
| 235 | [[package]] | |
| 236 | name = "quote" | |
| 237 | version = "0.6.11" | |
| 238 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
| 239 | dependencies = [ | |
| 240 | "proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)", | |
| 241 | ] | |
| 242 | ||
| 243 | [[package]] | |
| 170 | 244 | name = "redox_syscall" |
| 171 | 245 | version = "0.1.51" |
| 172 | 246 | source = "registry+https://github.com/rust-lang/crates.io-index" |
| 173 | 247 | |
| 174 | 248 | [[package]] |
| 249 | name = "rustc-demangle" | |
| 250 | version = "0.1.13" | |
| 251 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
| 252 | ||
| 253 | [[package]] | |
| 254 | name = "syn" | |
| 255 | version = "0.15.29" | |
| 256 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
| 257 | dependencies = [ | |
| 258 | "proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)", | |
| 259 | "quote 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)", | |
| 260 | "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", | |
| 261 | ] | |
| 262 | ||
| 263 | [[package]] | |
| 264 | name = "synstructure" | |
| 265 | version = "0.10.1" | |
| 266 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
| 267 | dependencies = [ | |
| 268 | "proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)", | |
| 269 | "quote 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)", | |
| 270 | "syn 0.15.29 (registry+https://github.com/rust-lang/crates.io-index)", | |
| 271 | "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", | |
| 272 | ] | |
| 273 | ||
| 274 | [[package]] | |
| 175 | 275 | name = "time" |
| 176 | 276 | version = "0.1.42" |
| 177 | 277 | source = "registry+https://github.com/rust-lang/crates.io-index" |
| 182 | 282 | ] |
| 183 | 283 | |
| 184 | 284 | [[package]] |
| 285 | name = "unicode-xid" | |
| 286 | version = "0.1.0" | |
| 287 | source = "registry+https://github.com/rust-lang/crates.io-index" | |
| 288 | ||
| 289 | [[package]] | |
| 185 | 290 | name = "winapi" |
| 186 | 291 | version = "0.3.6" |
| 187 | 292 | source = "registry+https://github.com/rust-lang/crates.io-index" |
| 210 | 315 | ] |
| 211 | 316 | |
| 212 | 317 | [metadata] |
| 318 | "checksum autocfg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a6d640bee2da49f60a4068a7fae53acde8982514ab7bae8b8cea9e88cbcfd799" | |
| 319 | "checksum backtrace 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)" = "cd5a90e2b463010cd0e0ce9a11d4a9d5d58d9f41d4a6ba3dcaf9e68b466e88b4" | |
| 320 | "checksum backtrace-sys 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)" = "797c830ac25ccc92a7f8a7b9862bde440715531514594a6154e3d4a54dd769b6" | |
| 213 | 321 | "checksum bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "228047a76f468627ca71776ecdebd732a3423081fcf5125585bcd7c49886ce12" |
| 214 | 322 | "checksum cairo-rs 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9e09d8a818b2ccc8983f04d95a9350c3cf8d24cc456cedca3b88fa3a81fdc0e2" |
| 215 | 323 | "checksum cairo-sys-rs 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b3fa13914fdc013387afa771f554f2f71d6ae931f4e5be9246c337d60c3dc484" |
| 324 | "checksum cc 1.0.31 (registry+https://github.com/rust-lang/crates.io-index)" = "c9ce8bb087aacff865633f0bd5aeaed910fe2fe55b55f4739527f2e023a2e53d" | |
| 325 | "checksum cfg-if 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "11d43355396e872eefb45ce6342e4374ed7bc2b3a502d1b28e36d6e23c05d1f4" | |
| 216 | 326 | "checksum chrono 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "45912881121cb26fad7c38c17ba7daa18764771836b34fab7d3fbd93ed633878" |
| 327 | "checksum failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "795bd83d3abeb9220f257e597aa0080a508b27533824adf336529648f6abf7e2" | |
| 328 | "checksum failure_derive 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "ea1063915fd7ef4309e222a5a07cf9c319fb9c7836b1f89b85458672dbb127e1" | |
| 217 | 329 | "checksum glib 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0c4e8fdc159c196a5dfa53a92929ac4c10c8a6637ffb43951f3fff89c2cd2365" |
| 218 | 330 | "checksum glib-sys 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5bda542f3caee39a027638e9644ff89204101ad916fd7370b585ad2c5fc97e61" |
| 219 | 331 | "checksum gobject-sys 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "23e05a14290d3dc255223cba51db4b0f3da438d5250657996fa99b2a30faf43e" |
| 226 | 338 | "checksum pangocairo 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "706e885b46a16ba96f46f3c8d880ca6082c2c62693b75f3d167bd3aa4e34b0d4" |
| 227 | 339 | "checksum pangocairo-sys 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "868310e83da5269323c28bd47b641557d032426f396cddfa45e247ff44da9a12" |
| 228 | 340 | "checksum pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)" = "676e8eb2b1b4c9043511a9b7bea0915320d7e502b0a079fb03f9635a5252b18c" |
| 341 | "checksum proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)" = "4d317f9caece796be1980837fd5cb3dfec5613ebdb04ad0956deea83ce168915" | |
| 342 | "checksum quote 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)" = "cdd8e04bd9c52e0342b406469d494fcb033be4bdbe5c606016defbb1681411e1" | |
| 229 | 343 | "checksum redox_syscall 0.1.51 (registry+https://github.com/rust-lang/crates.io-index)" = "423e376fffca3dfa06c9e9790a9ccd282fafb3cc6e6397d01dbf64f9bacc6b85" |
| 344 | "checksum rustc-demangle 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "adacaae16d02b6ec37fdc7acfcddf365978de76d1983d3ee22afc260e1ca9619" | |
| 345 | "checksum syn 0.15.29 (registry+https://github.com/rust-lang/crates.io-index)" = "1825685f977249735d510a242a6727b46efe914bb67e38d30c071b1b72b1d5c2" | |
| 346 | "checksum synstructure 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "73687139bf99285483c96ac0add482c3776528beac1d97d444f6e91f203a2015" | |
| 230 | 347 | "checksum time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)" = "db8dcfca086c1143c9270ac42a2bbd8a7ee477b78ac8e45b19abfb0cbede4b6f" |
| 348 | "checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc" | |
| 231 | 349 | "checksum winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "92c1eb33641e276cfa214a0522acad57be5c56b10cb348b3c5117db75f3ac4b0" |
| 232 | 350 | "checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" |
| 233 | 351 | "checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" |
| 11 | 11 | # time = "0.1" |
| 12 | 12 | chrono = "*" |
| 13 | 13 | libc = "0.2" |
| 14 | failure = "*" | |
| 14 | 15 | |
| 15 | 16 | [dependencies.cairo-sys-rs] |
| 16 | 17 | version = "0.8" |
| 1 | #[macro_use] | |
| 2 | extern crate failure; | |
| 3 | ||
| 1 | 4 | mod widgets; |
| 2 | 5 | mod window; |
| 3 | 6 | |
| 7 | 10 | use widgets::Widget; |
| 8 | 11 | use window::{Display,Event,Size,Window}; |
| 9 | 12 | |
| 10 |
fn main() |
|
| 13 | fn main() -> Result<(), failure::Error> { | |
| 11 | 14 | // set up the display and the window |
| 12 |
let mut d = Display::create() |
|
| 15 | let mut d = Display::create()?; | |
| 13 | 16 | let size = Size { |
| 14 | 17 | wd: d.get_width(), |
| 15 | 18 | // TODO: this should be a function of font size |
| 16 | 19 | ht: 36, |
| 17 | 20 | }; |
| 18 |
let mut w = Window::create(d, size) |
|
| 21 | let mut w = Window::create(d, size)?; | |
| 19 | 22 | // set some window-manager properties: this is a dock |
| 20 |
w.change_property("_NET_WM_WINDOW_TYPE", &["_NET_WM_WINDOW_TYPE_DOCK"]) |
|
| 23 | w.change_property("_NET_WM_WINDOW_TYPE", &["_NET_WM_WINDOW_TYPE_DOCK"])?; | |
| 21 | 24 | // ...and should push other windows out of the way |
| 22 |
w.change_property("_NET_WM_STRUT", &[0i64, 0, size.ht as i64, 0] |
|
| 25 | w.change_property("_NET_WM_STRUT", &[0i64, 0, size.ht as i64, 0])?; | |
| 23 | 26 | w.change_property( |
| 24 | 27 | "_NET_WM_STRUT_PARTIAL", |
| 25 | 28 | &[ 0, 0, size.ht as i64, 0, |
| 26 | 29 | 0, 0, 0, 0, |
| 27 | 30 | 0, size.wd as i64, 0, 0, |
| 28 | 31 | ], |
| 29 |
) |
|
| 32 | )?; | |
| 30 | 33 | |
| 31 | 34 | // we won't ever see this, but for good measure. |
| 32 |
w.set_title("rbar") |
|
| 35 | w.set_title("rbar")?; | |
| 33 | 36 | // we care about some input events! |
| 34 | w.set_input_masks(); | |
| 35 | w.set_protocols(); | |
| 37 | w.set_input_masks()?; | |
| 38 | w.set_protocols()?; | |
| 36 | 39 | // and now show it! |
| 37 | 40 | w.map(); |
| 38 | 41 | |
| 59 | 62 | tv_usec: 0, |
| 60 | 63 | }; |
| 61 | 64 | |
| 62 |
let layout = pangocairo::functions::create_layout(&ctx) |
|
| 65 | let layout = pangocairo::functions::create_layout(&ctx) | |
| 66 | .ok_or(format_err!("foo"))?; | |
| 63 | 67 | |
| 64 | 68 | // allow for the whole width of the bar, minus a small fixed amount |
| 65 | 69 | layout.set_width((size.wd - 20) * pango::SCALE); |
| 69 | 73 | layout.set_font_description(&font); |
| 70 | 74 | |
| 71 | 75 | // do an initial pass at drawing the bar! |
| 72 |
draw(&ctx, &layout, &input, size) |
|
| 76 | draw(&ctx, &layout, &input, size)?; | |
| 73 | 77 | |
| 74 | 78 | |
| 75 | 79 | // we're gonna keep looping until we don't |
| 97 | 101 | if unsafe { libc::FD_ISSET(stdin_fd, &mut fds) } { |
| 98 | 102 | use std::io::BufRead; |
| 99 | 103 | input = String::new(); |
| 100 |
stdin.read_line(&mut input) |
|
| 104 | stdin.read_line(&mut input)?; | |
| 101 | 105 | if input.len() == 0 { |
| 102 | 106 | break; |
| 103 | 107 | } |
| 104 |
draw(&ctx, &layout, &input, size) |
|
| 108 | draw(&ctx, &layout, &input, size)?; | |
| 105 | 109 | } |
| 106 | 110 | |
| 107 | 111 | // if we have X11 events, handle them. If any one was a quit |
| 114 | 118 | } |
| 115 | 119 | |
| 116 | 120 | // otherwise, draw the thing! |
| 117 |
draw(&ctx, &layout, &input, size) |
|
| 121 | draw(&ctx, &layout, &input, size)?; | |
| 118 | 122 | } |
| 123 | ||
| 124 | Ok(()) | |
| 119 | 125 | } |
| 120 | 126 | |
| 121 | 127 | |
| 122 | 128 | /// Do our Cairo drawing. This needs to be refactored to allow for |
| 123 | 129 | /// more configurability in terms of what gets written! |
| 124 |
fn draw( |
|
| 130 | fn draw( | |
| 131 | ctx: &cairo::Context, | |
| 132 | layout: &pango::Layout, | |
| 133 | left: &str, | |
| 134 | size: Size) | |
| 135 | -> Result<(), failure::Error> | |
| 136 | { | |
| 125 | 137 | // the background is... gray-ish? this'll be configurable eventually |
| 126 | 138 | ctx.set_source_rgb(0.1, 0.1, 0.1); |
| 127 | 139 | ctx.paint(); |
| 138 | 150 | // set up our widgets |
| 139 | 151 | let text = widgets::Text::new(left); |
| 140 | 152 | let time = widgets::Time::new(); |
| 141 |
let bat = widgets::Battery |
|
| 153 | let bat = widgets::Battery::new().unwrap(); | |
| 142 | 154 | |
| 143 | 155 | // and create a 'config' which tells us which widgets to draw from |
| 144 | 156 | // the left, and which from the right |
| 154 | 166 | // and draw them! |
| 155 | 167 | config.draw(&drawing); |
| 156 | 168 | |
| 169 | Ok(()) | |
| 157 | 170 | } |
| 105 | 105 | |
| 106 | 106 | |
| 107 | 107 | |
| 108 |
pub struct Battery |
|
| 108 | pub struct Battery { | |
| 109 | file_list: Vec<std::path::PathBuf>, | |
| 110 | } | |
| 109 | 111 | |
| 110 | 112 | impl Battery { |
| 111 |
|
|
| 113 | pub fn new() -> Result<Battery, failure::Error> { | |
| 112 | 114 | use std::fs; |
| 113 | 115 | |
| 114 | 116 | let mut batteries = Vec::new(); |
| 115 | for entry in fs::read_dir("/sys/class/power_supply").unwrap() { | |
| 116 | let e = entry.unwrap(); | |
| 117 | for entry in fs::read_dir("/sys/class/power_supply")? { | |
| 118 | let e = entry?; | |
| 117 | 119 | if e.file_name().to_string_lossy().starts_with("BAT") { |
| 118 |
|
|
| 120 | let mut path = e.path(); | |
| 121 | path.push("capacity"); | |
| 122 | batteries.push(path); | |
| 119 | 123 | } |
| 120 | 124 | } |
| 121 | 125 | |
| 122 | let mut charges: Vec<i32> = Vec::new(); | |
| 123 | for mut bat in batteries { | |
| 124 | bat.push("capacity"); | |
| 125 | let r = fs::read_to_string(bat).unwrap(); | |
| 126 | charges.push(r.trim().parse::<i32>().unwrap()); | |
| 127 | } | |
| 126 | Ok(Battery { | |
| 127 | file_list: batteries, | |
| 128 | }) | |
| 129 | } | |
| 130 | ||
| 131 | fn read_status(&self) -> Result<f64, failure::Error> { | |
| 132 | let charges: Result<Vec<i32>, failure::Error> = | |
| 133 | self.file_list.iter().map(|path| { | |
| 134 | Ok(std::fs::read_to_string(path)?.trim().parse()?) | |
| 135 | }).collect(); | |
| 136 | let charges = charges?; | |
| 128 | 137 | |
| 129 | 138 | let len = charges.len() as f64; |
| 130 | 139 | let sum: i32 = charges.into_iter().sum(); |
| 131 |
|
|
| 140 | Ok(sum as f64 / len / 100.0) | |
| 132 | 141 | } |
| 133 | 142 | } |
| 134 | 143 | |
| 135 | 144 | impl Widget for Battery { |
| 136 | 145 | fn draw(&self, d: &Drawing, loc: Located) -> i32 { |
| 137 |
let amt = self.read_status() |
|
| 146 | let amt = self.read_status().unwrap(); | |
| 138 | 147 | let sz = d.size.ht - 8; |
| 139 | 148 | let x = loc.target_x(d, sz); |
| 140 | 149 | if amt < 0.1 { |
| 16 | 16 | } |
| 17 | 17 | |
| 18 | 18 | impl Display { |
| 19 |
pub fn create() -> |
|
| 19 | pub fn create() -> Result<Display, failure::Error> { | |
| 20 | 20 | let display = unsafe { xlib::XOpenDisplay(ptr::null()) }; |
| 21 | if display.is_null() { | |
| 22 | bail!("Unable to open X11 display"); | |
| 23 | } | |
| 21 | 24 | let screen = unsafe { xlib::XDefaultScreen(display) }; |
| 22 |
|
|
| 25 | Ok(Display { display, screen }) | |
| 23 | 26 | } |
| 24 | 27 | |
| 25 | 28 | pub fn get_width(&mut self) -> i32 { |
| 52 | 55 | pub fn create( |
| 53 | 56 | d: Display, |
| 54 | 57 | Size { wd: width, ht: height }: Size, |
| 55 |
) -> |
|
| 58 | ) -> Result<Window, failure::Error> { | |
| 56 | 59 | unsafe { |
| 57 | 60 | let display = d.display; |
| 58 | 61 | let screen = d.screen; |
| 68 | 71 | xlib::XWhitePixel(display, screen), |
| 69 | 72 | ); |
| 70 | 73 | let wm_protocols = { |
| 71 |
let cstr = CString::new("WM_PROTOCOLS") |
|
| 74 | let cstr = CString::new("WM_PROTOCOLS")?; | |
| 72 | 75 | xlib::XInternAtom(display, cstr.as_ptr(), 0) |
| 73 | 76 | }; |
| 74 | 77 | let wm_delete_window = { |
| 75 |
let cstr = CString::new("WM_DELETE_WINDOW") |
|
| 78 | let cstr = CString::new("WM_DELETE_WINDOW")?; | |
| 76 | 79 | xlib::XInternAtom(display, cstr.as_ptr(), 0) |
| 77 | 80 | }; |
| 78 |
|
|
| 81 | Ok(Window { | |
| 79 | 82 | display, |
| 80 | 83 | screen, |
| 81 | 84 | window, |
| 83 | 86 | wm_delete_window, |
| 84 | 87 | width, |
| 85 | 88 | height, |
| 86 |
} |
|
| 89 | }) | |
| 87 | 90 | } |
| 88 | 91 | } |
| 89 | 92 | |
| 90 | 93 | /// for this application, we might eventually care about the |
| 91 | 94 | /// mouse, so make sure we notify x11 that we care about those |
| 92 |
pub fn set_input_masks(&mut self) |
|
| 95 | pub fn set_input_masks(&mut self) -> Result<(), failure::Error> { | |
| 93 | 96 | let mut opcode = 0; |
| 94 | 97 | let mut event = 0; |
| 95 | 98 | let mut error = 0; |
| 96 | 99 | |
| 97 |
let xinput_str = CString::new("XInputExtension") |
|
| 100 | let xinput_str = CString::new("XInputExtension")?; | |
| 98 | 101 | unsafe { |
| 99 | 102 | xlib::XQueryExtension( |
| 100 | 103 | self.display, |
| 128 | 131 | ) |
| 129 | 132 | } { |
| 130 | 133 | status if status as u8 == xlib::Success => (), |
| 131 | err => panic!("Failed to select events {:?}", err) | |
| 132 | } | |
| 133 | ||
| 134 | } | |
| 135 | ||
| 136 | pub fn set_protocols(&mut self) { | |
| 137 |
|
|
| 134 | err => bail!("Failed to select events {:?}", err) | |
| 135 | } | |
| 136 | ||
| 137 | Ok(()) | |
| 138 | } | |
| 139 | ||
| 140 | pub fn set_protocols(&mut self) -> Result<(), failure::Error> { | |
| 141 | let mut protocols = [self.intern("WM_DELETE_WINDOW")?]; | |
| 138 | 142 | unsafe { |
| 139 | 143 | xlib::XSetWMProtocols( |
| 140 | 144 | self.display, |
| 143 | 147 | protocols.len() as c_int, |
| 144 | 148 | ); |
| 145 | 149 | } |
| 150 | Ok(()) | |
| 146 | 151 | } |
| 147 | 152 | |
| 148 | 153 | /// Set the name of the window to the desired string |
| 149 |
pub fn set_title(&mut self, name: &str) |
|
| 154 | pub fn set_title(&mut self, name: &str) -> Result<(), failure::Error> { | |
| 150 | 155 | unsafe { |
| 151 | 156 | xlib::XStoreName( |
| 152 | 157 | self.display, |
| 153 | 158 | self.window, |
| 154 | CString::new(name).unwrap().as_ptr(), | |
| 155 | ); | |
| 156 |
|
|
| 159 | CString::new(name)?.as_ptr(), | |
| 160 | ); | |
| 161 | } | |
| 162 | Ok(()) | |
| 157 | 163 | } |
| 158 | 164 | |
| 159 | 165 | /// Map the window to the screen |
| 164 | 170 | } |
| 165 | 171 | |
| 166 | 172 | /// Intern a string in the x server |
| 167 | pub fn intern(&mut self, s: &str) -> u64 { | |
| 168 | unsafe { | |
| 169 | let cstr = CString::new(s).unwrap(); | |
| 170 | xlib::XInternAtom(self.display, cstr.as_ptr(), 0) | |
| 173 | pub fn intern(&mut self, s: &str) -> Result<u64, failure::Error> { | |
| 174 | unsafe { | |
| 175 | let cstr = CString::new(s)?; | |
| 176 | Ok(xlib::XInternAtom(self.display, cstr.as_ptr(), 0)) | |
| 171 | 177 | } |
| 172 | 178 | } |
| 173 | 179 | |
| 174 | 180 | /// Modify the supplied property to the noted value. |
| 175 | pub fn change_property<T: XProperty>(&mut self, prop: &str, val: &[T]) { | |
| 176 | let prop = self.intern(prop); | |
| 181 | pub fn change_property<T: XProperty>( | |
| 182 | &mut self, | |
| 183 | prop: &str, | |
| 184 | val: &[T] | |
| 185 | ) -> Result<(), failure::Error> | |
| 186 | { | |
| 187 | let prop = self.intern(prop)?; | |
| 177 | 188 | unsafe { |
| 178 | 189 | let len = val.len(); |
| 179 | 190 | T::with_ptr(val, self, |w, typ, ptr| { |
| 187 | 198 | ptr, |
| 188 | 199 | len as c_int, |
| 189 | 200 | ); |
| 190 | }); | |
| 191 | } | |
| 201 | })?; | |
| 202 | } | |
| 203 | Ok(()) | |
| 192 | 204 | } |
| 193 | 205 | |
| 194 | 206 | /// Get the Cairo drawing surface corresponding to the whole |
| 280 | 292 | xs: &[Self], |
| 281 | 293 | w: &mut Window, |
| 282 | 294 | f: impl FnOnce(&mut Window, u64, *const u8), |
| 283 |
) |
|
| 295 | ) -> Result<(), failure::Error> ; | |
| 284 | 296 | } |
| 285 | 297 | |
| 286 | 298 | impl XProperty for i64 { |
| 288 | 300 | xs: &[Self], |
| 289 | 301 | w: &mut Window, |
| 290 | 302 | f: impl FnOnce(&mut Window, u64, *const u8), |
| 291 | ) { | |
| 292 | f(w, xlib::XA_CARDINAL, unsafe { mem::transmute(xs.as_ptr()) }) | |
| 303 | ) -> Result<(), failure::Error> { | |
| 304 | f(w, xlib::XA_CARDINAL, unsafe { mem::transmute(xs.as_ptr()) }); | |
| 305 | Ok(()) | |
| 293 | 306 | } |
| 294 | 307 | } |
| 295 | 308 | |
| 298 | 311 | xs: &[Self], |
| 299 | 312 | w: &mut Window, |
| 300 | 313 | f: impl FnOnce(&mut Window, u64, *const u8), |
| 301 | ) { | |
| 302 | let xs: Vec<u64> = xs.iter().map(|s| w.intern(s)).collect(); | |
| 303 |
|
|
| 314 | ) -> Result<(), failure::Error> { | |
| 315 | let xs: Result<Vec<u64>, failure::Error> = | |
| 316 | xs.iter().map(|s| w.intern(s)).collect(); | |
| 317 | f(w, xlib::XA_ATOM, unsafe { mem::transmute(xs?.as_ptr()) }); | |
| 318 | Ok(()) | |
| 304 | 319 | } |
| 305 | 320 | } |
| 306 | 321 | |