system time, automatically sync it
if GPS time is more than 1 hour different than the system time, show a
"SYNC" button that will sync it if pressed
- - stacked notifier, with stacked modal dialogs
- (notify sms received during phone ringing during alarm)
- - aux acks the topmost dialog
- - custom ringtone per every notifier (stops ringtone of modifier below,
- saving the time offset of playing so it can be reloaded and resumed)
- log
- flash aux when there are unacknowledged log entries
- write data to disk as log happens (to have at least partial logs if power
- more detailed GPX data (dop, elev..)
- message (structured) (json?)
- turn on/off gsm
- - play ringtone when someone calls (not useful to pick up, but just to
- notify a call is there)
- (but stop ringtone if aux pressed in the meantime, to avoid annoying
- people)
- pick up phone call
- phone call applet (pushed when picking up)
- buttons for dtmf
}
*/
-public class AlarmNotifier : zavai.Resource, Gtk.Window
+protected class AlarmNotifierDialog : ui.notify.Notifier
{
- protected Gtk.VBox vbox;
- protected bool shown;
protected Gtk.Label message;
- protected Gtk.Button ack;
- protected uint cancel_timeout;
- protected weak clock.AlarmTriggerInfo current = null;
+ protected Gtk.Button message_button;
- public AlarmNotifier()
+ public AlarmNotifierDialog(string title, string text)
{
Object(
- type: Gtk.WindowType.TOPLEVEL,
- title: "Alarm"
+ notifier_name: "alarm",
+ title: title
);
- shown = false;
- destroy_with_parent = true;
- set_transient_for(zavai.app);
- set_modal(true);
- set_position(Gtk.WindowPosition.CENTER_ON_PARENT);
- set_size_request(300, 500);
-
- vbox = new Gtk.VBox(false, 0);
- add(vbox);
- cancel_timeout = 0;
-
- //destroy += Gtk.main_quit;
- //set_events(get_events() | Gdk.EventMask.VISIBILITY_NOTIFY_MASK);
- //visibility_notify_event += on_visibility;
- set_skip_pager_hint(true);
- set_skip_taskbar_hint(true);
- set_type_hint(Gdk.WindowTypeHint.POPUP_MENU);
+ set_size_request(300, 500);
- message = new Gtk.Label("no message");
- vbox.pack_start(message, false, true, 0);
+ add_button(Gtk.STOCK_OK, Gtk.ResponseType.OK);
+ add_button(Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL);
+ set_default_response(Gtk.ResponseType.OK);
- ack = new Gtk.Button.with_label("Ack");
- ack.clicked += on_iface_ack;
- vbox.pack_start(ack, true, true, 0);
+ weak Gtk.VBox vbox = (Gtk.VBox)get_content_area();
- //vbox.show_all();
- zavai.registry.register(this);
+ message = new Gtk.Label(text);
+ message_button = new Gtk.Button();
+ message_button.set_image(message);
+ message_button.clicked += (b) => { response(Gtk.ResponseType.OK); };
+ vbox.pack_start(message_button, true, true, 0);
+ message_button.show();
+ }
- clock.alarm_trigger_queue.triggered += on_trigger;
- clock.alarm_trigger_queue.acked += on_done;
- clock.alarm_trigger_queue.canceled += on_done;
+ protected override bool push_aux_state()
+ {
+ var state = new zavai.led.LedState(notifier_name);
+ state.set_blink(255);
+ zavai.led.aux.push_state(state);
+ return true;
}
- protected void abort_timeout()
+ protected override bool push_vibrator_state()
{
- if (cancel_timeout != 0)
- {
- Source.remove(cancel_timeout);
- cancel_timeout = 0;
- }
+ var state = new zavai.led.LedState(notifier_name);
+ state.set_blink(255);
+ zavai.led.vibrator.push_state(state);
+ return true;
}
- protected void on_iface_ack()
+ protected override bool push_ringtone_state()
{
- if (current == null) return;
- clock.alarm_trigger_queue.ack(current);
+ var state = new zavai.audio.PlayerState(notifier_name, config.ringtone_alarm, true);
+ zavai.audio.soundplayer.push_state(state);
+ return true;
}
+}
- protected bool on_iface_timeout()
+public class AlarmNotifier : zavai.Resource, Object
+{
+ protected weak clock.AlarmTriggerInfo current = null;
+ protected AlarmNotifierDialog dialog = null;
+
+ public AlarmNotifier()
{
- if (current == null) return false;
- clock.alarm_trigger_queue.cancel(current);
- return false;
+ zavai.registry.register(this);
+
+ clock.alarm_trigger_queue.triggered += on_trigger;
+ clock.alarm_trigger_queue.acked += on_done;
+ clock.alarm_trigger_queue.canceled += on_done;
}
public void on_trigger(clock.AlarmTriggerInfo info)
{
current = info;
- message.set_text(info.label);
+ dialog = new AlarmNotifierDialog("Alarm", info.label);
- ui.power.backlight.request("alarmnotifier");
+ if (zavai.led.auxbutton != null)
+ zavai.led.auxbutton.event += on_auxbutton;
- if (!shown)
+ uint cancel_timeout = 0;
+ cancel_timeout = Timeout.add(30 * 1000, () => {
+ dialog.response(Gtk.ResponseType.CANCEL);
+ cancel_timeout = 0;
+ return false;
+ });
+ int res = dialog.run();
+ if (cancel_timeout != 0) Source.remove(cancel_timeout);
+ switch (res)
{
- show_all();
- show();
- visible = true;
- present();
- shown = true;
- } else {
- // TODO: do more in case it is visible but has no visibility (is covered by others)
- visible = !visible;
- if (visible)
- present();
+ case Gtk.ResponseType.OK:
+ clock.alarm_trigger_queue.ack(current);
+ break;
+ case Gtk.ResponseType.CANCEL:
+ clock.alarm_trigger_queue.cancel(current);
+ break;
}
- abort_timeout();
- cancel_timeout = Timeout.add(30 * 1000, on_iface_timeout);
+ if (zavai.led.auxbutton != null)
+ zavai.led.auxbutton.event -= on_auxbutton;
+
+ dialog.destroy();
+ dialog = null;
+ current = null;
+ }
+
+ protected bool on_auxbutton(ulong time, bool pressed)
+ {
+ if (dialog == null) return false;
+ dialog.response(Gtk.ResponseType.OK);
+ return true;
}
public void on_done(clock.AlarmTriggerInfo info)
{
- if (current == null || current != info) return;
- visible = false;
- abort_timeout();
- current = null;
- ui.power.backlight.release("alarmnotifier");
+ if (current == null || dialog == null || current != info) return;
+ dialog.response(Gtk.ResponseType.NONE);
}
public void shutdown()
{
- abort_timeout();
+ if (dialog == null) return;
+ dialog.response(Gtk.ResponseType.CANCEL);
}
}
+++ /dev/null
-/*
- * app_aux - AUX button interaction
- *
- * Copyright (C) 2010 Enrico Zini <enrico@enricozini.org>
- *
- * 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 ui {
-namespace aux {
-
-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 void init()
-{
- aux = new AUX();
-}
-
-}
-}
-}
{
protected Gtk.Label l_status;
protected PlayPauseButton b_playpause;
- protected Gtk.Button b_stop;
+ //protected Gtk.Button b_stop;
protected Gtk.Button b_prev;
protected Gtk.Button b_next;
l_status = new Gtk.Label("");
//l_date.modify_font(Pango.FontDescription.from_string("Sans 40"));
b_playpause = new PlayPauseButton();
- b_stop = new Gtk.Button.from_stock(Gtk.STOCK_MEDIA_STOP);
- b_stop.clicked += (b) => { audio.musicplayer.stop(); };
+ //b_stop = new Gtk.Button.from_stock(Gtk.STOCK_MEDIA_STOP);
+ //b_stop.clicked += (b) => { audio.musicplayer.stop(); };
b_prev = new Gtk.Button.from_stock(Gtk.STOCK_MEDIA_PREVIOUS);
b_next = new Gtk.Button.from_stock(Gtk.STOCK_MEDIA_NEXT);
pack_start(l_status, false, false, 0);
var buttons = new Gtk.HButtonBox();
buttons.add(b_prev);
buttons.add(b_playpause);
- buttons.add(b_stop);
+ //buttons.add(b_stop);
buttons.add(b_next);
pack_start(buttons, false, false, 0);
--- /dev/null
+/*
+ * app_notify - zavai notification system
+ *
+ * Copyright (C) 2010 Enrico Zini <enrico@enricozini.org>
+ *
+ * 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 ui {
+namespace notify {
+
+public abstract class Notifier : Gtk.Dialog
+{
+ public string notifier_name { get; construct; }
+
+ construct {
+ set_transient_for(zavai.app);
+ set_modal(true);
+ set_position(Gtk.WindowPosition.CENTER_ON_PARENT);
+ }
+
+ protected virtual bool push_aux_state()
+ {
+ return false;
+ }
+
+ protected virtual bool push_vibrator_state()
+ {
+ return false;
+ }
+
+ protected virtual bool push_ringtone_state()
+ {
+ return false;
+ }
+
+ public int run()
+ {
+ ui.power.backlight.request(notifier_name);
+
+ // Setup our attention seeking strategy
+ bool has_aux = zavai.led.aux != null && push_aux_state();
+ bool has_vibrator = zavai.led.vibrator != null && push_vibrator_state();
+ bool has_ringtone = zavai.audio.soundplayer != null && push_ringtone_state();
+
+ // Run dialog
+ int res = base.run();
+
+ if (has_ringtone) zavai.audio.soundplayer.pop_state(notifier_name);
+ if (has_vibrator) zavai.led.vibrator.pop_state(notifier_name);
+ if (has_aux) zavai.led.aux.pop_state(notifier_name);
+
+ ui.power.backlight.release(notifier_name);
+ return res;
+ }
+}
+
+protected class CallNotifierDialog : ui.notify.Notifier
+{
+ protected Gtk.Label message;
+ protected Gtk.Button message_button;
+
+ public CallNotifierDialog(string title, string text)
+ {
+ Object(
+ notifier_name: "call",
+ title: title
+ );
+
+ set_size_request(300, 500);
+
+ add_button(Gtk.STOCK_OK, Gtk.ResponseType.OK);
+ add_button(Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL);
+ set_default_response(Gtk.ResponseType.OK);
+
+ weak Gtk.VBox vbox = (Gtk.VBox)get_content_area();
+
+ message = new Gtk.Label(text);
+ message_button = new Gtk.Button();
+ message_button.set_image(message);
+ message_button.clicked += (b) => { response(Gtk.ResponseType.OK); };
+ vbox.pack_start(message_button, true, true, 0);
+ message_button.show();
+ }
+
+ protected override bool push_aux_state()
+ {
+ var state = new zavai.led.LedState(notifier_name);
+ state.set_blink(255);
+ zavai.led.aux.push_state(state);
+ return true;
+ }
+
+ protected override bool push_vibrator_state()
+ {
+ var state = new zavai.led.LedState(notifier_name);
+ state.set_blink(255);
+ zavai.led.vibrator.push_state(state);
+ return true;
+ }
+
+ protected override bool push_ringtone_state()
+ {
+ var state = new zavai.audio.PlayerState(notifier_name, config.ringtone_call, true);
+ zavai.audio.soundplayer.push_state(state);
+ return true;
+ }
+}
+
+public class CallNotifier : zavai.Resource, ui.notify.Notifier
+{
+ protected int call_index = -1;
+ protected CallNotifierDialog dialog = null;
+
+ public CallNotifier()
+ {
+ zavai.registry.register(this);
+
+ zavai.gsm.gsm.new_call += trigger;
+ zavai.gsm.gsm.end_call += done;
+ }
+
+ public void trigger(int index)
+ {
+ call_index = index;
+ dialog = new CallNotifierDialog("Call", "TODO");
+
+ if (zavai.led.auxbutton != null)
+ zavai.led.auxbutton.event += on_auxbutton;
+
+ int res = dialog.run();
+ switch (res)
+ {
+ case Gtk.ResponseType.OK:
+ // TODO clock.alarm_trigger_queue.ack(current);
+ break;
+ case Gtk.ResponseType.CANCEL:
+ // TODO clock.alarm_trigger_queue.cancel(current);
+ break;
+ }
+
+ if (zavai.led.auxbutton != null)
+ zavai.led.auxbutton.event -= on_auxbutton;
+
+ dialog.destroy();
+ dialog = null;
+ call_index = -1;
+ }
+
+ protected bool on_auxbutton(ulong time, bool pressed)
+ {
+ if (dialog == null) return false;
+ dialog.response(Gtk.ResponseType.OK);
+ return true;
+ }
+
+ public void done(int index)
+ {
+ if (call_index != index || dialog == null) return;
+ dialog.response(Gtk.ResponseType.NONE);
+ }
+
+ public void shutdown()
+ {
+ if (dialog == null) return;
+ dialog.response(Gtk.ResponseType.CANCEL);
+ }
+}
+
+public CallNotifier call = null;
+
+public void sms()
+{
+ var ps = new zavai.audio.PlayerState("gsm", zavai.config.ringtone_sms, false);
+ zavai.audio.soundplayer.push_state(ps);
+}
+
+public void init()
+{
+ call = new CallNotifier();
+
+ zavai.gsm.gsm.new_sms += sms;
+}
+
+}
+}
+}
public class Audio: zavai.Service
{
- protected Omhacks.Led vibrator;
- protected bool has_vibrator;
-
/*
protected dynamic DBus.Object audiodev;
protected dynamic DBus.Object vibdev;
{
Object(name: "audio");
- has_vibrator = (vibrator.init("neo1973:vibrator") == 0);
-
/*
audiodev = zavai.registry.sbus.get_object(
"org.freesmartphone.odeviced",
"/org/freesmartphone/Device/LED/neo1973_vibrator",
"org.freesmartphone.Device.LED");
*/
- clock.alarm_trigger_queue.triggered += on_alarm_trigger;
- clock.alarm_trigger_queue.acked += on_alarm_done;
- clock.alarm_trigger_queue.canceled += on_alarm_done;
}
+}
- public void on_alarm_trigger(clock.AlarmTriggerInfo info)
+public class PlayerState : Object
+{
+ protected SoundPlayer soundplayer;
+ protected Gst.Element player;
+ public string owner;
+ public string uri;
+ public bool loop;
+
+ public PlayerState(string owner, string uri, bool loop=false)
{
- zavai.log.debug("Make noise for alarm");
- if (has_vibrator)
+ soundplayer = null;
+
+ this.owner = owner;
+ this.uri = uri;
+ this.loop = loop;
+
+ player = Gst.ElementFactory.make("playbin", null);
+ var bus = player.get_bus();
+ bus.add_signal_watch();
+ bus.message += on_message;
+
+ player.set_property("uri", uri);
+ player.set_state(Gst.State.PAUSED);
+ }
+
+ public void register(SoundPlayer sp)
+ {
+ soundplayer = sp;
+ }
+
+ public void stop()
+ {
+ player.set_state(Gst.State.NULL);
+ }
+
+ public void pause()
+ {
+ player.set_state(Gst.State.PAUSED);
+ }
+
+ public void resume()
+ {
+ player.set_state(Gst.State.PLAYING);
+ }
+
+ protected void on_message(Gst.Message message)
+ {
+ if (message.type == Gst.MessageType.EOS)
{
- vibrator.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)
+ if (loop)
{
- vibrator.trigger[i] = (char)trig[i];
- if (trig[i] == 0) break;
+ player.seek_simple(Gst.Format.TIME, Gst.SeekFlags.FLUSH | Gst.SeekFlags.KEY_UNIT, 0);
+ player.set_state(Gst.State.PLAYING);
}
- vibrator.delay_on = 200;
- vibrator.delay_off = 300;
- vibrator.set();
+ else if (soundplayer != null)
+ soundplayer.pop_state(owner);
}
- soundplayer.play(config.ringtone_alarm, true);
+ }
+}
+
+public class SoundPlayer : zavai.Resource, Object
+{
+ protected List<PlayerState> states;
+ protected MusicPlayer slave;
+ protected bool slave_was_playing;
+
+ public SoundPlayer()
+ {
+ states = new List<PlayerState>();
+ }
+
+ public void set_slave(MusicPlayer player)
+ {
+ slave = player;
+ slave.master = this;
+ }
+
+ public bool playing()
+ {
+ return states != null;
}
- public void on_alarm_done(clock.AlarmTriggerInfo info)
+ protected void stop_playing()
{
- zavai.log.debug("Stop noise for alarm");
- if (has_vibrator)
+ if (slave_was_playing)
+ slave.resume();
+ }
+
+ public void push_state(PlayerState state)
+ {
+ // Save current playing position
+ if (states == null)
{
- var trig = "none";
- for (int i = 0; ; ++i)
+ // We start playing: see about preempting slave
+ slave_was_playing = (slave != null && slave.playing);
+ if (slave_was_playing)
+ slave.pause();
+ } else
+ // We were playing: pause previous sound
+ states.data.pause();
+ state.register(this);
+ states.prepend(state);
+ states.data.resume();
+ }
+
+ public void pop_state(string owner)
+ {
+ // Handle empty list
+ if (states == null) return;
+
+ // Track if the list head changed
+ weak List<PlayerState> old_top = states;
+
+ // Remove state "name" from the stack
+ for (weak List<PlayerState> i = states; i != null; i = i.next)
+ if (i.data.owner == owner)
{
- vibrator.trigger[i] = (char)trig[i];
- if (trig[i] == 0) break;
+ i.data.stop();
+ states.delete_link(i);
+ break;
}
- vibrator.brightness = 0;
- vibrator.set();
+
+ // If the list head changed, put into action the new top state
+ if (states != old_top)
+ {
+ if (states == null)
+ stop_playing();
+ else
+ states.data.resume();
}
- soundplayer.stop();
}
-/*
- public void notify_alarm(zavai.clock.Alarm a)
- {
- // Wiggle screen to turn on backlight
- zavai.ui.power.backlight.wiggle();
- try {
- // Method does not exist in this frameworkd
- vibdev.BlinkSeconds(5, 500, 200);
- } catch (Error e) {
- zavai.log.error("Cannot blink vibrator: " + e.message);
+ public void shutdown()
+ {
+ while (states != null)
+ {
+ states.data.stop();
+ states.delete_link(states);
}
- // TODO: play music?
+ stop_playing();
}
-*/
}
-public class Player: zavai.Resource, Object
+public class MusicPlayer: zavai.Resource, Object
{
protected Gst.Element player;
- protected bool playing;
- protected Player slave;
- protected Player master;
- protected bool loop;
- protected string uri;
+ public SoundPlayer master;
public signal void state_changed(Gst.State new_state);
+ public string uri;
+ public bool playing;
- public Player()
+ public MusicPlayer()
{
- slave = null;
master = null;
- player = Gst.ElementFactory.make("playbin", null);
+ uri = null;
playing = false;
- loop = false;
+ player = Gst.ElementFactory.make("playbin", null);
var bus = player.get_bus();
bus.add_signal_watch();
bus.message += on_message;
}
- public void set_slave(Player player)
+ public void play(string uri)
{
- slave = player;
- slave.master = this;
+ this.uri = uri;
+ playing = true;
+ player.set_property("uri", uri);
+ player.set_state(master != null && master.playing() ? Gst.State.PAUSED : Gst.State.PLAYING);
}
- public void play(string uri, bool loop = false)
+ protected void stop_playing()
{
-stderr.printf("Playing %s\n", uri);
- this.uri = uri;
-
- if (slave != null && slave.playing)
- slave.pause();
-
- player.set_property("uri", uri);
- player.set_state(master != null && master.playing ? Gst.State.PAUSED : Gst.State.PLAYING);
- playing = true;
- this.loop = loop;
+ player.set_state(Gst.State.NULL);
+ state_changed(Gst.State.NULL);
}
public Gst.State get_state()
{
- Gst.State state;
- Gst.State pending;
-
- player.get_state(out state, out pending, (Gst.ClockType)Gst.CLOCK_TIME_NONE);
-
- return state;
+ return player.current_state;
}
public void pause()
{
+ playing = false;
player.set_state(Gst.State.PAUSED);
state_changed(Gst.State.PAUSED);
}
public void resume()
{
- player.set_state(Gst.State.PLAYING);
- state_changed(Gst.State.PLAYING);
+ playing = true;
+ if (master == null || !master.playing())
+ {
+ player.set_state(Gst.State.PLAYING);
+ state_changed(Gst.State.PLAYING);
+ }
}
public void restart()
state_changed(Gst.State.PLAYING);
}
- public void stop()
- {
- playing = false;
- player.set_state(Gst.State.NULL);
- state_changed(Gst.State.NULL);
-
- // Resume slave after we are done
- if (slave != null && slave.playing)
- slave.resume();
- }
-
protected void on_message(Gst.Message message)
{
if (message.type == Gst.MessageType.EOS)
{
- if (loop)
- restart();
- else
- stop();
+ playing = false;
+ stop_playing();
}
}
public void shutdown()
{
- stop();
+ stop_playing();
}
}
public Audio audio = null;
-public Player musicplayer = null;
-public Player soundplayer = null;
+public SoundPlayer soundplayer = null;
+public MusicPlayer musicplayer = null;
public void init()
{
audio = new Audio();
- musicplayer = new Player();
- soundplayer = new Player();
+ musicplayer = new MusicPlayer();
+ soundplayer = new SoundPlayer();
soundplayer.set_slave(musicplayer);
zavai.registry.register(musicplayer);
zavai.registry.register(soundplayer);
info.acked = true;
acked(info);
info.log.add("alarm acknowledged");
+ info.log.acked = true;
zavai.log.log.end(info.log);
}
done_with_first();
set { _ringtone_alarm = set_string("ringtone_alarm", value); }
}
+ private string _ringtone_call;
+ public string ringtone_call
+ {
+ get { return _ringtone_call; }
+ set { _ringtone_call = set_string("ringtone_call", value); }
+ }
+
+ private string _ringtone_sms;
+ public string ringtone_sms
+ {
+ get { return _ringtone_sms; }
+ set { _ringtone_sms = set_string("ringtone_sms", value); }
+ }
+
public int backlight_max
{
get;
_power_button_keycode = get_int("power_button_keycode");
_aux_button_keycode = get_int("aux_button_keycode");
_ringtone_alarm = get_string("ringtone_alarm");
+ _ringtone_call = get_string("ringtone_call");
+ _ringtone_sms = get_string("ringtone_sms");
}
public Config()
power_button_keycode = 124;
aux_button_keycode = 177;
ringtone_alarm = "file:///usr/share/sounds/yue-fso/lec1.ogg";
+ ringtone_call = "file:///usr/share/sounds/yue-fso/jmf1.ogg";
+ ringtone_sms = "file:///usr/share/sounds/yue-fso/nothing4.ogg";
// Read config
if (lua.do_file(homedir + "/config"))
if (el == null)
return false;
- requests.delete_link(el);
+ ++el.data.count;
+ if (el.data.count == 0)
+ requests.delete_link(el);
if (requests != null)
return false;
public signal void status_changed(string message);
public signal void info_changed();
+ public signal void new_call(int index);
+ public signal void end_call(int index);
+ public signal void new_sms();
protected void dump_table(HashTable<string, Value?> vals)
{
public void on_call_status(int index, string status, HashTable<string, Value?> properties)
{
+ bool is_new = false;
+ bool is_done = false;
stderr.printf("CALL STATUS %d %s\n", index, status);
dump_table(properties);
CallInfo? info = lookup_call(index);
if (info == null)
{
+ is_new = true;
Value? v = properties.lookup("peer");
string title;
if (v != null)
calls.delete_link(i);
break;
}
+ is_done = true;
}
/*
os.system("vibrator-stop")
os.system("ledctrl --off gta02-aux:red");
*/
+
+ if (is_new && !is_done)
+ new_call(index);
+ if (is_done)
+ end_call(index);
}
public async void sms_log_and_delete(int idx)
// Delete message
yield sim.delete_message(idx);
+
+ // Notify reception of the sms
+ new_sms();
}
}
--- /dev/null
+/*
+ * leds - Leds support
+ *
+ * Copyright (C) 2010 Enrico Zini <enrico@enricozini.org>
+ *
+ * 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 Led : zavai.Resource, Object
+{
+ protected Omhacks.Led led;
+
+ protected List<LedState> states;
+
+ public Led(string name) throws FileError
+ {
+ if (led.init(name) != 0)
+ throw new FileError.NOENT("led " + name + " not found");
+ states = new List<LedState>();
+ }
+
+ public void turn_off()
+ {
+ led.brightness = 0;
+ Memory.copy(led.trigger, "none", 5);
+ led.set();
+ }
+
+ public void push_state(LedState state)
+ {
+ states.prepend(state);
+ state.to_omhacks(ref led);
+ led.set();
+ }
+
+ public void pop_state(string name)
+ {
+ // Handle empty list
+ if (states == null) return;
+
+ // Track if the list head changed
+ weak List<LedState> old_top = states;
+
+ // Remove state "name" from the stack
+ for (weak List<LedState> 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 led);
+ led.set();
+ }
+ }
+
+ public void shutdown()
+ {
+ while (states != null)
+ states.delete_link(states);
+ turn_off();
+ }
+}
+
+public class AUXButton: zavai.Service
+{
+ public signal bool event(ulong time, bool pressed);
+
+ public AUXButton()
+ {
+ // 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)
+ return event(time, pressed);
+ return false;
+ }
+}
+
+public Led aux = null;
+public Led vibrator = null;
+public AUXButton auxbutton = null;
+
+public void init()
+{
+ auxbutton = new AUXButton();
+
+ try {
+ aux = new Led("gta02-aux:red");
+ zavai.registry.register(aux);
+ } catch (Error e) {
+ zavai.log.info("No aux led found");
+ aux = null;
+ }
+
+ try {
+ vibrator = new Led("neo1973:vibrator");
+ zavai.registry.register(vibrator);
+ } catch (Error e) {
+ zavai.log.info("No vibrator found");
+ vibrator = null;
+ }
+}
+
+}
+}
zavai.clock.init();
zavai.audio.init();
zavai.log.init();
+ zavai.led.init();
zavai.wifi.init();
zavai.bluetooth.init();
// User interface
zavai.ui.music.init();
zavai.ui.main.init();
+ zavai.ui.notify.init();
zavai.ui.gps.init();
zavai.ui.gsm.init();
zavai.config.find_and_run_script("display", "init");
zavai.ui.power.init();
- zavai.ui.aux.init();
zavai.ui.kbd.init();
zavai.ui.wm.init();
zavai.ui.calendar.init();
{
zavai.audio.musicplayer.play("file://" + args[2]);
- // Timeout.add(3 * 1000, () => {
- // zavai.audio.soundplayer.play("file:///backup/ciapino/src/openmoocow/data/moo.wav", true);
- // Timeout.add(4 * 1000, () => {
- // zavai.audio.soundplayer.stop();
- // return false;
- // });
- // return false;
- // });
+ Timeout.add(2 * 1000, () => {
+ var ps = new zavai.audio.PlayerState("zavai", "file:///backup/ciapino/src/openmoocow/data/moo.wav", true);
+ zavai.audio.soundplayer.push_state(ps);
+ Timeout.add(8 * 1000, () => {
+ zavai.audio.soundplayer.pop_state("zavai");
+ return false;
+ });
+ return false;
+ });
+
+ Timeout.add(3 * 1000, () => {
+ var ps = new zavai.audio.PlayerState("zavai", zavai.config.ringtone_alarm, false);
+ zavai.audio.soundplayer.push_state(ps);
+ Timeout.add(4 * 1000, () => {
+ zavai.audio.soundplayer.pop_state("zavai");
+ return false;
+ });
+ return false;
+ });
}
Gtk.main();