| @@ -0,0 +1,82 @@ | |||
| var syscheck = require("./js/syscheck"); | |||
| var modules = { | |||
| display: require("./modules/display"), | |||
| input: require("./modules/input"), | |||
| wallpaper: require("./modules/wallpaper") | |||
| }; | |||
| var config = { | |||
| display: [ | |||
| { | |||
| name: "*", | |||
| resolution: "max", | |||
| rate: "max", | |||
| where: { left_of: "primary" }, | |||
| }, | |||
| ], | |||
| input: [ | |||
| { | |||
| type: "pointer", | |||
| name: "*", | |||
| options: [, | |||
| [ "libinput Tapping Enabled", 1 ], | |||
| ], | |||
| }, | |||
| { | |||
| type: "keyboard", | |||
| name: "*", | |||
| commands: [ | |||
| "xset r rate 200 60", | |||
| "setxkbmap dvorak -option ctrl:swapcaps -option altwin:swap_alt_win", | |||
| ] | |||
| } | |||
| ], | |||
| wallpaper: { | |||
| path: "/home/martin/background.jpg", | |||
| }, | |||
| } | |||
| function createLogger(name) { | |||
| function log(pre, msg) { | |||
| console.error(pre+msg.join(" ")); | |||
| } | |||
| return { | |||
| info: (...msg) => log(name+": INFO: ", msg), | |||
| warn: (...msg) => log(name+": WARNING: ", msg), | |||
| error: (...msg) => log(name+": ERROR: ", msg), | |||
| } | |||
| } | |||
| function startAll() { | |||
| Object.keys(modules).forEach(i => { | |||
| var mod = modules[i]; | |||
| var conf = config[i] || {}; | |||
| mod.start(conf, createLogger(i), modules); | |||
| }); | |||
| } | |||
| function stopAll(cb) { | |||
| var keys = Object.keys(modules); | |||
| var cbs = keys.length; | |||
| function next() { | |||
| cbs -= 1; | |||
| if (cbs === 0) | |||
| cb(); | |||
| } | |||
| keys.forEach(i => modules.stop(next)); | |||
| } | |||
| syscheck(ok => { | |||
| if (ok) | |||
| startAll(); | |||
| else | |||
| console.error("Missing binaries, exiting."); | |||
| }); | |||
| @@ -0,0 +1,14 @@ | |||
| module.exports = debounce; | |||
| function debounce(fn, ms) { | |||
| if (ms == null) | |||
| ms = 100; | |||
| var timeout = null; | |||
| return function() { | |||
| if (timeout != null) | |||
| clearTimeout(timeout); | |||
| timeout = setTimeout(fn, ms); | |||
| } | |||
| } | |||
| @@ -0,0 +1,34 @@ | |||
| var spawn = require("child_process").spawn; | |||
| module.exports = check; | |||
| var needed = [ | |||
| "feh", | |||
| ]; | |||
| function need(str, cb) { | |||
| var child = spawn("which", [ str ]); | |||
| child.on("close", code => { | |||
| if (code === 0) { | |||
| cb(true); | |||
| } else { | |||
| console.error("Missing system binary:", str); | |||
| cb(false); | |||
| } | |||
| }); | |||
| } | |||
| function check(cb) { | |||
| var ok = true; | |||
| var cbs = needed.length; | |||
| function next(res) { | |||
| if (!res) | |||
| ok = false; | |||
| cbs -= 1; | |||
| if (cbs === 0) | |||
| cb(ok); | |||
| } | |||
| needed.forEach(s => need(s, next)); | |||
| } | |||
| @@ -0,0 +1,21 @@ | |||
| exports.start = start; | |||
| exports.stop = stop; | |||
| exports.event = event; | |||
| var conf; | |||
| var logger; | |||
| var modules; | |||
| function start(conf_, logger_, modules_) { | |||
| conf = conf_ || conf; | |||
| logger = logger_ || logger; | |||
| modules = modules_ || modules; | |||
| } | |||
| function stop(cb) { | |||
| cb(); | |||
| } | |||
| function event(name, ...params) { | |||
| logger.info("Event", name, params.toString()); | |||
| } | |||
| @@ -0,0 +1,21 @@ | |||
| exports.start = start; | |||
| exports.stop = stop; | |||
| exports.event = event; | |||
| var conf; | |||
| var logger; | |||
| var modules; | |||
| function start(conf_, logger_, modules_) { | |||
| conf = conf_ || conf; | |||
| logger = logger_ || logger; | |||
| modules = modules_ || modules; | |||
| } | |||
| function stop(cb) { | |||
| cb(); | |||
| } | |||
| function event(name, ...params) { | |||
| logger.info("Event", name, params.toString()); | |||
| } | |||
| @@ -0,0 +1,88 @@ | |||
| var spawn = require("child_process").spawn; | |||
| var fs = require("fs"); | |||
| var pathlib = require("path"); | |||
| var debounce = require("../../js/debounce"); | |||
| exports.start = start; | |||
| exports.stop = stop; | |||
| exports.event = event; | |||
| var conf; | |||
| var logger; | |||
| var modules; | |||
| function runFeh() { | |||
| var mode; | |||
| logger.info("Setting background to", conf.path); | |||
| switch (conf.mode) { | |||
| case "scale": | |||
| case undefined: | |||
| mode = "--bg-scale"; | |||
| break; | |||
| case "center": | |||
| mode = "--bg-center"; | |||
| break; | |||
| case "fill": | |||
| mode = "--bg-fill"; | |||
| break; | |||
| case "max": | |||
| mode = "--bg-max"; | |||
| break; | |||
| case "tile": | |||
| mode = "--bg-tile"; | |||
| break; | |||
| default: | |||
| return logger.error("Invalid mode: "+conf.mode); | |||
| } | |||
| var child = spawn("feh", [ mode, conf.path ]); | |||
| child.stdout.on("data", d => | |||
| logger.info("feh stdout:", d.toString().trim())); | |||
| child.stderr.on("data", d => | |||
| logger.info("feh stderr:", d.toString().trim())); | |||
| } | |||
| function start(conf_, logger_, modules_) { | |||
| conf = conf_ || conf; | |||
| logger = logger_ || logger; | |||
| modules = modules_ || modules; | |||
| if (!conf.path) | |||
| return logger.error("Expected conf.path"); | |||
| runFeh(); | |||
| var dirname = pathlib.dirname(conf.path); | |||
| var basename = pathlib.basename(conf.path); | |||
| var run = debounce(runFeh); | |||
| fs.watch(dirname, (type, name) => { | |||
| if (name !== basename) | |||
| return; | |||
| run(); | |||
| }); | |||
| } | |||
| function stop(cb) { | |||
| cb(); | |||
| } | |||
| function event(name, ...params) { | |||
| logger.info("Event", name, params.toString()); | |||
| switch (name) { | |||
| case "reload": | |||
| runFeh(); | |||
| break; | |||
| } | |||
| } | |||