X-Git-Url: https://git.toastfreeware.priv.at/gregoa/zavai.git/blobdiff_plain/351500dcc7f5e1344f20f9b8f52591f5c0f17061..15c3d4c508afdf0de8097f8c0a3a7c129c5f585e:/src/leds.vala diff --git a/src/leds.vala b/src/leds.vala new file mode 100644 index 0000000..a089ef6 --- /dev/null +++ b/src/leds.vala @@ -0,0 +1,226 @@ +/* + * leds - Leds/buttons support + * + * Copyright (C) 2010 Enrico Zini + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +using GLib; + +namespace zavai { +namespace led { + +public class LedState +{ + public string name; + public int brightness; + public string trigger; + public int delay_on; + public int delay_off; + + public LedState(string name) + { + this.name = name; + set_constant(0); + } + + public void set_constant(int power) + { + brightness = power; + trigger = "none"; + delay_on = 0; + delay_off = 0; + } + + public void set_blink(int power, int delay_on=200, int delay_off=300) + { + brightness = power; + trigger = "timer"; + this.delay_on = delay_on; + this.delay_off = delay_off; + } + + public void to_omhacks(ref Omhacks.Led led) + { + led.brightness = brightness; + Memory.copy(led.trigger, trigger, trigger.size()); + led.delay_on = 200; + led.delay_off = 300; + } +} + +public class Vibrator : zavai.Resource, Object +{ + protected Omhacks.Led vibrator; + + protected List states; + + public Vibrator() throws FileError + { + if (vibrator.init("neo1973:vibrator") != 0) + throw new FileError.NOENT("vibrator not found"); + + states = new List(); + } + + public void turn_off() + { + vibrator.brightness = 0; + Memory.copy(vibrator.trigger, "none", 5); + vibrator.set(); + } + + public void push_state(LedState state) + { + states.prepend(state); + state.to_omhacks(ref vibrator); + vibrator.set(); + } + + public void pop_state(string name) + { + // Handle empty list + if (states == null) return; + + // Track if the list head changed + weak List old_top = states; + + // Remove state "name" from the stack + for (weak List i = states; i != null; i = i.next) + if (i.data.name == name) + { + states.delete_link(i); + break; + } + + // If the list head changed, put into action the new top state + if (states != old_top) + if (states == null) + turn_off(); + else { + // Activate the new top + states.data.to_omhacks(ref vibrator); + vibrator.set(); + } + } + + public void shutdown() + { + while (states != null) + states.delete_link(states); + turn_off(); + } +} + +public class AUX: zavai.Service +{ + protected Omhacks.Led auxled; + protected bool has_aux; + + protected weak clock.AlarmTriggerInfo current_alarm = null; + + public AUX() + { + Object(name: "ui.aux"); + + has_aux = (auxled.init("gta02-aux:red") == 0); + + if (has_aux) + { + zavai.log.warning("aux: can notify alarm triggers"); + clock.alarm_trigger_queue.triggered += on_alarm_trigger; + clock.alarm_trigger_queue.acked += on_alarm_done; + clock.alarm_trigger_queue.canceled += on_alarm_done; + } else { + zavai.log.warning("aux: no way to notify alarm triggers"); + } + + // Listen to the button via X + input.hotkeys.hotkey += on_auxbutton; + input.hotkeys.grab(zavai.config.aux_button_keycode, 0, false); + input.hotkeys.request("auxbutton"); + } + + protected bool on_auxbutton(uint keycode, ulong time, bool pressed) + { + if (keycode == zavai.config.aux_button_keycode) + { + if (pressed) + { + zavai.log.debug("AUX button pressed"); + if (current_alarm != null) + { + zavai.log.debug("HASCA"); + clock.alarm_trigger_queue.ack(current_alarm); + } + } + else + zavai.log.debug("AUX button released"); + return true; + } + return false; + } + + public void on_alarm_trigger(clock.AlarmTriggerInfo info) + { + zavai.log.debug("Start blinking"); + auxled.brightness = 256; + // FIXME: is there a better way? I hope there is a better way. Please + // tell me there is a better way. + var trig = "timer"; + for (int i = 0; ; ++i) + { + auxled.trigger[i] = (char)trig[i]; + if (trig[i] == 0) break; + } + auxled.delay_on = 200; + auxled.delay_off = 300; + auxled.set(); + current_alarm = info; + } + + public void on_alarm_done(clock.AlarmTriggerInfo info) + { + zavai.log.debug("Stop blinking"); + var trig = "none"; + for (int i = 0; ; ++i) + { + auxled.trigger[i] = (char)trig[i]; + if (trig[i] == 0) break; + } + auxled.brightness = 0; + auxled.set(); + current_alarm = null; + } +} + +public AUX aux = null; +public Vibrator vibrator = null; + +public void init() +{ + aux = new AUX(); + try { + vibrator = new Vibrator(); + zavai.registry.register(vibrator); + } catch (Error e) { + zavai.log.info("No vibrator found"); + vibrator = null; + } +} + +} +}