Reunified sources, as there seemed to be only disadvantages in compilation time
authorEnrico Zini <enrico@enricozini.org>
Sat, 27 Mar 2010 11:46:25 +0000 (11:46 +0000)
committerEnrico Zini <enrico@enricozini.org>
Sat, 27 Mar 2010 11:46:25 +0000 (11:46 +0000)
48 files changed:
CMakeLists.txt
src/CMakeLists.txt
src/at.vala [new file with mode: 0644]
src/audio.vala [new file with mode: 0644]
src/bluetooth.vala [new file with mode: 0644]
src/clock.vala [new file with mode: 0644]
src/config.vala [new file with mode: 0644]
src/core.vala [new file with mode: 0644]
src/dbus-extra.vapi [new file with mode: 0644]
src/devkit-power-gobject.vapi [new file with mode: 0644]
src/gps.vala [new file with mode: 0644]
src/gsm.vala [new file with mode: 0644]
src/input.vala [new file with mode: 0644]
src/libgps.vapi [new file with mode: 0644]
src/libomhacks.vapi [new file with mode: 0644]
src/linux-input.vapi [new file with mode: 0644]
src/log.vala [new file with mode: 0644]
src/lua5.1.vapi [new symlink]
src/power.vala [new file with mode: 0644]
src/registry.vala [new file with mode: 0644]
src/uevent.vala [new file with mode: 0644]
src/wifi.vala [new file with mode: 0644]
src/x11.vapi [new file with mode: 0644]
src/zavai-calendar.vala [deleted file]
src/zavai.vala
test/CMakeLists.txt
zavai/CMakeLists.txt [deleted file]
zavai/at.vala [deleted file]
zavai/audio.vala [deleted file]
zavai/bluetooth.vala [deleted file]
zavai/clock.vala [deleted file]
zavai/config.vala [deleted file]
zavai/core.vala [deleted file]
zavai/dbus-extra.vapi [deleted file]
zavai/devkit-power-gobject.vapi [deleted file]
zavai/gps.vala [deleted file]
zavai/gsm.vala [deleted file]
zavai/input.vala [deleted file]
zavai/libgps.vapi [deleted file]
zavai/libomhacks.vapi [deleted file]
zavai/linux-input.vapi [deleted file]
zavai/log.vala [deleted file]
zavai/lua5.1.vapi [deleted symlink]
zavai/power.vala [deleted file]
zavai/registry.vala [deleted file]
zavai/uevent.vala [deleted file]
zavai/wifi.vala [deleted file]
zavai/x11.vapi [deleted file]

index 468379e0ec7124fb9a52dd4c54fb8b9694874a62..121d32a563982b01955ae83c4746a3aff41e5ee3 100644 (file)
@@ -4,7 +4,6 @@ set(zavai_version "0.1")
 add_subdirectory(gtkfisheyelist)
 add_subdirectory(polygen)
 add_subdirectory(player)
-add_subdirectory(test)
-add_subdirectory(zavai)
 add_subdirectory(src)
+add_subdirectory(test)
 #add_subdirectory(hooks)
index 06cacbd24af4981a1bdd7369afb890176ec5f950..e89883298fca434756391d8adea9c0a2529feb1e 100644 (file)
@@ -6,7 +6,7 @@ set(zavai_version 0.1)
 set(packages gtk+-2.0 dbus-glib-1>=0.80 libwnck-1.0>=2.26.0 lua5.1 libomhacks x11 gdk-x11-2.0 libgps gstreamer-0.10)
 add_packages(ZAVAI ${packages})
 
-set(VALA_PACKAGES ${packages} posix linux-input dbus-extra gtkfisheyelist libzavai)
+set(VALA_PACKAGES ${packages} posix linux-input dbus-extra gtkfisheyelist)
 set(VFLAGS --vapidir=${zavai_SOURCE_DIR} --vapidir=${gtkfisheyelist_BINARY_DIR})
 add_definitions(-Wall)
 # -Werror 
@@ -22,24 +22,12 @@ else()
   message("-- Not using devkit-power-gobject")
 endif ()
 
-set(VFLAGS ${VFLAGS} --vapidir=${zavai_BINARY_DIR} --vapidir=${libzavai_SOURCE_DIR} --vapidir=${libzavai_BINARY_DIR})
+add_definitions(-DWNCK_I_KNOW_THIS_IS_UNSTABLE -DI_KNOW_THE_DEVICEKIT_POWER_API_IS_SUBJECT_TO_CHANGE -I${gtkfisheyelist_BINARY_DIR} -I${zavai_BINARY_DIR})
+link_libraries(gtkfisheyelist-static)
 
-file(GLOB libvala [a-y]*.vala widgets/*.vala)
-add_vala_library(libzavaiui ${libvala})
-add_library(libzavaiui STATIC ${libzavaiui_CSOURCES})
-
-add_definitions(-DWNCK_I_KNOW_THIS_IS_UNSTABLE -DI_KNOW_THE_DEVICEKIT_POWER_API_IS_SUBJECT_TO_CHANGE -I${gtkfisheyelist_BINARY_DIR} -I${zavai_BINARY_DIR} -I${libzavai_BINARY_DIR})
-set(VALA_PACKAGES ${VALA_PACKAGES} libzavai libzavaiui)
-link_libraries(gtkfisheyelist-static libzavai libzavaiui)
-
-file(GLOB zavala zavai.vala)
+file(GLOB zavala *.vala)
 add_vala_program(zavai ${zavala})
 add_executable(zavai ${zavai_CSOURCES})
 
-file(GLOB zacvala zavai-calendar.vala)
-add_vala_program(zavai-calendar ${zacvala})
-add_executable(zavai-calendar ${zavai-calendar_CSOURCES})
-
 install(TARGETS zavai RUNTIME DESTINATION bin)
-install(TARGETS zavai-calendar RUNTIME DESTINATION bin)
 install(FILES sat-monitor DESTINATION bin)
diff --git a/src/at.vala b/src/at.vala
new file mode 100644 (file)
index 0000000..33cdf27
--- /dev/null
@@ -0,0 +1,164 @@
+/*
+ * at - at interface
+ *
+ * Copyright (C) 2009  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 at {
+
+public struct Event
+{
+       int id;
+       time_t deadline;
+}
+
+// Return the earliest ID in the queue, or -1 if none are found
+// Queue is null for all queues, otherwise a queue name
+public static Event earliestID(string? queue = null)
+{
+       Event res = { -1, 0 };
+
+       string argv[4];
+       argv[0] = "/usr/bin/atq";
+       if (queue == null)
+               argv[1] = null;
+       else
+       {
+               argv[1] = "-q";
+               argv[2] = queue;
+               argv[3] = null;
+       }
+
+       Pid pid;
+       int stdout;
+
+       try
+       {
+               if (!Process.spawn_async_with_pipes("/", argv, null, SpawnFlags.STDERR_TO_DEV_NULL, null, out pid, null, out stdout, null))
+                       return res;
+       } catch (SpawnError e) {
+               stderr.printf("Cannot run 'at -q': %s\n", e.message);
+               return res;
+       }
+
+       FileStream fs = FileStream.fdopen(stdout, "r");
+       if (fs == null)
+               return res;
+
+       char buf[200];
+       string? line;
+       while ((line = fs.gets(buf)) != null)
+       {
+               if (!line[0].isdigit()) continue;
+               weak string rest;
+               ulong id = line.to_ulong(out rest, 10);
+               Time t = Time();
+               rest = t.strptime(rest.offset(1), "%a %b %d %H:%M:%S %Y");
+               if (rest == null) continue;
+               if (rest.size() < 2) continue;
+               //stderr.printf("PARSE QUEUE rest %s\n", rest);
+               // Skip the queue of tasks currently being executed
+               //if (rest[1] == '=') continue;
+               // Skip entries not in the wanted queue
+               if (queue != null && rest[1] != queue[0]) continue;
+               time_t tt = t.mktime();
+               if (res.deadline == 0 || tt < res.deadline) {
+                       res.id = (int)id;
+                       res.deadline = tt;
+               }
+       }
+       Process.close_pid(pid);
+       return res;
+}
+
+public delegate bool jobParser(int fd);
+
+// Get the contents of a job given its id
+public static bool jobContents(int id, jobParser parser)
+{
+       string argv[4];
+       argv[0] = "/usr/bin/at";
+       argv[1] = "-c";
+       argv[2] = id.to_string();
+       argv[3] = null;
+
+       Pid pid;
+       int stdoutfd;
+
+       try
+       {
+               if (!Process.spawn_async_with_pipes("/", argv, null, SpawnFlags.STDERR_TO_DEV_NULL, null, out pid, null, out stdoutfd, null))
+                       return false;
+       } catch (SpawnError e) {
+               stderr.printf("Cannot run 'at -c': %s\n", e.message);
+               return false;
+       }
+
+       bool res = parser(stdoutfd);
+
+       Process.close_pid(pid);
+
+       return res;
+}
+
+/*
+TODO: schedule alarms via at
+
+Uses the 'z' queue.
+
+atq -q z  can be used to list the jobs (for example, at startup, or after a job has run)
+at -c id  can be used to query a job, parsing its contents (which can have
+          comments or variables being set)
+zavai --notify ...  can be used to notify the job (and start zavai if it's not running)
+
+Alarm needs to be able to serialize itself to an at invocation and to
+deserialize itself from the output of at -c
+
+Alarm needs to deserialize also a job with no special markers whatsoever: a
+generic at job.
+*/
+
+
+/*
+public class Alarm : Object
+{
+       // TODO: make a factory method to construct from an "at -c" output
+
+       // TODO: make a method that provides an at invocation
+
+       public signal void trigger(Alarm a);
+
+       public time_t deadline;
+       public string label;
+
+       public Alarm(time_t deadline, string label)
+       {
+               this.deadline = deadline;
+               this.label = label;
+       }
+}
+*/
+
+       // Schedule a task that notifies a string
+       // TODO public void schedule_label(const Alarm a);
+
+       // Return the next item in the queue due to be run
+       // TODO public Alarm? next_scheduled();
+
+}
diff --git a/src/audio.vala b/src/audio.vala
new file mode 100644 (file)
index 0000000..1c39420
--- /dev/null
@@ -0,0 +1,225 @@
+/*
+ * audio - audio resource for zavai
+ *
+ * Copyright (C) 2009--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 audio {
+
+public class Audio: zavai.Service
+{
+    protected Omhacks.Led vibrator;
+    protected bool has_vibrator;
+
+    /*
+       protected dynamic DBus.Object audiodev;
+       protected dynamic DBus.Object vibdev;
+   */
+
+    public Audio()
+    {
+        Object(name: "audio");
+
+        has_vibrator = (vibrator.init("neo1973:vibrator") == 0);
+
+/*
+        audiodev = zavai.registry.sbus.get_object(
+                "org.freesmartphone.odeviced",
+                "/org/freesmartphone/Device/Audio",
+                "org.freesmartphone.Device.Audio");
+        vibdev = 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)
+    {
+        zavai.log.debug("Make noise for alarm");
+        if (has_vibrator)
+        {
+            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)
+            {
+                vibrator.trigger[i] = (char)trig[i];
+                if (trig[i] == 0) break;
+            }
+            vibrator.delay_on = 200;
+            vibrator.delay_off = 300;
+            vibrator.set();
+        }
+        soundplayer.play(config.ringtone_alarm, true);
+    }
+
+    public void on_alarm_done(clock.AlarmTriggerInfo info)
+    {
+        zavai.log.debug("Stop noise for alarm");
+        if (has_vibrator)
+        {
+            var trig = "none";
+            for (int i = 0; ; ++i)
+            {
+                vibrator.trigger[i] = (char)trig[i];
+                if (trig[i] == 0) break;
+            }
+            vibrator.brightness = 0;
+            vibrator.set();
+        }
+        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);
+        }
+        // TODO: play music?
+    }
+*/
+}
+
+public class Player: zavai.Resource, Object
+{
+    protected Gst.Element player;
+    protected bool playing;
+    protected Player slave;
+    protected Player master;
+    protected bool loop;
+    protected string uri;
+    public signal void state_changed(Gst.State new_state);
+
+    public Player()
+    {
+        slave = null;
+        master = null;
+        player = Gst.ElementFactory.make("playbin", null);
+        playing = false;
+        loop = false;
+        var bus = player.get_bus();
+        bus.add_signal_watch();
+        bus.message += on_message;
+    }
+
+    public void set_slave(Player player)
+    {
+        slave = player;
+        slave.master = this;
+    }
+
+    public void play(string uri, bool loop = false)
+    {
+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;
+    }
+
+    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;
+    }
+
+    public void pause()
+    {
+        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);
+    }
+
+    public void restart()
+    {
+        player.seek_simple(Gst.Format.TIME, Gst.SeekFlags.FLUSH | Gst.SeekFlags.KEY_UNIT, 0);
+        player.set_state(Gst.State.PLAYING);
+        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();
+        }
+    }
+
+    public void shutdown()
+    {
+        stop();
+    }
+}
+
+public Audio audio = null;
+public Player musicplayer = null;
+public Player soundplayer = null;
+
+public void init()
+{
+    audio = new Audio();
+    musicplayer = new Player();
+    soundplayer = new Player();
+    soundplayer.set_slave(musicplayer);
+    zavai.registry.register(musicplayer);
+    zavai.registry.register(soundplayer);
+}
+
+}
+}
diff --git a/src/bluetooth.vala b/src/bluetooth.vala
new file mode 100644 (file)
index 0000000..0103d0f
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ * bluetooth - bluetooth resource for zavai
+ *
+ * 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 bluetooth {
+
+public class Bluetooth: zavai.ScriptService
+{
+    public Bluetooth()
+    {
+        Object(name: "bluetooth");
+        started = script_status();
+    }
+
+    /// Start Bluetooth
+    public override void start()
+    {
+        if (started) return;
+        if (!script_start()) return;
+        zavai.log.info("bluetooth turned on");
+        base.start();
+    }
+
+    // Release usage of GPS
+    public override void stop()
+    {
+        if (!started) return;
+        script_stop();
+        base.stop();
+    }
+}
+
+public Bluetooth bluetooth = null;
+
+public void init()
+{
+    bluetooth = new Bluetooth();
+
+}
+
+}
+}
diff --git a/src/clock.vala b/src/clock.vala
new file mode 100644 (file)
index 0000000..d08717b
--- /dev/null
@@ -0,0 +1,357 @@
+/*
+ * clock - clock resource for zavai
+ *
+ * Copyright (C) 2009--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 clock {
+
+public enum SourceType
+{
+    SYSTEM,
+    GPS
+}
+
+/*
+TODO: schedule alarms via at
+
+Uses the 'z' queue.
+
+atq -q z  can be used to list the jobs (for example, at startup, or after a job has run)
+at -c id  can be used to query a job, parsing its contents (which can have
+          comments or variables being set)
+zavai --notify ...  can be used to notify the job (and start zavai if it's not running)
+
+Alarm needs to be able to serialize itself to an at invocation and to
+deserialize itself from the output of at -c
+
+Alarm needs to deserialize also a job with no special markers whatsoever: a
+generic at job.
+
+
+
+refresh_alarms()
+{
+    oldtime = next_alarm ? next_alarm.time : 0
+    next_alarm = the first alarm from atq
+    if (oldtime != next_alarm.time)
+    {
+        remove existing triggers
+          (triggers can be skipped if we don't need to support non-zavai alarms)
+        schedule a trigger calling refresh_alarms() at next_alarm.time + 30 seconds
+          (triggers can be skipped if we don't need to support non-zavai alarms)
+    }
+}
+
+at clock constructor: refresh_alarms()
+inotifywait -e close /usr/bin/at -> refresh_alarms()  (shows when someone has just used at)
+  (can be skipped if we don't need to support non-zavai alarms)
+at alarm triggered through zavai: refresh_alarms()
+
+
+*/
+
+
+public class Alarm : Object
+{
+    public at.Event ev;
+    public string label;
+
+    // Schedule with at
+    public static void schedule(string timespec, string label) throws Error
+    {
+        string argv[5];
+        argv[0] = "/usr/bin/at";
+        argv[1] = "-q";
+        argv[2] = "z";
+        argv[3] = timespec;
+        argv[4] = null;
+
+        Pid pid;
+        int stdinfd;
+
+        if (!Process.spawn_async_with_pipes("/", argv, null, SpawnFlags.STDERR_TO_DEV_NULL, null, out pid, out stdinfd, null, null))
+            return;
+
+        {
+            FileStream fs = FileStream.fdopen(stdinfd, "w");
+            string display = GLib.Environment.get_variable("DISPLAY");
+            if (display != null)
+                fs.printf("DISPLAY=\"%s\"; export DISPLAY\n", display);
+            fs.printf("# Zavai variables start here\n");
+            fs.printf("ZAVAI_LABEL=\"%s\"\n", label.escape(""));
+            fs.printf("# Zavai commands starts here\n");
+            fs.printf("%s notify \"$ZAVAI_LABEL\"", zavai.config.argv0);
+        }
+        
+        Process.close_pid(pid);
+    }
+
+    // Get the label of the job with the given at ID
+    public static string? getLabel(int atID)
+    {
+        string label = null;
+        at.jobContents(atID, fd => {
+            FileStream fs = FileStream.fdopen(fd, "r");
+            while (true)
+            {
+                string? line = fs.read_line();
+                if (line == null) break;
+                if (line.has_prefix("ZAVAI_LABEL=\""))
+                {
+                    size_t size = line.size();
+                    if (size < 15) continue;
+                    label = line.substring(13, (long)(size - 14));
+                    label = label.compress();
+                    break;
+                }
+            }
+            return true;
+        });
+        return label;
+    }
+}
+
+[DBus (name = "org.enricozini.zavai.Alarm")]
+public class ZavaiClock : Object {
+    public void Notify (string label) {
+        clock.notify_alarm(label);
+    }
+}
+
+public class AlarmTriggerInfo
+{
+    public uint id;
+    public string label;
+    public bool acked;
+    public bool canceled;
+
+    public AlarmTriggerInfo(string label)
+    {
+        id = 0;
+        this.label = label;
+        acked = false;
+        canceled = false;
+    }
+}
+
+public class AlarmTriggerQueue : zavai.Service
+{
+    protected List<AlarmTriggerInfo> queue;
+
+    public signal void triggered(AlarmTriggerInfo info);
+    public signal void acked(AlarmTriggerInfo info);
+    public signal void canceled(AlarmTriggerInfo info);
+
+    public AlarmTriggerQueue()
+    {
+        queue = new List<AlarmTriggerInfo>();
+    }
+
+    public uint enqueue_trigger(AlarmTriggerInfo info)
+    {
+        // Reuse IDs from the associated logger object
+        info.id = zavai.log.log.start("alarm", "Alarm " + info.label);
+        queue.append(info);
+        if (queue.data.id == info.id)
+            triggered(queue.data);
+        return info.id;
+    }
+
+    protected void done_with_first()
+    {
+        var first = queue.data;
+        queue.remove_link(queue);
+        if (queue != null)
+            triggered(queue.data);
+    }
+
+    public void ack(AlarmTriggerInfo info)
+    {
+        if (queue == null || info.id != queue.data.id) return;
+        if (!info.acked && !info.canceled)
+        {
+            info.acked = true;
+            acked(info);
+            zavai.log.log.add(info.id, "alarm acknowledged");
+            zavai.log.log.end(info.id);
+        }
+        done_with_first();
+    }
+
+    public void cancel(AlarmTriggerInfo info)
+    {
+        if (queue == null || info.id != queue.data.id) return;
+        if (!info.acked && !info.canceled)
+        {
+            info.canceled = true;
+            canceled(info);
+            zavai.log.log.add(info.id, "alarm canceled");
+            zavai.log.log.end(info.id);
+        }
+        done_with_first();
+    }
+}
+
+public class Clock: zavai.Service
+{
+    protected time_t last_gps_time;
+    protected time_t last_gps_time_system_time;
+    protected time_t last_system_time;
+    protected uint system_time_timeout;
+    protected time_t last_minute;
+    protected time_t chosen_time;
+    protected SourceType chosen_type;
+    protected ZavaiClock dbusClock;
+
+    protected dynamic DBus.Object otimed_alarm;
+    protected dynamic DBus.Object rtc;
+    protected SList<Alarm> alarms;
+
+    // Ticks once a minute
+    public signal void minute_changed(long time, SourceType source);
+    public signal void schedule_changed(Alarm? next);
+
+    public Clock()
+    {
+        Object(name: "clock");
+        alarms = null;
+        dbusClock = new ZavaiClock();
+        last_minute = 0;
+        last_gps_time = 0;
+        last_gps_time_system_time = 0;
+        last_system_time = time_t();
+        chosen_time = last_system_time;
+
+        // FSO alarm system
+        otimed_alarm = zavai.registry.sbus.get_object(
+                "org.freesmartphone.otimed",
+                "/org/freesmartphone/Time/Alarm",
+                "org.freesmartphone.Time.Alarm");
+
+        rtc = zavai.registry.sbus.get_object(
+                "org.freesmartphone.odeviced",
+                "/org/freesmartphone/Device/RTC/0",
+                "org.freesmartphone.Device.RealtimeClock");
+
+        zavai.registry.sbus.register_object("/org/enricozini/Zavai/Clock", dbusClock);
+    }
+
+    public void notify_alarm(string label)
+    {
+        stderr.printf("Notifying %s\n", label);
+        AlarmTriggerInfo info = new AlarmTriggerInfo(label);
+        alarm_trigger_queue.enqueue_trigger(info);
+        schedule_changed(next_alarm());
+    }
+
+    public Alarm? next_alarm()
+    {
+        at.Event ev;
+        ev = at.earliestID("z");
+        if (ev.deadline == 0)
+            return null;
+        string label = Alarm.getLabel(ev.id);
+        Alarm res = new Alarm();
+        res.ev = ev;
+        res.label = label;
+        return res;
+    }
+
+    public void schedule(string timespec, string label) throws Error
+    {
+        Alarm.schedule(timespec, label);
+        schedule_changed(next_alarm());
+    }
+
+    private void on_gps_time(uint t)
+    {
+        if (t == 0)
+        {
+            last_gps_time_system_time = 0;
+            update_time();
+        } else {
+            last_gps_time = (time_t)t;
+            last_gps_time_system_time = time_t();
+            update_time();
+        }
+    }
+
+    private bool on_system_time()
+    {
+        last_system_time = time_t();
+        update_time();
+        return true;
+    }
+
+    private void update_time()
+    {
+        if (last_gps_time_system_time + 10 > last_system_time)
+        {
+            chosen_time = last_gps_time;
+            chosen_type = SourceType.GPS;
+        }
+        else
+        {
+            chosen_time = last_system_time;
+            chosen_type = SourceType.SYSTEM;
+        }
+        if (chosen_time / 60 != last_minute)
+        {
+            last_minute = chosen_time / 60;
+            minute_changed(chosen_time, chosen_type);
+        }
+    }
+
+    /// Request GPS resource
+    public override void start()
+    {
+        if (started) return;
+
+        system_time_timeout = Timeout.add(5000, on_system_time);
+        zavai.gps.gps.time_changed += on_gps_time;
+        last_system_time = time_t();
+        update_time();
+
+        base.start();
+    }
+
+    public override void stop()
+    {
+        if (!started) return;
+
+        Source.remove(system_time_timeout);
+        zavai.gps.gps.time_changed -= on_gps_time;
+
+        base.stop();
+    }
+}
+
+public Clock clock = null;
+public AlarmTriggerQueue alarm_trigger_queue = null;
+
+public void init()
+{
+    clock = new Clock();
+    alarm_trigger_queue = new AlarmTriggerQueue();
+}
+
+}
+}
diff --git a/src/config.vala b/src/config.vala
new file mode 100644 (file)
index 0000000..444bbc2
--- /dev/null
@@ -0,0 +1,265 @@
+/*
+ * config - zavai configuration
+ *
+ * Copyright (C) 2009--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
+ */
+
+namespace zavai {
+
+public class Config
+{
+    protected Lua.LuaVM lua;
+    protected weak string get_string(string name)
+    {
+        lua.get_global(name);
+        weak string res = lua.to_string(-1);
+        lua.pop(1);
+        return res;
+    }
+    protected string set_string(string name, string? val)
+    {
+        if (val == null)
+            lua.push_nil();
+        else
+            lua.push_string(val);
+        lua.set_global(name);
+        return val;
+    }
+    protected weak int get_int(string name)
+    {
+        lua.get_global(name);
+        int res = lua.to_integer(-1);
+        lua.pop(1);
+        return res;
+    }
+    protected int set_int(string name, int val)
+    {
+        lua.push_integer(val);
+        lua.set_global(name);
+        return val;
+    }
+
+    private string _version;
+    public string version
+    {
+        get { return _version; }
+        set { _version = set_string("version", value); }
+    }
+
+    // "phone" or "laptop"
+    private string _profile;
+    public string profile
+    {
+        get { return _profile; }
+        set { _profile = set_string("profile", value); }
+    }
+
+    private string _homedir;
+    public string homedir
+    {
+        get { return _homedir; }
+        set { _homedir = set_string("homedir", value); }
+    }
+
+    private string _icondir;
+    public string icondir
+    {
+        get { return _icondir; }
+        set { _icondir = set_string("icondir", value); }
+    }
+
+    private int _min_button_height;
+    public int min_button_height
+    {
+        get { return _min_button_height; }
+        set { _min_button_height = set_int("min_button_height", value); }
+    }
+
+    private string _gpsd_host;
+    public string gpsd_host
+    {
+        get { return _gpsd_host; }
+        set { _gpsd_host = set_string("gpsd_host", value); }
+    }
+
+    private string _gpsd_port;
+    public string gpsd_port
+    {
+        get { return _gpsd_port; }
+        set { _gpsd_port = set_string("gpsd_port", value); }
+    }
+
+    private string _gprs_apn;
+    public string gprs_apn
+    {
+        get { return _gprs_apn; }
+        set { _gprs_apn = set_string("gprs_apn", value); }
+    }
+
+    private string _gprs_user;
+    public string gprs_user
+    {
+        get { return _gprs_user; }
+        set { _gprs_user = set_string("gprs_user", value); }
+    }
+
+    private string _gprs_pass;
+    public string gprs_pass
+    {
+        get { return _gprs_pass; }
+        set { _gprs_pass = set_string("gprs_pass", value); }
+    }
+
+    private string _sim_pin;
+    public string sim_pin
+    {
+        get { return _sim_pin; }
+        set { _sim_pin = set_string("sim_pin", value); }
+    }
+
+    private int _power_button_keycode;
+    public int power_button_keycode
+    {
+        get { return _power_button_keycode; }
+        set { _power_button_keycode = set_int("power_button_keycode", value); }
+    }
+
+    private int _aux_button_keycode;
+    public int aux_button_keycode
+    {
+        get { return _aux_button_keycode; }
+        set { _aux_button_keycode = set_int("aux_button_keycode", value); }
+    }
+
+    private string _ringtone_alarm;
+    public string ringtone_alarm
+    {
+        get { return _ringtone_alarm; }
+        set { _ringtone_alarm = set_string("ringtone_alarm", value); }
+    }
+
+    public int backlight_max
+    {
+        get;
+        set;
+    }
+
+    private string _argv0;
+    public string argv0 {
+        get { return _argv0; }
+        set {
+            if (value.chr(-1, '/') != null)
+            {
+                if (Path.is_absolute(value))
+                {
+                    _argv0 = value;
+                } else {
+                    _argv0 = Path.build_filename(Environment.get_current_dir(), value, null);
+                }
+            } else {
+                _argv0 = Environment.find_program_in_path(value);
+            }
+            zavai.log.debug("ARGV0: " + _argv0);
+        }
+    }
+
+    /// Reread config values from the Lua VM, to be run after running Lua code
+    protected void refresh_from_lua()
+    {
+        _version = get_string("version");
+        _profile = get_string("profile");
+        _homedir = get_string("homedir");
+        _icondir = get_string("icondir");
+        _min_button_height = get_int("min_button_height");
+        _gpsd_host = get_string("gpsd_host");
+        _gpsd_port = get_string("gpsd_port");
+        _gprs_apn = get_string("gprs_apn");
+        _gprs_user = get_string("gprs_user");
+        _gprs_pass = get_string("gprs_pass");
+        _sim_pin = get_string("sim_pin");
+        _power_button_keycode = get_int("power_button_keycode");
+        _aux_button_keycode = get_int("aux_button_keycode");
+        _ringtone_alarm = get_string("ringtone_alarm");
+    }
+
+    public Config()
+    {
+        lua = new Lua.LuaVM();
+        lua.open_libs();
+
+        // Set defaults
+        version = "0.1";
+        profile = "phone";
+        homedir = GLib.Environment.get_home_dir() + "/.zavai";
+        icondir = GLib.Environment.get_variable("ZAVAI_ICONDIR");
+        if (icondir == null)
+                icondir = "/usr/share/zavai/icons";
+        min_button_height = 80;
+        gpsd_host = "localhost";
+        gpsd_port = "gpsd";
+        gprs_apn = "general.t-mobile.uk";
+        gprs_user = "x";
+        gprs_pass = "x";
+        sim_pin = "1234";
+        backlight_max = 15;
+        power_button_keycode = 124;
+        aux_button_keycode = 177;
+        ringtone_alarm = "file:///usr/share/sounds/yue-fso/lec1.ogg";
+
+        // Read config
+        if (lua.do_file(homedir + "/config"))
+        {
+            zavai.log.error("Failed to parse " + homedir + "/config: " + lua.to_string(-1));
+        }
+        refresh_from_lua();
+    }
+
+    public void run_script(string command)
+    {
+        zavai.log.info("Run program: " + command);
+        string[] args = command.split(" ");
+        Pid pid;
+        try {
+            Process.spawn_async(
+                Environment.get_home_dir(),
+                args,
+                null,
+                SpawnFlags.SEARCH_PATH,
+                null,
+                out pid);
+        } catch (SpawnError e) {
+            zavai.log.error("Running " + command + ": " + e.message);
+        }
+    }
+
+    public int run_script_sync(string command, out string std_out, out string std_err)
+    {
+        int status = -1;
+        zavai.log.info("Run program: " + command);
+        string[] args = command.split(" ");
+        try {
+            bool res = Process.spawn_sync(Environment.get_home_dir(), args, null, SpawnFlags.SEARCH_PATH, null, out std_out, out std_err, out status);
+        } catch (SpawnError e) {
+            zavai.log.error("Running " + command + ": " + e.message);
+        }
+        return status;
+    }
+}
+
+public Config config = null;
+
+}
diff --git a/src/core.vala b/src/core.vala
new file mode 100644 (file)
index 0000000..3c31ccd
--- /dev/null
@@ -0,0 +1,279 @@
+/*
+ * app - zavai main window
+ *
+ * Copyright (C) 2009  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 {
+
+public interface Resource : Object {
+    /**
+     * Shut down this resource.
+     *
+     * Normally one does nothing here, but it is important to give resources a
+     * chance to do cleanup when the program quits.
+     * 
+     * This can be used for tasks like closing the tags on a GPX track,
+     * releasing a FSO resource, restoring mixer settings and so on.
+     */
+    public abstract void shutdown();
+}
+
+public abstract class Service : Object, Resource {
+    public string name { get; construct; }
+
+    bool _started;
+    public bool started {
+        get { return _started; }
+        set { _started = value; }
+    }
+
+    public signal void toggled(bool new_state);
+
+    protected class Request
+    {
+        public string requestor;
+        public int count;
+        public Request(string requestor)
+        {
+            this.requestor = requestor;
+            count = 1;
+        }
+    }
+
+    protected List<Request> requests;
+
+    construct
+    {
+        started = false;
+        requests = null;
+        zavai.registry.register(this);
+    }
+
+    public void shutdown()
+    {
+        stop();
+    }
+
+    /// Activate the service
+    protected virtual void start()
+    {
+        if (!started)
+        {
+            zavai.log.info("Service " + name + " started\n");
+            started = true;
+            toggled(started);
+        }
+    }
+
+    /// Deactivate the service
+    protected virtual void stop()
+    {
+        if (started)
+        {
+            zavai.log.info("Service " + name + " stopped\n");
+            started = false;
+            toggled(started);
+        }
+    }
+
+    /**
+      Request a resource using the given ID.
+     *
+     * If it is the first time the resource is requested, start it and
+     * return true. Else, take note of the request and return false.
+     *
+     * If a resource is requested multiple times with the same ID, it will
+     * need to be released multiple times with that ID.
+     */
+    public bool request(string id)
+    {
+        bool res = (requests == null);
+        bool got = false;
+        for (weak List<Request> i = requests; i != null; i = i.next)
+            if (i.data.requestor == id)
+            {
+                ++i.data.count;
+                got = true;
+                break;
+            }
+        if (!got)
+            requests.prepend(new Request(id));
+        if (res) start();
+        return res;
+    }
+
+    /**
+     * Release a resource using the given ID.
+     *
+     * If after the call nothing is requesting the resource, stop it and
+     * return true. Else, take note of the release and return false.
+     *
+     * If a resource is requested multiple times with the same ID, it will
+     * need to be released multiple times with that ID.
+     */
+    public bool release(string id)
+    {
+        weak List<Request> el = null;
+        for (weak List<Request> i = requests; i != null; i = i.next)
+            if (i.data.requestor == id)
+            {
+                el = i;
+                break;
+            }
+
+        if (el == null)
+            return false;
+
+        requests.delete_link(el);
+
+        if (requests != null)
+            return false;
+
+        stop();
+        return true;
+    }
+}
+
+public abstract class ScriptService : Service
+{
+    protected bool script_start()
+    {
+        try {
+            // Then run our own script
+            zavai.config.run_script(zavai.config.homedir + "/" + name + " start");
+            return true;
+        } catch (Error e) {
+            zavai.log.error("Running " + zavai.config.homedir + "/" + name + " start: " + e.message);
+            return false;
+        }
+    }
+
+    protected bool script_stop()
+    {
+        try {
+            // Then run our own script
+            zavai.config.run_script(zavai.config.homedir + "/" + name + " stop");
+            return true;
+        } catch (Error e) {
+            zavai.log.error("Running " + zavai.config.homedir + "/" + name + " stop: " + e.message);
+            return false;
+        }
+    }
+
+    protected bool script_status()
+    {
+        string std_out;
+        string std_err;
+        string command = zavai.config.homedir + "/" + name + " status";
+        int res = zavai.config.run_script_sync(command, out std_out, out std_err);
+        if (res != 0)
+        {
+            zavai.log.error("Running " + command + ": " + std_err);
+            return false;
+        }
+
+        std_out._strip();
+
+        return (std_out == "on");
+    }
+}
+
+public abstract class ScriptMonitorService : Service
+{
+    protected Pid child_pid;
+    protected int child_watch_id;
+
+    ScriptMonitorService()
+    {
+        child_pid = 0;
+        child_watch_id = 0;
+    }
+
+    protected bool script_start()
+    {
+        string command = zavai.config.homedir + "/" + name + " pre";
+        try {
+            // Then run our own script
+            zavai.config.run_script(command);
+        } catch (Error e) {
+            zavai.log.error("Running " + command + ": " + e.message);
+            return false;
+        }
+
+        command = zavai.config.homedir + "/" + name + " run";
+        zavai.log.info("Run program: " + command);
+        string[] args = command.split(" ");
+        try {
+            Process.spawn_async(
+                Environment.get_home_dir(),
+                args,
+                null,
+                SpawnFlags.SEARCH_PATH | SpawnFlags.DO_NOT_REAP_CHILD,
+                null,
+                out child_pid);
+        } catch (SpawnError e) {
+            zavai.log.error("Running " + command + ": " + e.message);
+            return false;
+        }
+
+        // Add a child watch source to know when it ends
+        ChildWatch.add(child_pid, on_child);
+
+        return true;
+    }
+
+    protected bool script_stop()
+    {
+        Posix.kill((Posix.pid_t)child_pid, Posix.SIGTERM);
+        return true;
+    }
+
+    protected void on_child(Pid pid, int status)
+    {
+        zavai.log.info("Exited");
+stderr.printf("STATUS %d\n", status);
+        Process.close_pid(pid);
+
+        string command = zavai.config.homedir + "/" + name + " post";
+        try {
+            // Then run our own script
+            zavai.config.run_script(command);
+        } catch (Error e) {
+            zavai.log.error("Running " + command + ": " + e.message);
+            return;
+        }
+
+        cleanup_after_script_stop();
+
+        base.stop();
+    }
+
+    protected virtual void cleanup_after_script_stop()
+    {
+    }
+
+    /*
+    protected bool script_status()
+    {
+    }
+    */
+}
+
+}
diff --git a/src/dbus-extra.vapi b/src/dbus-extra.vapi
new file mode 100644 (file)
index 0000000..5213899
--- /dev/null
@@ -0,0 +1,5 @@
+namespace DBus {
+       [CCode (cname = "dbus_bus_get_unique_name")]
+       public unowned string bus_get_unique_name (DBus.RawConnection conn);
+}
+
diff --git a/src/devkit-power-gobject.vapi b/src/devkit-power-gobject.vapi
new file mode 100644 (file)
index 0000000..139abc2
--- /dev/null
@@ -0,0 +1,232 @@
+/* devkit-power-gobject.vapi generated by vapigen, do not modify. */
+
+[CCode (cprefix = "Dkp", lower_case_cprefix = "dkp_")]
+namespace Dkp {
+       [CCode (cheader_filename = "devkit-power-gobject/devicekit-power.h")]
+       public class Client : GLib.Object {
+               [CCode (has_construct_function = false)]
+               public Client ();
+               public unowned GLib.PtrArray enumerate_devices () throws GLib.Error;
+               [CCode (cname = "dkp_client_can_hibernate")]
+               public bool get_can_hibernate ();
+               [CCode (cname = "dkp_client_can_suspend")]
+               public bool get_can_suspend ();
+               public unowned string get_daemon_version ();
+               [CCode (cname = "dkp_client_lid_is_closed")]
+               public bool get_lid_is_closed ();
+               [CCode (cname = "dkp_client_on_battery")]
+               public bool get_on_battery ();
+               [CCode (cname = "dkp_client_on_low_battery")]
+               public bool get_on_low_battery ();
+               public bool hibernate () throws GLib.Error;
+               public bool suspend () throws GLib.Error;
+               [NoAccessorMethod]
+               public bool can_hibernate { get; }
+               [NoAccessorMethod]
+               public bool can_suspend { get; }
+               public string daemon_version { get; }
+               [NoAccessorMethod]
+               public bool lid_is_closed { get; }
+               [NoAccessorMethod]
+               public bool lid_is_present { get; }
+               [NoAccessorMethod]
+               public bool on_battery { get; }
+               [NoAccessorMethod]
+               public bool on_low_battery { get; }
+               public virtual signal void changed ();
+               public virtual signal void device_added (void* device);
+               public virtual signal void device_changed (void* device);
+               public virtual signal void device_removed (void* device);
+       }
+       [CCode (cheader_filename = "devkit-power-gobject/devicekit-power.h")]
+       public class Device : GLib.Object {
+               [CCode (has_construct_function = false)]
+               public Device ();
+               public unowned GLib.PtrArray get_history (string type, uint timespec, uint resolution) throws GLib.Error;
+               public unowned string get_object_path ();
+               public unowned GLib.PtrArray get_statistics (string type) throws GLib.Error;
+               public bool print ();
+               public bool refresh () throws GLib.Error;
+               public bool set_object_path (string object_path) throws GLib.Error;
+               public static Dkp.DeviceState state_from_text (string state);
+               public static unowned string state_to_text (Dkp.DeviceState state_enum);
+               public static Dkp.DeviceTechnology technology_from_text (string technology);
+               public static unowned string technology_to_text (Dkp.DeviceTechnology technology_enum);
+               public static Dkp.DeviceType type_from_text (string type);
+               public static unowned string type_to_text (Dkp.DeviceType type_enum);
+               [NoAccessorMethod]
+               public double capacity { get; set; }
+               [NoAccessorMethod]
+               public double energy { get; set; }
+               [NoAccessorMethod]
+               public double energy_empty { get; set; }
+               [NoAccessorMethod]
+               public double energy_full { get; set; }
+               [NoAccessorMethod]
+               public double energy_full_design { get; set; }
+               [NoAccessorMethod]
+               public double energy_rate { get; set; }
+               [NoAccessorMethod]
+               public bool has_history { get; set; }
+               [NoAccessorMethod]
+               public bool has_statistics { get; set; }
+               [NoAccessorMethod]
+               public bool is_present { get; set; }
+               [NoAccessorMethod]
+               public bool is_rechargeable { get; set; }
+               [NoAccessorMethod]
+               public string model { owned get; set; }
+               [NoAccessorMethod]
+               public string native_path { owned get; set; }
+               [NoAccessorMethod]
+               public bool online { get; set; }
+               [NoAccessorMethod]
+               public double percentage { get; set; }
+               [NoAccessorMethod]
+               public bool power_supply { get; set; }
+               [NoAccessorMethod]
+               public bool recall_notice { get; set; }
+               [NoAccessorMethod]
+               public string recall_url { owned get; set; }
+               [NoAccessorMethod]
+               public string recall_vendor { owned get; set; }
+               [NoAccessorMethod]
+               public string serial { owned get; set; }
+               [NoAccessorMethod]
+               public uint state { get; set; }
+               [NoAccessorMethod]
+               public uint technology { get; set; }
+               [NoAccessorMethod]
+               public int64 time_to_empty { get; set; }
+               [NoAccessorMethod]
+               public int64 time_to_full { get; set; }
+               [NoAccessorMethod]
+               public uint type { get; set; }
+               [NoAccessorMethod]
+               public uint64 update_time { get; set; }
+               [NoAccessorMethod]
+               public string vendor { owned get; set; }
+               [NoAccessorMethod]
+               public double voltage { get; set; }
+               public virtual signal void changed (void* obj);
+       }
+       [Compact]
+       [CCode (copy_function = "dkp_history_obj_copy", cheader_filename = "devkit-power-gobject/devicekit-power.h")]
+       public class HistoryObj {
+               public Dkp.DeviceState state;
+               public uint time;
+               public double value;
+               [CCode (has_construct_function = false)]
+               public HistoryObj ();
+               public bool clear ();
+               public unowned Dkp.HistoryObj copy ();
+               public static unowned Dkp.HistoryObj create (double value, Dkp.DeviceState state);
+               public bool equal (Dkp.HistoryObj obj2);
+               public static unowned Dkp.HistoryObj from_string (string text);
+               public bool print ();
+               public unowned string to_string ();
+       }
+       [Compact]
+       [CCode (copy_function = "dkp_qos_obj_copy", cheader_filename = "devkit-power-gobject/devicekit-power.h")]
+       public class QosObj {
+               public weak string cmdline;
+               public uint cookie;
+               public bool persistent;
+               public uint pid;
+               public weak string sender;
+               public uint64 timespec;
+               public Dkp.QosType type;
+               public uint uid;
+               public int value;
+               [CCode (has_construct_function = false)]
+               public QosObj ();
+               public unowned Dkp.QosObj copy ();
+               public bool equal (Dkp.QosObj obj2);
+               public bool print ();
+       }
+       [Compact]
+       [CCode (copy_function = "dkp_stats_obj_copy", cheader_filename = "devkit-power-gobject/devicekit-power.h")]
+       public class StatsObj {
+               public double accuracy;
+               public double value;
+               [CCode (has_construct_function = false)]
+               public StatsObj ();
+               public unowned Dkp.StatsObj copy ();
+               public static unowned Dkp.StatsObj create (double value, double accuracy);
+               public static unowned Dkp.StatsObj from_string (string text);
+               public unowned string to_string ();
+       }
+       [CCode (cheader_filename = "devkit-power-gobject/devicekit-power.h")]
+       public class Wakeups : GLib.Object {
+               [CCode (has_construct_function = false)]
+               public Wakeups ();
+               public unowned GLib.PtrArray get_data () throws GLib.Error;
+               public uint get_total () throws GLib.Error;
+               public bool has_capability ();
+               public virtual signal void data_changed ();
+               public virtual signal void total_changed (uint value);
+       }
+       [Compact]
+       [CCode (copy_function = "dkp_wakeups_obj_copy", cheader_filename = "devkit-power-gobject/devicekit-power.h")]
+       public class WakeupsObj {
+               public weak string cmdline;
+               public weak string details;
+               public uint id;
+               public bool is_userspace;
+               public uint old;
+               public float value;
+               [CCode (has_construct_function = false)]
+               public WakeupsObj ();
+               public unowned Dkp.WakeupsObj copy ();
+               public bool equal (Dkp.WakeupsObj obj2);
+               public bool print ();
+       }
+       [CCode (cprefix = "DKP_DEVICE_STATE_", has_type_id = "0", cheader_filename = "devkit-power-gobject/devicekit-power.h")]
+       public enum DeviceState {
+               UNKNOWN,
+               CHARGING,
+               DISCHARGING,
+               EMPTY,
+               FULLY_CHARGED,
+               PENDING_CHARGE,
+               PENDING_DISCHARGE,
+               LAST
+       }
+       [CCode (cprefix = "DKP_DEVICE_TECHNOLOGY_", has_type_id = "0", cheader_filename = "devkit-power-gobject/devicekit-power.h")]
+       public enum DeviceTechnology {
+               UNKNOWN,
+               LITHIUM_ION,
+               LITHIUM_POLYMER,
+               LITHIUM_IRON_PHOSPHATE,
+               LEAD_ACID,
+               NICKEL_CADMIUM,
+               NICKEL_METAL_HYDRIDE,
+               LAST
+       }
+       [CCode (cprefix = "DKP_DEVICE_TYPE_", has_type_id = "0", cheader_filename = "devkit-power-gobject/devicekit-power.h")]
+       public enum DeviceType {
+               UNKNOWN,
+               LINE_POWER,
+               BATTERY,
+               UPS,
+               MONITOR,
+               MOUSE,
+               KEYBOARD,
+               PDA,
+               PHONE,
+               LAST
+       }
+       [CCode (cprefix = "DKP_QOS_TYPE_", has_type_id = "0", cheader_filename = "devkit-power-gobject/devicekit-power.h")]
+       public enum QosType {
+               UNKNOWN,
+               NETWORK,
+               CPU_DMA,
+               LAST
+       }
+       [CCode (cheader_filename = "devkit-power-gobject/devicekit-power.h")]
+       public const int COMPILE_VERSION;
+       [CCode (cheader_filename = "devkit-power-gobject/devicekit-power.h")]
+       public static Dkp.QosType qos_type_from_text (string type);
+       [CCode (cheader_filename = "devkit-power-gobject/devicekit-power.h")]
+       public static unowned string qos_type_to_text (Dkp.QosType type);
+}
diff --git a/src/gps.vala b/src/gps.vala
new file mode 100644 (file)
index 0000000..950d76b
--- /dev/null
@@ -0,0 +1,247 @@
+/*
+ * gps - gps resource for zavai
+ *
+ * Copyright (C) 2009--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 gps {
+
+// For a list of dbus services, look in /etc/dbus-1/system.d/
+public class GPS: zavai.ScriptService
+{
+    protected libgps.data_t data;
+    protected IOChannel gpsfd = null;
+    protected uint gpsfd_watch = 0;
+
+    protected int old_fix_status = libgps.STATUS_NO_FIX;
+    protected uint old_time = 0;
+    protected double old_lat = 1000;
+    protected double old_lon = 1000;
+
+    public signal void fix_status_changed(int status);
+    public signal void time_changed(uint time);
+    public signal void pos_changed();
+
+    public GPS()
+    {
+        Object(name: "gps");
+        data = libgps.data_t();
+        started = script_status();
+    }
+
+    public int fix_status() { return old_fix_status; }
+    public double time() { return old_time; }
+    public weak libgps.data_t info() { return data; }
+
+    protected bool on_input_data(IOChannel source, IOCondition condition)
+    {
+        while (libgps.waiting(ref data))
+        {
+            int res = libgps.poll(ref data);
+            if (res != 0)
+                zavai.log.error(libgps.errstr(res));
+
+            if (data.status != old_fix_status)
+            {
+                fix_status_changed(data.status);
+                old_fix_status = data.status;
+            }
+
+            uint cur_time = (uint)data.fix.time;
+            if (data.status != libgps.STATUS_NO_FIX && old_time != cur_time)
+            {
+                time_changed(cur_time);
+                old_time = cur_time;
+            }
+
+            double lat = (data.status == libgps.STATUS_NO_FIX ? 1000 : data.fix.latitude);
+            double lon = (data.status == libgps.STATUS_NO_FIX ? 1000 : data.fix.longitude);
+            if (lat != old_lat || lon != old_lon)
+                pos_changed();
+
+            /*
+            stderr.printf("GPSMSG %d %d\n", (int)data.set, data.status);
+            stderr.printf("SATUSED %d\n", data.satellites_used);
+            stderr.printf("SWT %f\n", data.skyview_time);
+            stderr.printf("SATVIS %d\n", data.satellites_visible);
+            for (int i = 0; i < data.satellites_visible; ++i)
+            {
+                stderr.printf("PRN %d ELE %d AZI %d SS %f\n",
+                    data.PRN[i], data.elevation[i], data.azimuth[i], data.ss[i]);
+            }
+            */
+        }
+        return true;
+    }
+
+    /// Request GPS resource
+    public override void start()
+    {
+        if (started) return;
+
+        if (!script_start()) return;
+
+        zavai.log.info("Connecting to gpsd at " + config.gpsd_host + ":" + config.gpsd_port);
+        int res = libgps.open_r(config.gpsd_host, config.gpsd_port, ref data);
+        if (res != 0)
+        {
+            zavai.log.error(libgps.errstr(res));
+            return;
+        }
+
+        res = libgps.stream(ref data, libgps.WATCH_ENABLE, null);
+        if (res != 0)
+        {
+            zavai.log.error(libgps.errstr(res));
+            return;
+        }
+
+        //res = libgps.send(ref data, "?SKY;");
+        //res = libgps.send(ref data, "?WATCH;");
+        //if (res != 0) zavai.log.error(libgps.errstr(res));
+
+        gpsfd = new IOChannel.unix_new(data.gps_fd);
+        try {
+            gpsfd.set_encoding(null);
+        } catch (Error e) {
+            zavai.log.error("Setting encoding to null on gpsd io channel: " + e.message);
+        }
+        //gpsfd.set_buffered(false);
+        gpsfd_watch = gpsfd.add_watch(IOCondition.IN, on_input_data);
+
+        zavai.log.info("GPS turned on");
+        base.start();
+    }
+
+    // Release usage of GPS
+    public override void stop()
+    {
+        if (!started) return;
+
+        Source.remove(gpsfd_watch);
+
+        int res = libgps.close(ref data);
+        if (res != 0)
+            zavai.log.error(libgps.errstr(res));
+
+        script_stop();
+
+        if (old_fix_status != libgps.STATUS_NO_FIX)
+        {
+            old_fix_status = libgps.STATUS_NO_FIX;
+            fix_status_changed(old_fix_status);
+        }
+
+        if (old_time != 0)
+        {
+            old_time = 0;
+            time_changed(old_time);
+        }
+
+        base.stop();
+    }
+}
+
+// #    def start_recording(self):
+// #        if self.gps_monitor:
+// #            self.gps_monitor.stop()
+// #            self.gps_monitor = None
+// #
+// #        if not self.audio:
+// #            return
+// #
+// #        # Sync system time
+// #        gpstime = self.gps.gps_time.GetTime()
+// #        subprocess.call(["date", "-s", "@%d" % gpstime])
+// #        subprocess.call(["hwclock", "--systohc"])
+// #
+// #        # Compute basename for output files
+// #        self.basename = time.strftime("%Y-%m-%d-%H-%M-%S", time.localtime(gpstime))
+// #        self.basename = os.path.join(AUDIODIR, self.basename)
+// #
+// #        # Start recording the GPX track
+// #        self.gpx = GPX(self.basename)
+// #        self.gps.track_position(self.on_position_changed)
+// #
+// #        # Start recording in background forking arecord
+// #        self.audio.set_basename(self.basename)
+// #        self.audio.start_recording()
+// #
+
+// Write GPX track and waypoint files
+public class GPX : Service
+{
+    protected uint wpt_seq = 0;
+    protected uint log_id = 0;
+
+    public GPX()
+    {
+        Object(name: "gps.gpx");
+    }
+
+    public override void start()
+    {
+        if (!started)
+        {
+            log_id = log.log.start("track", "GPS track");
+            base.start();
+        }
+    }
+
+    public override void stop()
+    {
+        if (started)
+        {
+            log.log.end(log_id);
+            log_id = 0;
+            base.stop();
+        }
+    }
+
+    // Mark a waypoint
+    public void waypoint(string? name = null)
+    {
+        if (log_id == 0) return;
+
+        string wptname;
+        if (name == null)
+        {
+            wptname = "wpt_%u".printf(wpt_seq);
+            wpt_seq += 1;
+        } else {
+            wptname = name;
+        }
+
+        log.log.add(log_id, wptname);
+    }
+}
+
+public zavai.gps.GPS gps = null;
+public zavai.gps.GPX gpx = null;
+
+public void init()
+{
+    gps = new GPS();
+    gpx = new GPX();
+
+}
+
+}
+}
diff --git a/src/gsm.vala b/src/gsm.vala
new file mode 100644 (file)
index 0000000..19a854d
--- /dev/null
@@ -0,0 +1,449 @@
+/*
+ * gsm - gsm resource for zavai
+ *
+ * Copyright (C) 2009--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 gsm {
+
+[DBus (name = "org.freesmartphone.GSM.Device")]
+public interface FSO_GSM_Device : Object {
+    public abstract async int test_int (int i, out int j) throws DBus.Error;
+    public abstract async string test_string (string s, out string t) throws DBus.Error;
+    public abstract async void set_sim_buffers_sms(bool sim_buffers_sms) throws DBus.Error;
+    public abstract async void set_r_t_c() throws DBus.Error;
+    public abstract async void cancel_command() throws DBus.Error;
+    public abstract async void set_antenna_power(bool power) throws DBus.Error;
+    public abstract async GLib.HashTable<string, GLib.Value?> get_info() throws DBus.Error;
+    public abstract async void set_microphone_muted(bool muted) throws DBus.Error;
+    public signal void keypad_event(string name, bool pressed);
+    public abstract async int get_speaker_volume() throws DBus.Error;
+    public abstract async int get_r_t_c() throws DBus.Error;
+    public abstract async void set_speaker_volume(int modem_volume) throws DBus.Error;
+    public abstract async GLib.HashTable<string, GLib.Value?> get_features() throws DBus.Error;
+    public abstract async bool get_microphone_muted() throws DBus.Error;
+    public abstract async bool get_antenna_power() throws DBus.Error;
+    public abstract async void get_power_status(out string param0, out int param1) throws DBus.Error;
+    public abstract async bool get_sim_buffers_sms() throws DBus.Error;
+}
+
+[DBus (name = "org.freesmartphone.GSM.SIM")]
+public interface FSO_GSM_SIM : GLib.Object {
+    //public abstract async SIMParam0Struct[] retrieve_phonebook(string category) throws DBus.Error;
+    public abstract async void send_auth_code(string code) throws DBus.Error;
+    public abstract async string get_issuer() throws DBus.Error;
+    public abstract async void change_auth_code(string old_pin, string new_pin) throws DBus.Error;
+    public signal void auth_status(string status);
+    public abstract async string send_generic_sim_command(string command) throws DBus.Error;
+    public abstract async string[] list_phonebooks() throws DBus.Error;
+    public abstract async void set_service_center_number(string number) throws DBus.Error;
+    public abstract async GLib.HashTable<string, string> get_provider_list() throws DBus.Error;
+    //public abstract async SIMParam0Struct2[] get_home_zones() throws DBus.Error;
+    public signal void ready_status(bool status);
+    public abstract async void retrieve_entry(string category, int index, out string param0, out string param1) throws DBus.Error;
+    public abstract async void delete_message(int index) throws DBus.Error;
+    public abstract async void send_restricted_sim_command(int command, int fileid, int p1, int p2, int p3, string data, out int param0, out int param1, out string param2) throws DBus.Error;
+    public abstract async GLib.HashTable<string, GLib.Value?> get_messagebook_info() throws DBus.Error;
+    public abstract async bool get_sim_ready() throws DBus.Error;
+    public abstract async GLib.HashTable<string, GLib.Value?> get_phonebook_info(string category) throws DBus.Error;
+    public signal void memory_full();
+    public abstract async GLib.HashTable<string, GLib.Value?> get_sim_info() throws DBus.Error;
+    public abstract async void set_auth_code_required(bool required, string pin) throws DBus.Error;
+    public abstract async string get_auth_status() throws DBus.Error;
+    public abstract async void send_stored_message(int index, out int param0, out string param1) throws DBus.Error;
+    public abstract async int store_message(string number, string contents, GLib.HashTable<string, GLib.Value?> properties) throws DBus.Error;
+    public abstract async bool get_auth_code_required() throws DBus.Error;
+    public signal void incoming_stored_message(int index);
+    public abstract async void retrieve_message(int index, out string param0, out string param1, out string param2, out GLib.HashTable<string, GLib.Value?> param3) throws DBus.Error;
+    public abstract async void store_entry(string category, int index, string name, string number) throws DBus.Error;
+    public abstract async void unlock(string puk, string new_pin) throws DBus.Error;
+    public abstract async string get_service_center_number() throws DBus.Error;
+    //public abstract async SIMParam0Struct23[] retrieve_messagebook(string category) throws DBus.Error;
+    public abstract async void delete_entry(string category, int index) throws DBus.Error;
+}
+
+[DBus (name = "org.freesmartphone.GSM.Network")]
+public interface FSO_GSM_Network : GLib.Object {
+    public signal void status(GLib.HashTable<string, GLib.Value?> status);
+    public signal void signal_strength(int strength);
+    //public abstract async NetworkParam0Struct[] list_providers() throws DBus.Error;
+    public abstract async GLib.HashTable<string, GLib.Value?> get_call_forwarding(string reason) throws DBus.Error;
+    public signal void time_zone_report(int timezone);
+    public abstract async void unregister() throws DBus.Error;
+    public abstract async void set_calling_identification(string status) throws DBus.Error;
+    public abstract async void register_() throws DBus.Error;
+    public abstract async void send_ussd_request(string request) throws DBus.Error;
+    public abstract async void disable_call_forwarding(string reason, string class_) throws DBus.Error;
+    public signal void incoming_ussd(string mode, string message_);
+    public abstract async int get_signal_strength() throws DBus.Error;
+    public abstract async void enable_call_forwarding(string reason, string class_, string number, int timeout) throws DBus.Error;
+    public abstract async string get_calling_identification() throws DBus.Error;
+    public abstract async void register_with_provider(string operator_code) throws DBus.Error;
+    public signal void cipher_status(string gsm, string gprs);
+    public abstract async GLib.HashTable<string, GLib.Value?> get_status() throws DBus.Error;
+    public abstract async void get_country_code(out string param0, out string param1) throws DBus.Error;
+}
+
+[DBus (name = "org.freesmartphone.GSM.Call")]
+public interface FSO_GSM_Call : GLib.Object {
+    public abstract async void activate(int index) throws DBus.Error;
+    public abstract async void emergency(string number) throws DBus.Error;
+    public abstract async void hold_active() throws DBus.Error;
+    public abstract async void release_held() throws DBus.Error;
+    public abstract async void send_dtmf(string tones) throws DBus.Error;
+    public abstract async void release_all() throws DBus.Error;
+    public abstract async int initiate(string number, string type_) throws DBus.Error;
+    // public abstract async CallParam0Struct[] list_calls() throws DBus.Error;
+    public abstract async void transfer(string number) throws DBus.Error;
+    public abstract async void release(int index) throws DBus.Error;
+    public signal void call_status(int index, string status, GLib.HashTable<string, GLib.Value?> properties);
+    public abstract async void activate_conference(int index) throws DBus.Error;
+}
+
+public class GSM: zavai.ScriptMonitorService
+{
+    protected dynamic DBus.Object dbus;
+    public FSO_GSM_Device device;
+    public FSO_GSM_Network network;
+    public FSO_GSM_SIM sim;
+    public FSO_GSM_Call call;
+
+    protected class CallInfo
+    {
+        public int gsm_id;
+        public uint log_id;
+    }
+    protected List<CallInfo> calls;
+
+    public string info_provider;
+    public int info_signal_strength;
+
+    public signal void status_changed(string message);
+    public signal void info_changed();
+
+    protected void dump_table(HashTable<string, Value?> vals)
+    {
+        vals.for_each((pk, pv) => {
+            string k = (string)pk;
+            Value? v = (Value?)pv;
+            stderr.printf("K: %s V: %s\n", k, v == null ? "(null)" : v.strdup_contents());
+        });
+    }
+
+    protected void acquire_new_status(HashTable<string, Value?> status)
+    {
+        // NETWORK STATUS
+        // K: provider V: "vodafone UK"
+        // K: mode V: "automatic"
+        // K: registration V: "roaming"
+        // K: cid V: "157F"
+        // K: lac V: "0031"
+        // K: act V: "GSM"
+        // K: code V: "23415"
+        bool changed = false;
+
+        var vprovider = status.lookup("provider");
+        if (vprovider != null)
+        {
+            if (info_provider != vprovider.get_string())
+            {
+                info_provider = vprovider.get_string();
+stderr.printf("ACQUIRE PROV %s\n", info_provider);
+                changed = true;
+            }
+        }
+
+        if (changed)
+        {
+stderr.printf("NOTIFY CHANGED\n");
+            info_changed();
+        }
+    }
+
+    protected void acquire_new_signal_strength(int strength)
+    {
+        if (info_signal_strength != strength)
+        {
+            info_signal_strength = strength;
+stderr.printf("ACQUIRE SIG %d\n", info_signal_strength);
+            info_changed();
+        }
+    }
+
+    public GSM()
+    {
+        Object(name: "gsm");
+
+        calls = new List<CallInfo>();
+
+        device = (FSO_GSM_Device)zavai.registry.sbus.get_object(
+                "org.freesmartphone.ogsmd", 
+                "/org/freesmartphone/GSM/Device",
+                "org.freesmartphone.GSM.Device");
+        network = (FSO_GSM_Network)zavai.registry.sbus.get_object(
+            "org.freesmartphone.ogsmd", 
+            "/org/freesmartphone/GSM/Device",
+            "org.freesmartphone.GSM.Network");
+        sim = (FSO_GSM_SIM)zavai.registry.sbus.get_object(
+                "org.freesmartphone.ogsmd", 
+                "/org/freesmartphone/GSM/Device",
+                "org.freesmartphone.GSM.SIM");
+        call = (FSO_GSM_Call)zavai.registry.sbus.get_object(
+            "org.freesmartphone.ogsmd", 
+            "/org/freesmartphone/GSM/Device",
+            "org.freesmartphone.GSM.Call");
+        dbus = zavai.registry.sbus.get_object(
+                "org.freedesktop.DBus",
+                "/org/freedesktop/DBus",
+                "org.freedesktop.DBus");
+        dbus.NameOwnerChanged += on_name_owner_changed;
+
+        info_provider = "(unknown)";
+        info_signal_strength = -1;
+
+        network.status += (status) => {
+            stderr.printf("NETWORK STATUS\n");
+            dump_table(status);
+            acquire_new_status(status);
+        };
+
+        network.signal_strength += (strength) => {
+            stderr.printf("SIGNAL STRENGTH %d\n", strength);
+            acquire_new_signal_strength(strength);
+        };
+
+        call.call_status += on_call_status;
+    }
+
+    /// Request GPS resource
+    public override void start()
+    {
+        if (started) return;
+
+        status_changed("Starting");
+
+        script_start();
+
+        base.start();
+    }
+
+    protected void on_name_owner_changed(DBus.Object sender, string name, string oldOwner, string newOwner)
+    {
+        zavai.log.debug("NOC " + name + " from " + oldOwner + " to " + newOwner);
+        if (name == "org.freesmartphone.ogsmd" && newOwner != "")
+        {
+            status_changed("ogpsd came online");
+            start_gsm.begin();
+        }
+    }
+
+    // Release usage of GPS
+    public override void stop()
+    {
+        if (!started) return;
+
+        script_stop();
+
+        status_changed("");
+        info_provider = "";
+        info_signal_strength = -1;
+        info_changed();
+    }
+
+    protected override void cleanup_after_script_stop()
+    {
+        call = null;
+    }
+
+    public async void start_gsm()
+    {
+        status_changed("Turning on antenna");
+        while (true)
+        {
+            try {
+                yield device.set_antenna_power(true);
+                break;
+            } catch (Error e) {
+                zavai.log.warning("SetAntennaPower: " + e.message);
+                if (e.message.str("current status is 'enabling'") != null
+                 || e.message.str("current status is 'unknown'") != null)
+                {
+                    status_changed("Waiting for ogsmd to settle");
+                    zavai.log.info("trying again after 2 seconds");
+                    Timeout.add(2 * 1000, () => {
+                        start_gsm.callback();
+                        return false;
+                    });
+                    yield;
+                } else {
+                    status_changed("Checking if PIN is required");
+                    string status = yield sim.get_auth_status();
+                    zavai.log.info("on_auth_status: " + status);
+                    if (status == "READY")
+                        status_changed("PIN ok");
+                    else if (status == "SIM PIN")
+                    {
+                        status_changed("Sending PIN");
+                        yield sim.send_auth_code(zavai.config.sim_pin);
+                        status_changed("PIN OK");
+                    }
+                    else
+                        zavai.log.debug("Unknown status: " + status);
+                }
+            }
+        }
+        zavai.log.warning("on_antenna_power ok");
+        status_changed("Registering with network");
+        yield network.register_();
+        status_changed("Registered with network");
+
+        acquire_new_status(yield network.get_status());
+        acquire_new_signal_strength(yield network.get_signal_strength());
+    }
+
+    protected CallInfo? lookup_call(int gsm_id)
+    {
+        for (weak List<CallInfo> i = calls; i != null; i = i.next)
+            if (i.data.gsm_id == gsm_id)
+                return i.data;
+        return null;
+    }
+
+    public void on_call_status(int index, string status, HashTable<string, Value?> properties)
+    {
+        stderr.printf("CALL STATUS %d %s\n", index, status);
+        dump_table(properties);
+
+        CallInfo? info = lookup_call(index);
+        if (info == null)
+        {
+            Value? v = properties.lookup("peer");
+            string title;
+            if (v != null)
+                title = "%s call from %s".printf(status, v.get_string());
+            else
+                title = "%s call".printf(status);
+
+            info = new CallInfo();
+            info.gsm_id = index;
+            info.log_id = zavai.log.log.start("call", title);
+            calls.append(info);
+        }
+
+        // Log a summary of all info
+        string call_info = "status: %s\n".printf(status);
+        properties.for_each((pk, pv) => {
+            string k = (string)pk;
+            Value? v = (Value?)pv;
+            call_info = call_info + "%s: %s\n".printf(k, v == null ? "(null)" : v.strdup_contents());
+        });
+        zavai.log.log.add(info.log_id, call_info);
+
+        // Remove entry when it's the last possible status
+        if (status == "release")
+        {
+            zavai.log.log.end(info.log_id);
+            for (weak List<CallInfo> i = calls; i != null; i = i.next)
+                if (i.data.gsm_id == index)
+                {
+                    calls.delete_link(i);
+                    break;
+                }
+        }
+
+        /*
+        dbg("cbCallStatus %d, %s, %s" % (id, status, formatDict(properties)))
+        self.status = status
+        if status == "incoming":
+            if "peer" in properties and properties["peer"] == "+358942832031":
+                self.gsm_call_iface.ReleaseAll()
+                os.system("kapula-debug-call-handler &")
+            else:
+                os.system("alsactl restore -f /etc/alsa-scenarios/stereoout-maxvolume.state")
+                os.system("vibrator-start")
+                os.system("ringtone-start")
+                os.system("ledctrl --on-time 400 --off-time 200 gta02-aux:red");
+        if status == "release":
+            os.system("ringtone-stop")
+            os.system("vibrator-stop")
+            os.system("ledctrl --off gta02-aux:red");
+        */
+    }
+}
+
+public class GPRS: zavai.Service
+{
+    public dynamic DBus.Object device;
+
+    public GPRS()
+    {
+        Object(name: "gsm.gprs");
+
+        device = zavai.registry.sbus.get_object(
+            "org.freesmartphone.ogsmd", 
+            "/org/freesmartphone/GSM/Device",
+            "org.freesmartphone.GSM.PDP");
+    }
+
+    /// Request GPS resource
+    public override void start()
+    {
+        if (started) return;
+        try {
+            //gsm.request(name);
+            device.ActivateContext(
+                zavai.config.gprs_apn,
+                zavai.config.gprs_user,
+                zavai.config.gprs_pass);
+            zavai.log.info("Started GPRS");
+            base.start();
+        } catch (GLib.Error e) {
+            zavai.log.error(e.message);
+        }
+        base.start();
+    }
+
+    // Release usage of GPS
+    public override void stop()
+    {
+        if (!started) return;
+        try {
+            //gsm.release(name);
+            device.DeactivateContext();
+            zavai.log.info("Stopped GPRS");
+            base.stop();
+        } catch (GLib.Error e) {
+            zavai.log.error(e.message);
+        }
+        base.stop();
+    }
+}
+
+public zavai.gsm.GSM gsm = null;
+public zavai.gsm.GPRS gprs = null;
+
+public void init()
+{
+    gsm = new GSM();
+    gprs = new GPRS();
+}
+
+}
+}
diff --git a/src/input.vala b/src/input.vala
new file mode 100644 (file)
index 0000000..ffa0add
--- /dev/null
@@ -0,0 +1,425 @@
+/*
+ * devinput - zavai /dev/input device handling
+ *
+ * Copyright (C) 2009  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
+ */
+
+namespace zavai {
+namespace input {
+
+public class DevInput : zavai.Service
+{
+    public string device { get; construct; }
+
+    public signal bool event(LinuxInput.Event* ev);
+
+    protected IOChannel fd = null;
+    protected uint fd_watch = 0;
+
+    public DevInput(string name, string device)
+    {
+        Object(name: "input.power_button", device: "/dev/input/event0");
+    }
+
+    protected void close_fd()
+    {
+        if (fd != null)
+        {
+            try {
+                fd.shutdown(false);
+            } catch (IOChannelError e) {
+                zavai.log.error("When closing " + device + ": " + e.message);
+            }
+
+            fd = null;
+        }
+    }
+
+    protected bool on_input_data(IOChannel source, IOCondition condition)
+    {
+        if (condition != IOCondition.IN) return true;
+
+        //stderr.printf("GOT INPUT ON %s %d\n", device, source.unix_get_fd());
+        char[] buf = new char[sizeof(LinuxInput.Event)];
+        size_t count_read;
+        try {
+            source.read_chars(buf, out count_read);
+        } catch (Error e) {
+            zavai.log.error("Reading from " + device + ": " + e.message);
+            return true;
+        }
+        //stderr.printf("READ %zu chars\n", count_read);
+
+        LinuxInput.Event* ie = (LinuxInput.Event*)buf;
+        //stderr.printf("INPUT EVENT time %lu.%lu type %hu code %hu val %d\n", (ulong)ie->time.tv_sec, ie->time.tv_usec, ie->type, ie->code, ie->val);
+
+        /*
+        ts1, ts2, type, code, value = struct.unpack("LLHHI", buf)
+        #print ts1, ts2, type, code, value
+        if type == 1 and code == 119:
+            if value:
+                #print "BUTTON RELEASE"
+                pass
+            else:
+                if self.last_button_press + 1 < ts1:
+                    self.last_button_press = ts1
+                    if self.button_press_handler is not None:
+                        self.button_press_handler()
+                    #print "BUTTON PRESS"
+        elif type == 5 and code == 2:
+            if value:
+                info("Headset plugged in")
+                self.mixer_for_headset(self)
+            else:
+                info("Headset plugged out")
+                self.mixer_for_handset(self)
+        */
+        return event(ie);
+    }
+
+    /// Start reading from the device
+    public override void start()
+    {
+        if (started) return;
+
+        if (fd != null)
+            close_fd();
+
+        // Open the device and listed to it using the GObject main loop
+        zavai.log.info("Opening device " + device);
+        fd = new IOChannel.file(device, "r");
+        try {
+            fd.set_encoding(null);
+        } catch (Error e) {
+            zavai.log.error("Setting encoding to null on " + device + ": " + e.message);
+        }
+        fd.set_buffered(false);
+        fd_watch = fd.add_watch(IOCondition.IN, on_input_data);
+
+        base.start();
+    }
+
+    // Stop reading from the device
+    public override void stop()
+    {
+        if (!started) return;
+
+        if (fd != null)
+        {
+            Source.remove(fd_watch);
+            close_fd();
+        }
+
+        base.stop();
+    }
+}
+
+public class HotKeys : zavai.Service
+{
+    protected List<int> grabbed;
+    public signal bool hotkey(uint keycode, ulong time, bool pressed);
+
+    public HotKeys()
+    {
+        Object(name: "input.hotkeys");
+
+        grabbed = new List<int>();
+    }
+
+    // Hotkey handlink takes inspiration from
+    // http://old.nabble.com/-PATCH--Initial-non-working-implementation-of-wxWindow::%28Un%29RegisterHotKey-on-wxGTK-td14557263.html
+    private static Gdk.FilterReturn on_hotkey(Gdk.XEvent* xevent, Gdk.Event? event, void* data)
+    {
+        // Global events don't get their data translated to gdk, as there is no
+        // GdkWindow to work with, therefore we need to use the xevent, because
+        // GdkEvent* is always GDK_NOTHING
+        X.Event* xev = (X.Event*)xevent;
+
+        switch (xev->type)
+        {
+            case X.EventType.KeyPress:
+                return zavai.input.hotkeys.my_on_hotkey(xev, true);
+            case X.EventType.KeyRelease:
+                return zavai.input.hotkeys.my_on_hotkey(xev, false);
+            default:
+                return Gdk.FilterReturn.CONTINUE;
+        }
+    }
+
+    //public Gdk.FilterReturn on_hotkey(Gdk.XEvent xevent, Gdk.Event? event)
+    private Gdk.FilterReturn my_on_hotkey(X.Event* xev, bool pressed)
+    {
+        // From http://tronche.com/gui/x/xlib/input/pointer-grabbing.html:
+        //
+        // A timestamp is a time value, expressed in milliseconds. It typically is the
+        // time since the last server reset. Timestamp values wrap around (after about
+        // 49.7 days). The server, given its current time is represented by timestamp
+        // T, always interprets timestamps from clients by treating half of the
+        // timestamp space as being later in time than T. One timestamp value, named
+        // CurrentTime, is never generated by the server. This value is reserved for
+        // use in requests to represent the current server time. 
+
+        if (grabbed.index((int)xev->xkey.keycode) == -1)
+            return Gdk.FilterReturn.CONTINUE;
+
+        if (hotkey(xev->xkey.keycode, xev->xkey.time, pressed))
+            return Gdk.FilterReturn.REMOVE;
+        return Gdk.FilterReturn.CONTINUE;
+    }
+
+    public void grab(int keycode, int modifiers, bool owner_events)
+    {
+        // We need to grab the keys we want to listen to
+        int res = Gdk.x11_get_default_xdisplay().grab_key(keycode, modifiers, Gdk.x11_get_default_root_xwindow(), owner_events, X.GrabMode.Async, X.GrabMode.Async);
+        if (res != 0)
+            stderr.printf("Grab result: %d\n", res); // We get BadRequest and don't know why
+        grabbed.append(keycode);
+    }
+
+    /// Start reading from the device
+    public override void start()
+    {
+        if (started) return;
+
+        //gdk_window_add_filter (NULL, _wxgtk_global_hotkey_callback, this);
+        ((Gdk.Window*)null)->add_filter((Gdk.FilterFunc)on_hotkey);
+
+        grab(160, 0, false);
+
+        base.start();
+    }
+
+    // Stop reading from the device
+    public override void stop()
+    {
+        if (!started) return;
+
+        //gdk_window_remove_filter(NULL, _wxgtk_global_hotkey_callback, this); 
+        ((Gdk.Window*)null)->remove_filter((Gdk.FilterFunc)on_hotkey);
+
+        base.stop();
+    }
+}
+
+public class PowerButton : zavai.Service
+{
+    protected DevInput devinput;
+
+    public signal void power_button(Posix.timeval* time, bool pressed);
+
+    public PowerButton()
+    {
+        // FIXME: change to event0 for the power button
+        // FIXME: change to event4 for the aux button and headset button
+        string inputdev = "/dev/input/event0";
+        if (Posix.access(inputdev, Posix.R_OK) == 0)
+        {
+            zavai.log.info("Handle power button via " + inputdev);
+            // Listen via input device
+            devinput = new DevInput("input.power_button", "/dev/input/event0");
+            devinput.event += on_event;
+            devinput.request("powerbutton");
+        } else {
+            zavai.log.info("Handle power button via XGrabKey on keycode " + zavai.config.power_button_keycode.to_string());
+            // Listen via X
+            hotkeys.hotkey += on_hotkey;
+            hotkeys.grab(zavai.config.power_button_keycode, 0, false);
+            hotkeys.request("powerbutton");
+        }
+    }
+
+    protected bool on_event(LinuxInput.Event* ev)
+    {
+        if (ev->type == LinuxInput.Type.KEY && 
+            ev->code == LinuxInput.Key.POWER)
+        {
+            power_button(&(ev->time), ev->val == 0 ? false : true);
+        }
+        return true;
+    }
+
+    protected bool on_hotkey(uint keycode, ulong time, bool pressed)
+    {
+        if (keycode == zavai.config.power_button_keycode)
+        {
+            // Convert X time to a fake timeval
+            // TODO: handle wraparound
+            Posix.timeval tv = {
+                (time_t)(time / 1000),
+                (long)((time % 1000) * 1000)
+            };
+            power_button(&tv, pressed);
+            return true;
+        }
+        return false;
+    }
+}
+
+
+/*
+# TODO:
+#  - hook into the headset plugged/unplugged event
+#  - if unplugged, turn on handset microphone
+#  - if plugged, redo headest mixer settings
+class Audio:
+    "Handle mixer settings, audio recording and headset button presses"
+    def __init__(self, button_press_handler = None):
+        self.saved_scenario = os.path.expanduser("~/.audiomap.state")
+
+        # Setup the mixer
+        # Set mixer to record from headset and handle headset button
+        self.save_scenario(self.saved_scenario)
+        self.load_scenario("/usr/share/openmoko/scenarios/voip-handset.state")
+
+        # This is a work-around because I have not found a way to query for the
+        # current headset state, I can only know when it changes. So in my
+        # system I configured oeventsd with a rule to touch this file when the
+        # headset is plugged in, and remove the file when it's plugged out.
+        if os.path.exists("/tmp/has_headset"):
+            self.mixer_for_headset(True)
+        else:
+            self.mixer_for_handset(True)
+
+        #self.mixer_set("DAPM Handset Mic", "mute")
+        #self.mixer_set("DAPM Headset Mic", "unmute")
+        #self.mixer_set("Left Mixer Sidetone Playback Sw", "unmute")
+        #self.mixer_set("ALC Mixer Mic1", "cap")
+        #self.mixer_set("Amp Spk", "mute") # We don't need the phone playing what we say
+
+        # Watch the headset button
+        self.button_press_handler = button_press_handler
+        self.input_fd = open("/dev/input/event4", "rb")
+        self.input_watch = gobject.io_add_watch(self.input_fd.fileno(), gobject.IO_IN, self.on_input_data)
+
+        self.last_button_press = 0
+        self.recorder = None
+        self.basename = None
+
+    def mixer_for_headset(self, force=False):
+        if not force and self.has_headset: return
+        info("Setting mixer for headset")
+        # TODO: find out how to disable the handset microphone: this does not
+        # seem to be sufficient
+        self.mixer_set_many(
+                ("DAPM Handset Mic", "mute"),
+                ("DAPM Headset Mic", "unmute"),
+                ("Left Mixer Sidetone Playback Sw", "unmute"),
+                ("ALC Mixer Mic1", "cap"),
+                ("Amp Spk", "mute") # We don't need the phone playing what we say
+        )
+        self.has_headset = True
+
+    def mixer_for_handset(self, force=False):
+        if not force and not self.has_headset: return
+        info("Setting mixer for handset")
+        self.mixer_set_many(
+                ("DAPM Handset Mic", "unmute"),
+                ("DAPM Headset Mic", "mute"),
+                ("Left Mixer Sidetone Playback Sw", "mute"),
+                ("ALC Mixer Mic1", "cap"),
+                ("Amp Spk", "mute") # We don't need the phone playing what we say
+        )
+        self.has_headset = False
+
+    def set_basename(self, basename):
+        self.basename = basename
+
+    def start_recording(self):
+        if self.basename is None:
+            raise RuntimeError("Recording requested but basename not set")
+        self.recorder = subprocess.Popen(
+            ["arecord", "-D", "hw", "-f", "cd", "-r", "8000", "-t", "wav", self.basename + ".wav"])
+
+    def start_levels(self):
+        self.recorder = subprocess.Popen(
+            ["arecord", "-D", "hw", "-f", "cd", "-r", "8000", "-t", "wav", "-V", "stereo", "/dev/null"])
+
+    def close(self):
+        if self.recorder is not None:
+            os.kill(self.recorder.pid, signal.SIGINT)
+            self.recorder.wait()
+
+        # Restore mixer settings
+        self.load_scenario(self.saved_scenario)
+
+        gobject.source_remove(self.input_watch)
+        self.input_fd.close()
+
+    def on_input_data(self, source, condition):
+        buf = self.input_fd.read(16)
+        ts1, ts2, type, code, value = struct.unpack("LLHHI", buf)
+        #print ts1, ts2, type, code, value
+        if type == 1 and code == 119:
+            if value:
+                #print "BUTTON RELEASE"
+                pass
+            else:
+                if self.last_button_press + 1 < ts1:
+                    self.last_button_press = ts1
+                    if self.button_press_handler is not None:
+                        self.button_press_handler()
+                    #print "BUTTON PRESS"
+        elif type == 5 and code == 2:
+            if value:
+                info("Headset plugged in")
+                self.mixer_for_headset(self)
+            else:
+                info("Headset plugged out")
+                self.mixer_for_handset(self)
+        return True
+
+    def save_scenario(self, name):
+        res = subprocess.call(["alsactl", "store", "-f", name])
+        if res != 0:
+            raise RuntimeError("Saving audio scenario to '%s' failed" % name)
+
+    def load_scenario(self, name):
+        res = subprocess.call(["alsactl", "restore", "-f", name])
+        if res != 0:
+            raise RuntimeError("Loading audio scenario '%s' failed" % name)
+
+    def mixer_set(self, name, *args):
+        args = map(str, args)
+        res = subprocess.call(["amixer", "-q", "set", name] + args)
+        if res != 0:
+            raise RuntimeError("Setting mixer '%s' to %s failed" % (name, " ".join(args)))
+
+    # Will do this when we find out the syntax for giving amixer commands on stdin
+    def mixer_set_many(self, *args):
+        """Perform many mixer set operations via amixer --stdin"""
+        proc = subprocess.Popen(["amixer", "-q", "--stdin"], stdin=subprocess.PIPE)
+        cmd_input = []
+        for k, v in args:
+            cmd_input.append("sset " + repr(k) + " " + repr(v))
+        (out, err) = proc.communicate(input="\n".join(cmd_input))
+        res = proc.wait()
+        if res != 0:
+            raise RuntimeError("Setting mixer failed")
+*/
+
+
+public HotKeys hotkeys = null;
+public PowerButton power_button = null;
+
+public void init()
+{
+    hotkeys = new HotKeys();
+    power_button = new PowerButton();
+}
+
+}
+}
diff --git a/src/libgps.vapi b/src/libgps.vapi
new file mode 100644 (file)
index 0000000..da29fcd
--- /dev/null
@@ -0,0 +1,238 @@
+[CCode (lower_case_cprefix="", cprefix="", cheader_filename="gps.h")]
+namespace libgps
+{
+    public const int MAXCHANNELS;
+
+    [SimpleType]
+    [IntegerType (rank = 9)]
+    public struct mask_t {}
+
+    [CCode (cname = "struct gps_fix_t")]
+    public struct fix_t
+    {
+        double time;   /* Time of update, seconds since Unix epoch */
+        int    mode;   /* Mode of fix */
+        double ept;            /* Expected time uncertainty */
+        double latitude;       /* Latitude in degrees (valid if mode >= 2) */
+        double epy;    /* Latitude position uncertainty, meters */
+        double longitude;      /* Longitude in degrees (valid if mode >= 2) */
+        double epx;    /* Longitude position uncertainty, meters */
+        double altitude;       /* Altitude in meters (valid if mode == 3) */
+        double epv;    /* Vertical position uncertainty, meters */
+        double track;  /* Course made good (relative to true north) */
+        double epd;            /* Track uncertainty, degrees */
+        double speed;  /* Speed over ground, meters/sec */
+        double eps;            /* Speed uncertainty, meters/sec */
+        double climb;   /* Vertical speed, meters/sec */
+        double epc;            /* Vertical speed uncertainty */
+    }
+    public const int MODE_NOT_SEEN; /* mode update not seen yet */
+    public const int MODE_NO_FIX;   /* none */
+    public const int MODE_2D;       /* good for latitude/longitude */
+    public const int MODE_3D;       /* good for altitude/climb too */
+
+    [CCode (cname = "struct dop_t")]
+    public struct dop_t
+    {
+        /* Dilution of precision factors */
+        double xdop;
+        double ydop;
+        double pdop;
+        double hdop;
+        double vdop;
+        double tdop;
+        double gdop;
+    }
+
+    [CCode (cname = "struct gps_data_t", destroy_function = "")]
+    public struct data_t
+    {
+        mask_t set;
+        double online;
+        int gps_fd;
+        fix_t fix;
+        double separation;
+        int status;
+        int satellites_used;        /* Number of satellites used in solution */
+        int[] used;      /* PRNs of satellites used in solution */
+        dop_t dop;
+        /* redundant with the estimate elements in the fix structure */
+        double epe;  /* spherical position error, 95% confidence (meters)  */
+
+        /* satellite status -- valid when satellites_visible > 0 */
+        double skyview_time;        /* skyview timestamp */
+        int satellites_visible;     /* # of satellites in view */
+        int[] PRN;       /* PRNs of satellite */
+        int[] elevation; /* elevation of satellite */
+        int[] azimuth;   /* azimuth */
+        double[] ss;     /* signal-to-noise ratio (dB) */
+
+        //struct devconfig_t dev;     /* device that shipped last update */
+
+        //struct policy_t policy;     /* our listening policy */
+
+        //char tag[MAXTAGLEN+1];      /* tag of last sentence processed */
+    }
+    public const int ONLINE_SET;
+    public const int TIME_SET;
+    public const int TIMERR_SET;
+    public const int LATLON_SET;
+    public const int ALTITUDE_SET;
+    public const int SPEED_SET;
+    public const int TRACK_SET;
+    public const int CLIMB_SET;
+    public const int STATUS_SET;
+    public const int MODE_SET;
+    public const int DOP_SET;
+    public const int VERSION_SET; /* only used in client library */
+    public const int HERR_SET;
+    public const int VERR_SET;
+    public const int PERR_SET;
+    public const int POLICY_SET; /* only used in client library */
+    public const int ERR_SET;
+    public const int SATELLITE_SET;
+    public const int RAW_SET;
+    public const int USED_SET;
+    public const int SPEEDERR_SET;
+    public const int TRACKERR_SET;
+    public const int CLIMBERR_SET;
+    public const int DEVICE_SET;
+    public const int DEVICELIST_SET;
+    public const int DEVICEID_SET;
+    public const int ERROR_SET;
+    public const int RTCM2_SET;
+    public const int RTCM3_SET;
+    public const int AIS_SET;
+    public const int PACKET_SET;
+    public const int CLEAR_SET; /* sentence starts a reporting cycle */
+    public const int REPORT_SET; /* sentence ends a reporting cycle */
+    public const int DATA_SET;
+
+    public const int STATUS_NO_FIX;   /* no */
+    public const int STATUS_FIX;      /* yes, without DGPS */
+    public const int STATUS_DGPS_FIX; /* yes, with DGPS */
+
+    [CCode (cname = "gps_open_r")]
+    public int open_r(string server, string port, ref data_t gpsdata);
+
+    [CCode (cname = "gps_close")]
+    public int close(ref data_t gpsdata);
+
+    [CCode (cname = "gps_errstr")]
+    public weak string errstr(int err);
+
+    [CCode (cname = "gps_poll")]
+    public int poll(ref data_t gpsdata);
+
+    [CCode (cname = "gps_waiting")]
+    public bool waiting(ref data_t gpsdata);
+
+    [CCode (cname = "gps_send")]
+    public int send(ref data_t gpsdata, string fmt, ...);
+
+    [CCode (cname = "gps_stream")]
+    public int stream(ref data_t gpsdata, uint flags, void* data);
+
+    /* mode flags for gps_stream() */
+    public int WATCH_DISABLE;  /* disable watching */
+    public int WATCH_ENABLE;   /* enable streaming */
+    public int WATCH_JSON;     /* enable JSON output */
+    public int WATCH_NMEA;     /* enable output in NMEA */
+    public int WATCH_RARE;     /* enable output of packets in hex */
+    public int WATCH_RAW;      /* enable output of raw packets */
+    public int WATCH_SCALED;   /* scale output to floats, when applicable */ 
+    public int WATCH_NEWSTYLE; /* force JSON streaming */
+    public int WATCH_OLDSTYLE; /* force old-style streaming */
+    public int WATCH_DEVICE;   /* watch specific device */
+    public int POLL_NONBLOCK;  /* set non-blocking poll */
+
+    /*
+       [CCode (cname = "struct input_event")]
+       public struct Event
+       {
+               public Posix.timeval time;
+               public uint16 type;
+               public uint16 code;
+               [CCode (cname="value")]
+               public int32 val;
+       }
+
+       [CCode (cprefix="KEY_")]
+       public enum Key
+       {
+               POWER
+       }
+
+       [CCode (cprefix="EV_")]
+       public enum Type
+       {
+               SYN,
+               KEY,
+               REL,
+               ABS,
+               MSC,
+               SW,
+               LED,
+               SND,
+               REP,
+               FF,
+               PWR,
+               FF_STATUS
+       }
+}
+[CCode (cprefix="", cheader_filename="omhacks/all.h")]
+namespace Omhacks
+{
+    [CCode (cname = "struct om_led", cheader_filename = "omhacks/led.h", destroy_function = "")]
+    public struct Led
+    {
+        public char name[255];
+        public string dir;
+        public int dir_len;
+        public int brightness;
+        public char trigger[255];
+        public int delay_on;
+        public int delay_off;
+
+        [CCode (cname = "om_led_init")]
+        public int init(string name);
+        [CCode (cname = "om_led_get")]
+        public int get();
+        [CCode (cname = "om_led_set")]
+        public int set();
+    }
+
+    namespace Screen
+    {
+        namespace Brightness
+        {
+            [CCode (cname = "om_screen_brightness_get")]
+            public int get();
+            [CCode (cname = "om_screen_brightness_get_max")]
+            public int get_max();
+            [CCode (cname = "om_screen_brightness_set")]
+            public int set(int val);
+        }
+    }
+
+    namespace UEvent
+    {
+        [CCode (cname = "struct om_uevent", cheader_filename = "omhacks/uevent.h", destroy_function = "")]
+        public struct Event
+        {
+            public string buffer;
+            size_t buflen;
+            weak string action;
+            weak string devpath;
+            weak string[] envp;
+        }
+
+        [CCode (cname = "om_uevent_open")]
+        public int open();
+        [CCode (cname = "om_uevent_read")]
+        public int read(int sock, ref Event ou);
+        [CCode (cname = "om_uevent_parse")]
+        public int parse(ref Event ou);
+    }
+    */
+}
diff --git a/src/libomhacks.vapi b/src/libomhacks.vapi
new file mode 100644 (file)
index 0000000..83434f3
--- /dev/null
@@ -0,0 +1,55 @@
+[CCode (cprefix="", cheader_filename="omhacks/all.h")]
+namespace Omhacks
+{
+    [CCode (cname = "struct om_led", cheader_filename = "omhacks/led.h", destroy_function = "")]
+    public struct Led
+    {
+        public char name[255];
+        public string dir;
+        public int dir_len;
+        public int brightness;
+        public char trigger[255];
+        public int delay_on;
+        public int delay_off;
+
+        [CCode (cname = "om_led_init")]
+        public int init(string name);
+        [CCode (cname = "om_led_get")]
+        public int get();
+        [CCode (cname = "om_led_set")]
+        public int set();
+    }
+
+    namespace Screen
+    {
+        namespace Brightness
+        {
+            [CCode (cname = "om_screen_brightness_get")]
+            public int get();
+            [CCode (cname = "om_screen_brightness_get_max")]
+            public int get_max();
+            [CCode (cname = "om_screen_brightness_set")]
+            public int set(int val);
+        }
+    }
+
+    namespace UEvent
+    {
+        [CCode (cname = "struct om_uevent", cheader_filename = "omhacks/uevent.h", destroy_function = "")]
+        public struct Event
+        {
+            public string buffer;
+            size_t buflen;
+            weak string action;
+            weak string devpath;
+            weak string[] envp;
+        }
+
+        [CCode (cname = "om_uevent_open")]
+        public int open();
+        [CCode (cname = "om_uevent_read")]
+        public int read(int sock, ref Event ou);
+        [CCode (cname = "om_uevent_parse")]
+        public int parse(ref Event ou);
+    }
+}
diff --git a/src/linux-input.vapi b/src/linux-input.vapi
new file mode 100644 (file)
index 0000000..211eab5
--- /dev/null
@@ -0,0 +1,42 @@
+[CCode (lower_case_cprefix="", cprefix="", cheader_filename="linux/input.h")]
+namespace LinuxInput
+{
+       [CCode (cname = "struct input_event")]
+       public struct Event
+       {
+               public Posix.timeval time;
+               public uint16 type;
+               public uint16 code;
+               [CCode (cname="value")]
+               public int32 val;
+       }
+
+       [CCode (cprefix="KEY_")]
+       public enum Key
+       {
+               POWER
+       }
+
+       [CCode (cprefix="EV_")]
+       public enum Type
+       {
+               SYN,
+               KEY,
+               REL,
+               ABS,
+               MSC,
+               SW,
+               LED,
+               SND,
+               REP,
+               FF,
+               PWR,
+               FF_STATUS
+       }
+
+    [CCode (cprefix="EVIO")]
+    public enum Evio
+    {
+        CGRAB
+    }
+}
diff --git a/src/log.vala b/src/log.vala
new file mode 100644 (file)
index 0000000..eb78363
--- /dev/null
@@ -0,0 +1,317 @@
+/*
+ * log - logging functions
+ *
+ * Copyright (C) 2009--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 log {
+
+public class Waypoint : Object
+{
+    public time_t ts;
+    public double lat;
+    public double lon;
+
+    public Waypoint()
+    {
+        if (gps.gps.fix_status() != libgps.STATUS_NO_FIX)
+        {
+            lat = gps.gps.info().fix.latitude;
+            lon = gps.gps.info().fix.longitude;
+            ts = (time_t)gps.gps.info().fix.time;
+        } else {
+            // Use 1000 as missing values
+            lat = 1000;
+            lon = 1000;
+            ts = time_t();
+        }
+    }
+
+    public void writeInside(FileStream outfd)
+    {
+        var t = Time.gm(ts);
+        outfd.printf("   <time>%s</time>\n", t.format("%Y-%m-%dT%H:%M:%SZ"));
+    }
+}
+
+
+public class LogEntry : Waypoint
+{
+    public string msg;
+
+    public LogEntry()
+    {
+        base();
+    }
+
+    public void write(FileStream outfd)
+    {
+        outfd.printf("   <wpt lat=\"%f\" lon=\"%f\">\n", lat, lon);
+        writeInside(outfd);
+        outfd.printf("   <name>%s</name>\n", Markup.escape_text(msg));
+        outfd.puts("   </wpt>\n");
+    }
+}
+
+public class TrackEntry : Waypoint
+{
+    public TrackEntry()
+    {
+        base();
+    }
+
+    public void write(FileStream outfd)
+    {
+        outfd.printf("   <trkpt lat=\"%f\" lon=\"%f\">\n", lat, lon);
+        writeInside(outfd);
+        outfd.puts("   </trkpt>\n");
+    }
+}
+
+
+public class Log : Object
+{
+    public uint id;
+    public string tag;
+    public string title;
+    public List<LogEntry> entries;
+    public List<TrackEntry> track;
+
+    public Log(uint id, string tag, string title)
+    {
+        this.id = id;
+        this.tag = tag;
+        this.title = title;
+        entries = null;
+        track = null;
+    }
+
+    public void add(string msg)
+    {
+        var entry = new LogEntry();
+        entry.msg = msg;
+        entries.append(entry);
+    }
+
+    public void add_trackpoint()
+    {
+        track.append(new TrackEntry());
+    }
+
+    public void save()
+    {
+        if (entries == null) return;
+
+        // Directory where we save the log
+        string dir = config.homedir + "/log-" + tag;
+        DirUtils.create(dir, 0777);
+
+        // First try with a plain name
+        var t = Time.local(entries.data.ts);
+        string basename = dir + "/" + t.format("%Y%m%d-%H%M%S");
+
+        string pathname = basename + ".gpx";
+
+        // Find a pathname that does not exist already
+        for (int i = 1; FileUtils.test(pathname, FileTest.EXISTS); ++i)
+            pathname = "%s-%d.gpx".printf(basename, i);
+
+        // Write out
+        var outfd = FileStream.open(pathname, "w");
+        if (outfd == null)
+        {
+            zavai.log.error("opening " + pathname + ": " + strerror(errno));
+            return;
+        }
+
+        write(outfd);
+        outfd.flush();
+    }
+
+    protected void writeTrack(FileStream outfd)
+    {
+        outfd.puts("   <trk>\n");
+        outfd.puts("     <trkseg>\n");
+        for (weak List<TrackEntry> i = track; i != null; i = i.next)
+            i.data.write(outfd);
+        outfd.puts("     </trkseg>\n");
+        outfd.puts("   </trk>\n");
+    }
+
+    protected void writeEntries(FileStream outfd)
+    {
+        outfd.puts("   <wpt>\n");
+        for (weak List<LogEntry> i = entries; i != null; i = i.next)
+            i.data.write(outfd);
+        outfd.puts("   </wpt>\n");
+    }
+
+    protected void write(FileStream outfd)
+    {
+        outfd.puts("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
+        outfd.puts("<gpx version=\"1.0\"\n");
+        outfd.printf("     creator=\"zavai %s\"\n", zavai.config.version);
+        outfd.puts("     xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n");
+        outfd.puts("     xmlns=\"http://www.topografix.com/GPX/1/0\"\n");
+        outfd.puts("     xsi:schemaLocation=\"http://www.topografix.com/GPX/1/0 http://www.topografix.com/GPX/1/0/gpx.xsd\">\n");
+        outfd.puts("  <metadata>\n");
+        outfd.printf("    <name>%s</name>\n", Markup.escape_text(title));
+        outfd.puts("  </metadata>\n");
+        if (track != null) writeTrack(outfd);
+        if (entries != null) writeEntries(outfd);
+        outfd.puts(" </gpx>\n");
+    }
+}
+
+public class Logger : Resource, Object
+{
+    protected List<Log> logs;
+    protected uint seq;
+
+    public Logger()
+    {
+        logs = null;
+        seq = 0;
+
+        zavai.registry.register(this);
+    }
+
+    protected void start_trace()
+    {
+        gps.gps.pos_changed += on_pos_changed;
+    }
+
+    protected void end_trace()
+    {
+        gps.gps.pos_changed -= on_pos_changed;
+    }
+
+    protected void on_pos_changed()
+    {
+        for (weak List<Log> i = logs; i != null; i = i.next)
+            i.data.add_trackpoint();
+    }
+
+    protected uint gen_seq()
+    {
+        // Increase avoiding 0 on rollover
+        while (true)
+        {
+            if (++seq == 0) ++seq;
+            bool found = false;
+            for (weak List<Log> i = logs; i != null; i = i.next)
+            {
+                if (i.data.id == seq)
+                {
+                    found = true;
+                    break;
+                }
+            }
+            if (!found) break;
+        }
+        return seq;
+    }
+
+    protected weak Log? find(uint id)
+    {
+        for (weak List<Log> i = logs; i != null; i = i.next)
+            if (i.data.id == id)
+                return i.data;
+        return null;
+    }
+
+    protected Log? pop(uint id)
+    {
+        for (weak List<Log> i = logs; i != null; i = i.next)
+            if (i.data.id == id)
+            {
+                Log res = i.data;
+                logs.delete_link(i);
+                return res;
+            }
+        return null;
+    }
+
+    public uint start(string tag, string title)
+    {
+        bool was_empty = (logs == null);
+        uint id = gen_seq();
+        logs.append(new Log(id, tag, title));
+        if (was_empty) start_trace();
+        return id;
+    }
+
+    public void add(uint id, string msg)
+    {
+        Log log = find(id);
+        if (log == null) return;
+        log.add(msg);
+    }
+
+    public void end(uint id)
+    {
+        Log log = pop(id);
+        log.save();
+        if (log == null) end_trace();
+    }
+
+    public void instant(string tag, string msg)
+    {
+        var log = new Log(0, tag, msg);
+        log.add(msg);
+        log.save();
+    }
+
+    public void shutdown()
+    {
+        while (logs != null)
+        {
+            var log = pop(logs.data.id);
+            log.save();
+        }
+    }
+}
+
+public void error(string s)
+{
+       stderr.printf("%s\n", s);
+}
+public void warning(string s)
+{
+       stderr.printf("%s\n", s);
+}
+public void info(string s)
+{
+       stderr.printf("%s\n", s);
+}
+public void debug(string s)
+{
+       stderr.printf("%s\n", s);
+}
+
+Logger log = null;
+
+public void init()
+{
+    log = new Logger();
+}
+
+}
+}
diff --git a/src/lua5.1.vapi b/src/lua5.1.vapi
new file mode 120000 (symlink)
index 0000000..e730dfc
--- /dev/null
@@ -0,0 +1 @@
+/usr/share/vala/vapi/lua.vapi
\ No newline at end of file
diff --git a/src/power.vala b/src/power.vala
new file mode 100644 (file)
index 0000000..5571117
--- /dev/null
@@ -0,0 +1,192 @@
+/*
+ * power - zavai power event handling
+ *
+ * Copyright (C) 2009  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 power {
+
+public class Power : Service
+{
+    public enum State
+    {
+        UNKNOWN,
+        CHARGING,
+        DISCHARGING,
+        FULLY_CHARGED,
+    }
+
+    protected string battery_device;
+    protected uint timeout;
+    public signal void changed();
+    public State state;
+    public int percentage;
+
+    public Power()
+    {
+        battery_device = "/sys/class/power_supply/battery/";
+        if (Posix.access(battery_device, Posix.R_OK) != 0)
+            battery_device = null;
+        timeout = 0;
+        state = State.UNKNOWN;
+        percentage = 0;
+    }
+
+    /// Activate the service
+    protected override void start()
+    {
+        if (started) return;
+
+        uint poll_time;
+        if (uevent.uevent != null)
+        {
+            zavai.log.info("We have uevent: poll rarely");
+            uevent.uevent.event += on_uevent;
+            uevent.uevent.request("zavai.power");
+            // If we can get plug/unplug notifications, it's ok to just poll
+            // every 5 minutes
+            poll_time = 300 * 1000;
+        } else {
+            if (battery_device == null)
+            {
+                zavai.log.warning("No battery device found that I know how to read: try building with devkit-power");
+                poll_time = 0;
+            } else {
+                zavai.log.info("Polling battery device only");
+                // Else poll every 30 seconds to be somehow reactive to plug/unplug
+                // events
+                poll_time = 30 * 1000;
+            }
+        }
+
+        poll();
+
+        // Poll battery every minute
+        if (poll_time != 0)
+            timeout = Timeout.add(poll_time, on_timeout);
+
+        base.start();
+    }
+
+    /// Deactivate the service
+    protected override void stop()
+    {
+        if (!started) return;
+
+        // Stop polling
+        if (timeout != 0)
+            Source.remove(timeout);
+
+        if (uevent.uevent != null)
+        {
+            uevent.uevent.release("zavai.power");
+            uevent.uevent.event -= on_uevent;
+        }
+
+        base.stop();
+    }
+
+    protected void poll()
+    {
+        if (battery_device == null)
+            return;
+
+        char buf[200];
+        State new_state = State.UNKNOWN;
+        int new_percentage = 0;
+
+        FileStream state_fd = FileStream.open(battery_device + "/status", "r");
+        string val = state_fd.gets(buf);
+        if (val == "Charging")
+            new_state = State.CHARGING;
+        else if (val == "Discharging")
+            new_state = State.DISCHARGING;
+        else if (val == "Not charging")
+            new_state = State.FULLY_CHARGED;
+
+        FileStream cap_fd = FileStream.open(battery_device + "/capacity", "r");
+        val = cap_fd.gets(buf);
+        new_percentage = val.to_int();
+
+        if (new_state != state || new_percentage != percentage)
+        {
+            state = new_state;
+            percentage = new_percentage;
+            changed();
+        }
+    }
+
+    protected bool on_timeout()
+    {
+        poll();
+        return true;
+    }
+
+    protected void on_uevent()
+    {
+        /* if (uevent.uevent.event_data.buffer.has_prefix("change@/class/power_supply/ac"))
+        {
+            changed();
+        }
+        else */
+        if (uevent.uevent.event_data.buffer.has_prefix("change@/class/power_supply/battery"))
+        {
+            State new_state = State.UNKNOWN;
+            int new_percentage = 0;
+
+            Omhacks.UEvent.parse(ref uevent.uevent.event_data);
+            for (int i = 0; uevent.uevent.event_data.envp[i] != null; ++i)
+            {
+                if (uevent.uevent.event_data.envp[i].has_prefix("POWER_SUPPLY_STATUS="))
+                {
+                    var val = uevent.uevent.event_data.envp[i].offset(20);
+                    if (val == "Charging")
+                        new_state = State.CHARGING;
+                    else if (val == "Discharging")
+                        new_state = State.DISCHARGING;
+                    else if (val == "Not charging")
+                        new_state = State.FULLY_CHARGED;
+                    else
+                        zavai.log.warning("Unknown state: " + uevent.uevent.event_data.envp[i]);
+                }
+                else if (uevent.uevent.event_data.envp[i].has_prefix("POWER_SUPPLY_CAPACITY="))
+                {
+                    new_percentage = uevent.uevent.event_data.envp[i].offset(22).to_int();
+                }
+            }
+            if (new_state != state || new_percentage != percentage)
+            {
+                state = new_state;
+                percentage = new_percentage;
+                changed();
+            }
+        }
+    }
+}
+
+public Power power;
+
+public void init()
+{
+    power = new Power();
+}
+
+}
+}
diff --git a/src/registry.vala b/src/registry.vala
new file mode 100644 (file)
index 0000000..3d549da
--- /dev/null
@@ -0,0 +1,83 @@
+/* 
+ * registry - zavai resource registry
+ *
+ * Copyright (C) 2009  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 {
+
+public class Registry : Object, Resource
+{
+    List<Resource> resources;
+    public DBus.Connection sbus;
+    public string bus_name;
+
+    public Registry()
+    {
+        resources = new List<Resource>();
+        try {
+            sbus = DBus.Bus.get(DBus.BusType.SYSTEM);
+        } catch (DBus.Error e) {
+            stderr.printf("Cannot access system DBus bus: %s\n", e.message);
+            sbus = null;
+        }
+
+        bus_name = DBus.bus_get_unique_name(sbus.get_connection());
+        zavai.log.info("My bus name: " + bus_name);
+
+        dynamic DBus.Object tmp_dbus = sbus.get_object(
+            "org.freedesktop.DBus",
+            "/org/freedesktop/DBus",
+            "org.freedesktop.DBus");
+        bus_name = "org.enricozini.zavai";
+        uint res = tmp_dbus.RequestName(bus_name, (uint)DBus.NameFlag.DO_NOT_QUEUE);
+        switch (res)
+        {
+            case DBus.RequestNameReply.PRIMARY_OWNER:
+                zavai.log.info("Registered to dbus as " + bus_name);
+                break;
+            case DBus.RequestNameReply.IN_QUEUE:
+                zavai.log.info("In queue, but I asked not to");
+                break;
+            case DBus.RequestNameReply.EXISTS:
+                zavai.log.info(bus_name + " already exists");
+                break;
+            case DBus.RequestNameReply.ALREADY_OWNER:
+                zavai.log.info("I already own the name " + bus_name + " but I do not remember asking for it");
+                break;
+        }
+    }
+
+    public void shutdown()
+    {
+        // Shutdown in reverse registration order
+        for (weak List<Resource> i = resources; i != null; i = i.next)
+            i.data.shutdown();
+    }
+
+    public void register(Resource obj)
+    {
+        resources.prepend(obj);
+    }
+}
+
+public zavai.Registry registry;
+
+}
+
diff --git a/src/uevent.vala b/src/uevent.vala
new file mode 100644 (file)
index 0000000..b9475ae
--- /dev/null
@@ -0,0 +1,92 @@
+/*
+ * uevent - zavai uevent handling
+ *
+ * Copyright (C) 2009  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 uevent {
+
+class UEvent : Service
+{
+    protected IOChannel sock;
+    protected uint sock_watch = 0;
+    public Omhacks.UEvent.Event event_data;
+    public signal void event();
+
+    public UEvent()
+    {
+        event_data = Omhacks.UEvent.Event();
+    }
+
+    protected bool on_input_data(IOChannel source, IOCondition condition)
+    {
+        if (condition != IOCondition.IN) return true;
+
+        Omhacks.UEvent.read(sock.unix_get_fd(), ref event_data);
+        event();
+
+        return true;
+    }
+
+    /// Activate the service
+    protected override void start()
+    {
+        if (started) return;
+
+        int sock_fd = Omhacks.UEvent.open();
+        if (sock_fd < 0)
+        {
+            zavai.log.error("UEvent: error getting socket");
+            return;
+        }
+
+        sock = new IOChannel.unix_new(sock_fd);
+        sock_watch = sock.add_watch(IOCondition.IN, on_input_data);
+
+        base.start();
+    }
+
+    /// Deactivate the service
+    protected override void stop()
+    {
+        if (!started) return;
+        Source.remove(sock_watch);
+        try {
+            sock.shutdown(false);
+        } catch (IOChannelError e) {
+            zavai.log.error("When closing UEvent socket: " + e.message);
+        }
+        sock = null;
+        base.stop();
+    }
+}
+
+UEvent uevent;
+
+public void init()
+{
+    if (Posix.getuid() == 0)
+        uevent = new UEvent();
+    else
+        uevent = null;
+}
+
+}
+}
diff --git a/src/wifi.vala b/src/wifi.vala
new file mode 100644 (file)
index 0000000..55cf1cc
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ * wifi - wifi resource for zavai
+ *
+ * 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 wifi {
+
+public class Wifi: zavai.ScriptService
+{
+    public Wifi()
+    {
+        Object(name: "wifi");
+        started = script_status();
+    }
+
+    /// Start wifi
+    public override void start()
+    {
+        if (started) return;
+        if (!script_start()) return;
+        zavai.log.info("wifi turned on");
+        base.start();
+    }
+
+    // Release usage of wifi
+    public override void stop()
+    {
+        if (!started) return;
+        script_stop();
+        base.stop();
+    }
+}
+
+public Wifi wifi = null;
+
+public void init()
+{
+    wifi = new Wifi();
+
+}
+
+}
+}
diff --git a/src/x11.vapi b/src/x11.vapi
new file mode 100644 (file)
index 0000000..ec8b074
--- /dev/null
@@ -0,0 +1,883 @@
+/* x11.vapi
+ *
+ * Copyright (C) 2009  Jürg Billeter
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA
+ *
+ * Author:
+ *     Jürg Billeter <j@bitron.ch>
+ */
+
+[CCode (cprefix = "", lower_case_cprefix = "", cheader_filename = "X11/Xlib.h,X11/Xatom.h,X11/Xutil.h")]
+namespace X {
+       // Note: must be called before opening a display or calling any other Xlib function,
+       // see http://tronche.com/gui/x/xlib/display/XInitThreads.html
+       [CCode (cname = "XInitThreads")]
+       public Status init_threads ();
+
+       [Compact]
+       [CCode (cname = "Display", ref_function = "", unref_function = "")]
+       public class Display {
+               [CCode (cname = "XOpenDisplay")]
+               public Display (string? name = null);
+
+               [CCode (cname = "XGetAtomName")]
+               public string get_atom_name(Atom a);
+
+               [CCode (cname = "XAllPlanes")]
+               public static ulong get_all_planes ();
+
+               [CCode (cname = "XAddToSaveSet")]
+               public int add_to_save_set (Window w);
+
+               [CCode (cname = "XAllowEvents")]
+               public int allow_events (int event_mode, int time);
+
+               [CCode (cname = "XBitmapBitOrder")]
+               public int bitmap_bit_order ();
+
+               [CCode (cname = "XBitmapUnit")]
+               public int bitmap_scanline_unit ();
+
+               [CCode (cname = "XBitmapPad")]
+               public int bitmap_scanline_padding ();
+
+               [CCode (cname = "XChangeProperty")]
+               public int change_property (Window w, Atom property, Atom type, int format, int mode, [CCode (array_length = false)] uchar[] data, int nelements);
+
+               [CCode (cname = "XChangeWindowAttributes")]
+               public int change_window_attributes (Window w, ulong valuemask, SetWindowAttributes attributes);
+
+               [CCode (cname = "XConfigureWindow")]
+               public int configure_window (Window w, uint value_mask, WindowChanges values);
+
+               [CCode (cname = "ConnectionNumber")]
+               public int connection_number ();
+
+               [CCode (cname = "DefaultRootWindow")]
+               public Window default_root_window ();
+
+               [CCode (cname = "XDefaultScreenOfDisplay")]
+               public unowned Screen default_screen ();
+
+               [CCode (cname = "XScreenOfDisplay")]
+               public unowned Screen screen_by_id (int screen_number);
+
+               [CCode (cname = "DisplayString")]
+               public string display_string ();
+
+               [CCode (cname = "XQLength")]
+               public int event_queue_length ();
+
+               [CCode (cname = "XFlush")]
+               public int flush ();
+
+               [CCode (cname = "XGetKeyboardMapping", array_length = false)]
+               public weak uint[] get_keyboard_mapping (uint first_keycode, int keycode_count, ref int keysyms_per_keycode_return);
+
+               [CCode (cname = "XGetModifierMapping")]
+               public ModifierKeymap get_modifier_mapping ();
+
+               [CCode (cname = "XGetSelectionOwner")]
+               public Window get_selection_owner (Atom selection);
+
+               [CCode (cname = "XGetWindowAttributes")]
+               public void get_window_attributes (Window w, out WindowAttributes window_attributes_return);
+
+               [CCode (cname = "XGetWindowProperty")]
+               public int get_window_property (Window w, Atom property, long long_offset, long long_length, bool delete, Atom req_type, out Atom actual_type_return, out int actual_format_return, out ulong nitems_return, out ulong bytes_after_return, out void* prop_return);
+
+               [CCode (cname = "XGrabButton")]
+               public int grab_button (uint button, uint modifiers, Window grab_window, bool owner_events, uint event_mask, int pointer_mode, int keyboard_mode, Window confine_to, uint cursor);
+
+               [CCode (cname = "XGrabKey")]
+               public int grab_key (int keycode, uint modifiers, Window grab_window, bool owner_events, int pointer_mode, int keyboard_mode);
+
+               [CCode (cname = "XGrabPointer")]
+               public int grab_pointer (Window grab_window, bool owner_events, uint event_mask, int pointer_mode, int keyboard_mode, Window confine_to, uint cursor, int time);
+
+               [CCode (cname = "XGrabServer")]
+               public int grab_server ();
+
+               [CCode (cname = "XImageByteOrder")]
+               public int image_byte_order ();
+
+               [CCode (cname = "XInternAtom")]
+               public Atom intern_atom (string atom_name, bool only_if_exists);
+
+               [CCode (cname = "XInternAtoms")]
+               public void intern_atoms (string[] names, bool only_if_exists, [CCode (array_length = false)] Atom[] atoms_return);
+
+               [CCode (cname = "XInternalConnectionNumbers")]
+               public Status internal_connection_numbers (ref int[] fd_return);
+
+               [CCode (cname = "XDisplayKeycodes")]
+               public int keycodes (ref int min_keycodes_return, ref int max_keycodes_return);
+
+               [CCode (cname = "XKeysymToKeycode")]
+               public int keysym_to_keycode (uint keysym);
+
+               [CCode (cname = "XLastKnownRequestProcessed")]
+               public ulong last_known_request_processed ();
+
+               [CCode (cname = "XLockDisplay")]
+               public void lock_display ();
+
+               [CCode (cname = "XMapWindow")]
+               public int map_window (Window w);
+
+               [CCode (cname = "XMaxRequestSize")]
+               public long max_request_size ();
+
+               [CCode (cname = "XExtendedMaxRequestSize")]
+               public long max_extended_request_size ();
+
+               [CCode (cname = "XNextEvent")]
+               public int next_event (ref Event event_return);
+
+               [CCode (cname = "XNextRequest")]
+               public ulong next_request ();
+
+               [CCode (cname = "XNoOp")]
+               public void no_operation ();
+
+               [CCode (cname = "XScreenCount")]
+               public int number_of_screens ();
+
+               [CCode (cname = "XPending")]
+               public int pending ();
+
+               [CCode (cname = "XProcessInternalConnection")]
+               public void process_internal_connection (int fd);
+
+               [CCode (cname = "XProtocolVersion")]
+               public int protocol_version ();
+
+               [CCode (cname = "XProtocolRevision")]
+               public int protocol_revision ();
+
+               [CCode (cname = "XRaiseWindow")]
+               public int raise_window (Window w);
+
+               [CCode (cname = "XReparentWindow")]
+               public int reparent_window (Window w, Window parent, int x, int y);
+
+               [CCode (cname = "XResizeWindow")]
+               public int resize_window (Window w, uint width, uint height);
+
+               [CCode (cname = "XRootWindow")]
+               public Window root_window (int screen_number);
+
+               [CCode (cname = "ScreenCount")]
+               public int screen_count ();
+
+               [CCode (cname = "XScreenOfDisplay")]
+               public weak Screen screen_of_display (int screen_number);
+
+               [CCode (cname = "XSelectInput")]
+               public int select_input (Window w, long event_mask);
+
+               [CCode (cname = "XSendEvent")]
+               public void send_event (Window w, bool prpagate, long event_mask, ref Event event_send);
+
+               [CCode (cname = "XSetCloseDownMode")]
+               public void set_close_down_mode (int close_mode);
+
+               [CCode (cname = "XSetSelectionOwner")]
+               public Window set_selection_owner (Atom selection, Window owner, int time);
+
+               [CCode (cname = "XSetInputFocus")]
+               public int set_input_focus (Window focus, int revert_to, int time);
+
+               [CCode (cname = "XUngrabButton")]
+               public int ungrab_button (uint button, uint modifiers, Window grab_window);
+
+               [CCode (cname = "XUngrabPointer")]
+               public int ungrab_pointer (int time);
+
+               [CCode (cname = "XUngrabServer")]
+               public int ungrab_server ();
+
+               [CCode (cname = "XUnlockDisplay")]
+               public void unlock_display ();
+
+               [CCode (cname = "XUnmapWindow")]
+               public int unmap_window (Window w);
+
+               [CCode (cname = "XQueryTree")]
+               public void query_tree (Window w, out Window root_return, out Window parent_return, out Window[] children_return);
+
+               [CCode (cname = "XWindowEvent")]
+               public int window_event (Window w, EventMask event_mask, out Event event_return);
+
+               [CCode (cname = "XServerVendor")]
+               public string xserver_vendor_name ();
+
+               [CCode (cname = "XVendorRelease")]
+               public string xserver_vendor_release ();
+
+               [CCode (cname = "XMoveWindow")]
+               public void move_window (Window window, int x, int y);
+       }
+
+       [Compact]
+       [CCode (cname = "XModifierKeymap", free_function = "XFreeModifiermap")]
+       public class ModifierKeymap {
+               // The server's max # of keys per modifier
+               public int max_keypermod;
+               // An 8 by max_keypermod array of modifiers
+               public uchar[] modifiermap;
+       }
+
+       [SimpleType]
+       [IntegerType (rank = 9)]
+       [CCode (cname = "Atom")]
+       public struct Atom {
+       }
+
+       [SimpleType]
+       [IntegerType (rank = 9)]
+       [CCode (cname = "Colormap")]
+       public struct Colormap {
+       }
+
+       [SimpleType]
+       [CCode (cname = "GC")]
+       public struct GC {
+       }
+
+       [SimpleType]
+       [IntegerType (rank = 9)]
+       [CCode (cname = "Status")]
+       public struct Status {
+       }
+
+       [SimpleType]
+       [IntegerType (rank = 9)]
+       [CCode (cname = "Window", type_id = "G_TYPE_INT",
+               marshaller_type_name = "INT",
+               get_value_function = "g_value_get_int",
+               set_value_function = "g_value_set_int", default_value = "0",
+               type_signature = "i")]
+       public struct Window {
+       }
+
+       public struct Visual {
+       }
+
+       public struct WindowChanges {
+               public int x;
+               public int y;
+               public int width;
+               public int height;
+               public int border_width;
+               public Window sibling;
+               public int stack_mode;
+       }
+       public struct SizeHints {
+               public long @flags;
+               public int x;
+               public int y;
+               public int width;
+               public int height;
+       }
+
+       [CCode (cname = "XCreateWindow")]
+       public Window create_window (Display display, Window parent, int x, int y, uint width, uint height, uint border_width, int depth, uint @class, Visual? visual, X.CW valuemask, ref SetWindowAttributes attributes);
+
+       [CCode (cname = "XSetWindowAttributes")]
+       public struct SetWindowAttributes {
+               // public Pixmap background_pixmap;     /* background or None or ParentRelative */
+               public ulong background_pixel;  /* background pixel */
+               // public Pixmap border_pixmap; /* border of the window */
+               public ulong border_pixel;      /* border pixel value */
+               public int bit_gravity;         /* one of bit gravity values */
+               public int win_gravity;         /* one of the window gravity values */
+               public int backing_store;               /* NotUseful, WhenMapped, Always */
+               public ulong backing_planes;/* planes to be preseved if possible */
+               public ulong backing_pixel;/* value to use in restoring planes */
+               public bool save_under;         /* should bits under be saved? (popups) */
+               public long event_mask;         /* set of events that should be saved */
+               public long do_not_propagate_mask;      /* set of events that should not propagate */
+               public bool override_redirect;  /* boolean value for override-redirect */
+               // public Colormap colormap;            /* color map to be associated with window */
+               // public Cursor cursor;                /* cursor to be displayed (or None) */
+       }
+
+       [CCode(cname = "XWindowAttributes",
+              cheader_filename = "X11/Xlib.h,X11/Xatom.h,X11/Xutil.h")]
+       public struct WindowAttributes {
+               public int x;
+               public int y;                   /* location of window */
+               public int width;
+               public int height;              /* width and height of window */
+               public int border_width;                /* border width of window */
+               public int depth;               /* depth of window */
+               public Visual visual;           /* the associated visual structure */
+               public Window root;             /* root of screen containing window */
+               public int @class;                      /* InputOutput, InputOnly*/
+               public int bit_gravity;         /* one of bit gravity values */
+               public int win_gravity;         /* one of the window gravity values */
+               public int backing_store;               /* NotUseful, WhenMapped, Always */
+               public ulong backing_planes;/* planes to be preserved if possible */
+               public ulong backing_pixel;/* value to be used when restoring planes */
+               public bool save_under;         /* boolean, should bits under be saved? */
+               // public Colormap colormap;            /* color map to be associated with window */
+               public bool map_installed;              /* boolean, is color map currently installed*/
+               public int map_state;           /* IsUnmapped, IsUnviewable, IsViewable */
+               public long all_event_masks;    /* set of events all people have interest in*/
+               public long your_event_mask;    /* my event mask */
+               public long do_not_propagate_mask; /* set of events that should not propagate */
+               public bool override_redirect;  /* boolean value for override-redirect */
+               // public Screen screen;                /* back pointer to correct screen */
+       }
+
+       [CCode (cname = "CopyFromParent")]
+       public const int COPY_FROM_PARENT;
+
+       [CCode (cname = "CurrentTime")]
+       public const ulong CURRENT_TIME;
+
+       [CCode (cname = "Success")]
+       public int Success;
+
+       [CCode (cname = "XFree")]
+       public int free (void* data);
+
+       [CCode (cprefix = "CW", cname = "int")]
+       public enum CW {
+               BackPixmap,
+               BackPixel,
+               BackingStore,
+               BackingPlanes,
+               BackingPixel,
+               BitGravity,
+               BorderPixmap,
+               BorderPixel,
+               BorderWidth,
+               Colormap,
+               Cursor,
+               DontPropagate,
+               EventMask,
+               Height,
+               OverrideRedirect,
+               SaveUnder,
+               Sibling,
+               StackMode,
+               X,
+               Y,
+               Width,
+               WinGravity
+       }
+
+       [CCode (cprefix = "GrabMode")]
+       public enum GrabMode {
+               Sync,
+               Async
+       }
+
+       [CCode (cprefix = "")]
+       public enum EventMask {
+               NoEventMask,
+               KeyPressMask,
+               KeyReleaseMask,
+               ButtonPressMask,
+               ButtonReleaseMask,
+               EnterWindowMask,
+               LeaveWindowMask,
+               PointerMotionMask,
+               PointerMotionHintMask,
+               Button1MotionMask,
+               Button2MotionMask,
+               Button3MotionMask,
+               Button4MotionMask,
+               Button5MotionMask,
+               ButtonMotionMask,
+               KeymapStateMask,
+               ExposureMask,
+               VisibilityChangeMask,
+               StructureNotifyMask,
+               ResizeRedirectMask,
+               SubstructureNotifyMask,
+               SubstructureRedirectMask,
+               FocusChangeMask,
+               PropertyChangeMask,
+               ColormapChangeMask,
+               OwnerGrabButtonMask
+       }
+
+       [CCode (cprefix = "")]
+       public enum KeyMask {
+               ShiftMask,
+               LockMask,
+               ControlMask,
+               Mod1Mask,
+               Mod2Mask,
+               Mod3Mask,
+               Mod4Mask,
+               Mod5Mask
+       }
+
+       [CCode (cprefix = "")]
+       public enum EventType {
+               KeyPress,
+               KeyRelease,
+               ButtonPress,
+               ButtonRelease,
+               MotionNotify,
+               EnterNotify,
+               LeaveNotify,
+               FocusIn,
+               FocusOut,
+               KeymapNotify,
+               Expose,
+               GraphicsExpose,
+               NoExpose,
+               VisibilityNotify,
+               CreateNotify,
+               DestroyNotify,
+               UnmapNotify,
+               MapNotify,
+               MapRequest,
+               ReparentNotify,
+               ConfigureNotify,
+               ConfigureRequest,
+               GravityNotify,
+               ResizeRequest,
+               CirculateNotify,
+               CirculateRequest,
+               PropertyNotify,
+               SelectionClear,
+               SelectionRequest,
+               SelectionNotify,
+               ColormapNotify,
+               ClientMessage,
+               MappingNotify
+       }
+
+       // union
+       [CCode (cname = "XEvent")]
+       public struct Event {
+               public int type;
+               public AnyEvent xany;
+               public KeyEvent xkey;
+               public ButtonEvent xbutton;
+               public MotionEvent xmotion;
+               public CrossingEvent xcrossing;
+               public CreateWindowEvent xcreatewindow;
+               public DestroyWindowEvent xdestroywindow;
+               public UnmapEvent xunmap;
+               public MapEvent xmap;
+               public MapRequestEvent xmaprequest;
+               public ReparentEvent xreparent;
+               public ConfigureEvent xconfigure;
+               public GravityEvent xgravity;
+               public ConfigureRequestEvent xconfigurerequest;
+               public CirculateEvent xcirculate;
+               public CirculateRequestEvent xcirculaterequest;
+               public PropertyEvent xproperty;
+               public SelectionEvent xselection;
+               public ClientMessageEvent xclient;
+       }
+
+       [CCode (cname = "XAnyEvent")]
+       public struct AnyEvent {
+               public int type;
+               public ulong serial;
+               public bool send_event;
+               public unowned Display display;
+               public Window window;
+       }
+
+       [CCode (cname = "XKeyEvent")]
+       public struct KeyEvent {
+               public int type;
+               public ulong serial;
+               public bool send_event;
+               public unowned Display display;
+               public Window window;
+               public Window root;
+               public Window subwindow;
+               public ulong time;
+               public int x;
+               public int y;
+               public int x_root;
+               public int y_root;
+               public uint state;
+               public uint keycode;
+               public bool same_screen;
+       }
+
+       [CCode (cname = "XButtonEvent")]
+       public struct ButtonEvent {
+               public int type;
+               public ulong serial;
+               public bool send_event;
+               public unowned Display display;
+               public Window window;
+               public Window subwindow;
+               public ulong time;
+               public int x;
+               public int y;
+               public int x_root;
+               public int y_root;
+               public uint state;
+               public uint button;
+               public bool same_screen;
+       }
+
+       [CCode (cname = "XMotionEvent")]
+       public struct MotionEvent {
+               public int type;
+               public ulong serial;
+               public bool send_event;
+               public unowned Display display;
+               public Window window;
+               public Window subwindow;
+               public ulong time;
+               public int x;
+               public int y;
+               public int x_root;
+               public int y_root;
+               public uint state;
+               public char is_hint;
+               public bool same_screen;
+       }
+
+       [CCode (cname = "XCrossingEvent")]
+       public struct CrossingEvent {
+               public int type;
+               public ulong serial;
+               public bool send_event;
+               public unowned Display display;
+               public Window window;
+               public Window root;
+               public Window subwindow;
+               public ulong time;
+               public int x;
+               public int y;
+               public int x_root;
+               public int y_root;
+               public int mode;
+               public int detail;
+               public bool same_screen;
+               public bool focus;
+               public uint state;
+       }
+
+       [CCode (cname = "XCreateWindowEvent")]
+       public struct CreateWindowEvent {
+               public int type;
+               public ulong serial;
+               public bool send_event;
+               public unowned Display display;
+               public Window parent;
+               public Window window;
+               public int x;
+               public int y;
+               public int width;
+               public int height;
+               public int border_width;
+               public bool override_redirect;
+       }
+
+       [CCode (cname = "XDestroyWindowEvent")]
+       public struct DestroyWindowEvent {
+               public int type;
+               public ulong serial;
+               public bool send_event;
+               public unowned Display display;
+               public Window event;
+               public Window window;
+       }
+
+       [CCode (cname = "XUnmapEvent")]
+       public struct UnmapEvent {
+               public int type;
+               public ulong serial;
+               public bool send_event;
+               public unowned Display display;
+               public Window event;
+               public Window window;
+               public bool from_configure;
+       }
+
+       [CCode (cname = "XMapEvent")]
+       public struct MapEvent {
+               public int type;
+               public ulong serial;
+               public bool send_event;
+               public unowned Display display;
+               public Window event;
+               public Window window;
+               public bool override_redirect;
+       }
+
+       [CCode (cname = "XMapRequestEvent")]
+       public struct MapRequestEvent {
+               public int type;
+               public ulong serial;
+               public bool send_event;
+               public unowned Display display;
+               public Window parent;
+               public Window window;
+       }
+
+       [CCode (cname = "XReparentEvent")]
+       public struct ReparentEvent {
+               public int type;
+               public ulong serial;
+               public bool send_event;
+               public unowned Display display;
+               public Window event;
+               public Window window;
+               public Window parent;
+               public int x;
+               public int y;
+               public bool override_redirect;
+       }
+
+       [CCode (cname = "XConfigureEvent")]
+       public struct ConfigureEvent {
+               public int type;
+               public ulong serial;
+               public bool send_event;
+               public unowned Display display;
+               public Window event;
+               public Window window;
+               public int x;
+               public int y;
+               public int width;
+               public int height;
+               public int border_width;
+               public Window above;
+               public bool override_redirect;
+       }
+
+       [CCode (cname = "XGravityEvent")]
+       public struct GravityEvent {
+               public int type;
+               public ulong serial;
+               public bool send_event;
+               public unowned Display display;
+               public Window event;
+               public Window window;
+               public int x;
+               public int y;
+       }
+
+       [CCode (cname = "XConfigureRequestEvent")]
+       public struct ConfigureRequestEvent {
+               public int type;
+               public ulong serial;
+               public bool send_event;
+               public unowned Display display;
+               public Window parent;
+               public Window window;
+               public int x;
+               public int y;
+               public int width;
+               public int height;
+               public int border_width;
+               public Window above;
+               public int detail;
+               public ulong value_mask;
+       }
+
+       [CCode (cname = "XCirculateEvent")]
+       public struct CirculateEvent {
+               public int type;
+               public ulong serial;
+               public bool send_event;
+               public unowned Display display;
+               public Window event;
+               public Window window;
+               public int place;
+       }
+
+       [CCode (cname = "XCirculateRequestEvent")]
+       public struct CirculateRequestEvent {
+               public int type;
+               public ulong serial;
+               public bool send_event;
+               public unowned Display display;
+               public Window parent;
+               public Window window;
+               public int place;
+       }
+
+       [CCode (cname = "XPropertyEvent")]
+       public struct PropertyEvent {
+               public int type;
+               public ulong serial;
+               public bool send_event;
+               public unowned Display display;
+               public Window window;
+               public Atom atom;
+               public ulong time;
+               public int state;
+       }
+
+       [CCode (cname = "XSelectionEvent")]
+       public struct SelectionEvent {
+               public int type;
+               public ulong serial;
+               public bool send_event;
+               public unowned Display display;
+               public Window requestor;
+               public Atom selection;
+               public Atom target;
+               public Atom property;
+               public ulong time;
+       }
+
+       [CCode (cname = "XClientMessageEvent")]
+       public struct ClientMessageEvent {
+               public int type;
+               public ulong serial;    /* # of last request processed by server */
+               public bool send_event; /* true if this came from a SendEvent request */
+               public unowned Display display; /* Display the event was read from */
+               public Window window;
+               public Atom message_type;
+               public int format;
+               public ClientMessageEventData data;
+       }
+
+       // union
+       public struct ClientMessageEventData {
+               public unowned char[] b;
+               public unowned short[] s;
+               public unowned long[] l;
+       }
+
+       [CCode (cprefix = "PropMode")]
+       public enum PropMode {
+               Replace,
+               Prepend,
+               Append
+       }
+
+       [CCode (cprefix = "")]
+       public enum AllowEventsMode {
+               AsyncPointer,
+               SyncPointer,
+               ReplayPointer,
+               AsyncKeyboard,
+               SyncKeyboard,
+               ReplayKeyboard,
+               AsyncBoth,
+               SyncBoth
+       }
+
+       [CCode (cprefix = "")]
+       public enum MapState {
+               IsUnmapped,
+               IsUnviewable,
+               IsViewable
+       }
+
+       [CCode (cprefix = "RevertTo")]
+       public enum RevertTo {
+               None,
+               PointerRoot,
+               Parent
+       }
+
+       [Compact]
+       [CCode (cname = "Screen")]
+       public class Screen {
+               public Display display;
+               public Window root;
+               public int width;
+               public int height;
+
+               [CCode (cname = "XScreenOfDisplay")]
+               public static unowned Screen get_screen (Display disp, int screen_number);
+
+               [CCode (cname = "XBlackPixelOfScreen")]
+               public ulong black_pixel_of_screen ();
+
+               [CCode (cname = "XCellsOfScreen")]
+               public int cells_of_screen ();
+
+               [CCode (cname = "XDefaultColormapOfScreen")]
+               public Colormap default_colormap_of_screen ();
+
+               [CCode (cname = "XDefaultDepthOfScreen")]
+               public int default_depth_of_screen ();
+
+               [CCode (cname = "XDefaultGCOfScreen")]
+               public GC default_gc_of_screen ();
+
+               [CCode (cname = "XDefaultVisualOfScreen")]
+               public Visual default_visual_of_screen ();
+
+               [CCode (cname = "XDisplayOfScreen")]
+               public unowned Display display_of_screen ();
+
+               [CCode (cname = "XDoesBackingStore")]
+               public int does_backing_store ();
+
+               [CCode (cname = "XDoesSaveUnders")]
+               public bool does_save_unders ();
+
+               [CCode (cname = "XEventMaskOfScreen")]
+               public long event_mask_of_Screen ();
+
+               [CCode (cname = "XHeightMMOfScreen")]
+               public int height_in_mm_of_screen ();
+
+               [CCode (cname = "XHeightOfScreen")]
+               public int height_of_screen ();
+
+               [CCode (cname = "XMaxCmapsOfScreen")]
+               public int max_colormaps_of_screen ();
+
+               [CCode (cname = "XMinCmapsOfScreen")]
+               public int min_colormaps_of_screen ();
+
+               [CCode (cname = "XPlanesOfScreen")]
+               public int planes_of_screen ();
+
+               [CCode (cname = "XRootWindowOfScreen")]
+               public Window root_window_of_screen ();
+
+               [CCode (cname = "XScreenNumberOfScreen")]
+               public int screen_number_of_screen ();
+
+               [CCode (cname = "XWhitePixelOfScreen")]
+               public ulong white_pixel_of_screen ();
+
+               [CCode (cname = "XWidthMMOfScreen")]
+               public int width_in_mm_of_screen ();
+
+               [CCode (cname = "XWidthOfScreen")]
+               public int width_of_screen ();
+       }
+
+       public const X.Atom XA_ATOM;
+       public const X.Atom XA_CARDINAL;
+       public const X.Atom XA_WINDOW;
+       public const X.Atom XA_WM_CLASS;
+       public const X.Atom XA_WM_HINTS;
+       public const X.Atom XA_WM_ICON_NAME;
+       public const X.Atom XA_WM_NAME;
+       public const X.Atom XA_WM_NORMAL_HINTS;
+       public const X.Atom XA_WM_TRANSIENT_FOR;
+
+       public const uint XK_Num_Lock;
+       public const uint XK_Scroll_Lock;
+}
+
diff --git a/src/zavai-calendar.vala b/src/zavai-calendar.vala
deleted file mode 100644 (file)
index 5d34139..0000000
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
- * zavai-calendar - simple calendar tool
- *
- * Copyright (C) 2009  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;
-
-//string VERSION = "0.1";
-
-static Posix.pid_t is_running()
-{
-       string pidfile = zavai.config.homedir + "/calendar.pid";
-       string contents;
-       try {
-               if (!FileUtils.get_contents(pidfile, out contents))
-                       return 0;
-       } catch (FileError e) {
-               return 0;
-       }
-       int val = contents.to_int();
-       string procdir = "/proc/%d".printf(val);
-       if (FileUtils.test(procdir, FileTest.IS_DIR))
-               return (Posix.pid_t)val;
-       else
-               return 0;
-}
-
-static void make_pidfile()
-{
-       string pidfile = zavai.config.homedir + "/calendar.pid";
-       FileUtils.set_contents(pidfile, "%d".printf(Posix.getpid()));
-}
-
-static void on_kill(int sig)
-{
-       Gtk.main_quit();
-}
-
-static int main (string[] args) {
-       bool opt_popup = false;
-       GLib.OptionEntry[] entries = new GLib.OptionEntry[] {
-               OptionEntry() {
-                       long_name = "popup",
-                       short_name = 'p',
-                       flags = 0,
-                       arg = OptionArg.NONE,
-                       arg_data = &opt_popup,
-                       description = "run as a popup at the specified location on screen",
-                       arg_description = null },
-               OptionEntry()
-       };
-        Gtk.init_with_args(ref args, "", entries, null);
-
-       // parser = Parser(usage="usage: %prog [options]",
-       //                 version="%prog "+ VERSION,
-       //                 description="Simple interactive interface for the OpenMoko")
-       // parser.add_option("-v", "--verbose", action="store_true", help="verbose mode")
-       // 
-       // (opts, args) = parser.parse_args()
-       // 
-       // if not opts.verbose:
-       //     zavai.set_quiet()
-       // 
-       // # Read configuration
-       // zavai.info("Loading configuration")
-       // conf = zavai.Config()
-
-       // Set up zavai
-
-       // Core infrastructure
-       zavai.config = new zavai.Config();
-
-       // User interface
-       var calendar = new zavai.widgets.Calendar();
-
-       Gtk.Window win = new Gtk.Window(Gtk.WindowType.TOPLEVEL);
-       if (opt_popup)
-       {
-               Posix.pid_t pid = is_running();
-               if (pid != 0)
-               {
-                       // Kill a running calendar
-                       Posix.kill(pid, Posix.SIGINT);
-                       FileUtils.unlink(zavai.config.homedir + "/calendar.pid");
-                       return 0;
-               }
-
-               make_pidfile();
-
-               win.set_decorated(false);
-               //win.set_resizable(false);
-               win.set_border_width(5);
-               win.set_skip_taskbar_hint(true);
-               win.set_skip_pager_hint(true);
-               //    gtk_window_set_type_hint(GTK_WINDOW(win), GDK_WINDOW_TYPE_HINT_DOCK);
-               win.set_position(Gtk.WindowPosition.MOUSE);
-               win.stick();
-       }
-
-       win.title = "Zavai calendar";
-       win.destroy += Gtk.main_quit;
-       win.add(calendar);
-       win.set_size_request(300, 500);
-       win.show_all();
-       win.show();
-
-       // Shutdown the main loop on SIGINT
-       Posix.signal(Posix.SIGINT, on_kill);
-       Posix.signal(Posix.SIGTERM, on_kill);
-
-       Gtk.main();
-
-       calendar.flush();
-
-       return 0;
-}
index d1dede55f8208a3884af2d800873aa3f899bb98e..3b467f0574fce38872c83ff80d8b64609060737a 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * zavai - simple interface to the OpenMoko (or to the FSO stack)
  *
- * Copyright (C) 2009  Enrico Zini <enrico@enricozini.org>
+ * Copyright (C) 2009--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
 using GLib;
 
 //string VERSION = "0.1";
+static string pidfilename;
+
+static Posix.pid_t is_running()
+{
+       string pidfile = zavai.config.homedir + "/" + pidfilename + ".pid";
+       string contents;
+       try {
+               if (!FileUtils.get_contents(pidfile, out contents))
+                       return 0;
+       } catch (FileError e) {
+               return 0;
+       }
+       int val = contents.to_int();
+       string procdir = "/proc/%d".printf(val);
+       if (FileUtils.test(procdir, FileTest.IS_DIR))
+               return (Posix.pid_t)val;
+       else
+               return 0;
+}
+
+static void make_pidfile()
+{
+       string pidfile = zavai.config.homedir + "/" + pidfilename + ".pid";
+       FileUtils.set_contents(pidfile, "%d".printf(Posix.getpid()));
+}
+
+static void on_kill(int sig)
+{
+       Gtk.main_quit();
+}
+
 
 static int main (string[] args) {
-       Gtk.init (ref args);
+       bool opt_popup = false;
+       bool opt_calendar = false;
+       GLib.OptionEntry[] entries = new GLib.OptionEntry[] {
+               OptionEntry() {
+                       long_name = "popup",
+                       short_name = 'p',
+                       flags = 0,
+                       arg = OptionArg.NONE,
+                       arg_data = &opt_popup,
+                       description = "run as a popup at the specified location on screen",
+                       arg_description = null },
+               OptionEntry() {
+                       long_name = "calendar",
+                       short_name = 0,
+                       flags = 0,
+                       arg = OptionArg.NONE,
+                       arg_data = &opt_calendar,
+                       description = "run as calendar only",
+                       arg_description = null },
+               OptionEntry()
+       };
+    Gtk.init_with_args(ref args, "", entries, null);
     Gst.init (ref args);
 
-       // parser = Parser(usage="usage: %prog [options]",
-       //                 version="%prog "+ VERSION,
-       //                 description="Simple interactive interface for the OpenMoko")
-       // parser.add_option("-v", "--verbose", action="store_true", help="verbose mode")
-       // 
-       // (opts, args) = parser.parse_args()
-       // 
+    pidfilename = "zavai";
+
        // if not opts.verbose:
        //     zavai.set_quiet()
-       // 
-       // # Read configuration
-       // zavai.info("Loading configuration")
-       // conf = zavai.Config()
 
        // Set up zavai
 
@@ -89,6 +132,57 @@ static int main (string[] args) {
     // Core infrastructure
        zavai.config = new zavai.Config();
        zavai.config.argv0 = args[0];
+
+    if (opt_calendar)
+    {
+        pidfilename = "calendar";
+
+        // User interface
+        var calendar = new zavai.widgets.Calendar();
+
+        Gtk.Window win = new Gtk.Window(Gtk.WindowType.TOPLEVEL);
+        if (opt_popup)
+        {
+            Posix.pid_t pid = is_running();
+            if (pid != 0)
+            {
+                // Kill a running calendar
+                Posix.kill(pid, Posix.SIGINT);
+                FileUtils.unlink(zavai.config.homedir + "/" + pidfilename + ".pid");
+                return 0;
+            }
+
+            make_pidfile();
+
+            win.set_decorated(false);
+            //win.set_resizable(false);
+            win.set_border_width(5);
+            win.set_skip_taskbar_hint(true);
+            win.set_skip_pager_hint(true);
+            //    gtk_window_set_type_hint(GTK_WINDOW(win), GDK_WINDOW_TYPE_HINT_DOCK);
+            win.set_position(Gtk.WindowPosition.MOUSE);
+            win.stick();
+        }
+
+        win.title = "Zavai calendar";
+        win.destroy += Gtk.main_quit;
+        win.add(calendar);
+        win.set_size_request(300, 500);
+        win.show_all();
+        win.show();
+
+        // Shutdown the main loop on SIGINT
+        Posix.signal(Posix.SIGINT, on_kill);
+        Posix.signal(Posix.SIGTERM, on_kill);
+
+        Gtk.main();
+
+        calendar.flush();
+
+        return 0;
+    }
+
+
        zavai.registry = new zavai.Registry();
 
     zavai.main.init();
index d27624c4dff684301a36a2240bc8d462bf389560..64e95e89c66f91ae7140631a8977adfd80ee9641 100644 (file)
@@ -4,8 +4,8 @@ include(../vala.cmake)
 set(packages gtk+-2.0 dbus-glib-1>=0.80 libwnck-1.0>=2.26.0 lua5.1 libomhacks x11 gdk-x11-2.0 libgps gstreamer-0.10)
 add_packages(ZAVAI ${packages})
 
-set(VALA_PACKAGES ${packages} posix linux-input dbus-extra gtkfisheyelist libzavai)
-set(VFLAGS --vapidir=${gtkfisheyelist_BINARY_DIR} --vapidir=${libzavai_SOURCE_DIR} --vapidir=${libzavai_BINARY_DIR})
+set(VALA_PACKAGES ${packages} posix linux-input dbus-extra gtkfisheyelist)
+set(VFLAGS --vapidir=${gtkfisheyelist_BINARY_DIR} --vapidir=${zavai_SOURCE_DIR} --vapidir=${zavai_BINARY_DIR})
 add_definitions(-Wall)
 # -Werror 
 
@@ -20,11 +20,7 @@ else()
   message("-- Not using devkit-power-gobject")
 endif ()
 
-set(VFLAGS ${VFLAGS} --vapidir=${zavai_BINARY_DIR})
-
-add_definitions(-DWNCK_I_KNOW_THIS_IS_UNSTABLE -DI_KNOW_THE_DEVICEKIT_POWER_API_IS_SUBJECT_TO_CHANGE -I${gtkfisheyelist_BINARY_DIR} -I${zavai_BINARY_DIR} -I${libzavai_BINARY_DIR})
-set(VALA_PACKAGES ${VALA_PACKAGES} libzavai)
-link_libraries(libzavai)
+add_definitions(-DWNCK_I_KNOW_THIS_IS_UNSTABLE -DI_KNOW_THE_DEVICEKIT_POWER_API_IS_SUBJECT_TO_CHANGE -I${gtkfisheyelist_BINARY_DIR} -I${zavai_BINARY_DIR})
 
 file(GLOB gsm-receive test-gsm-receive.vala)
 add_vala_program(test-gsm-receive ${gsm-receive})
diff --git a/zavai/CMakeLists.txt b/zavai/CMakeLists.txt
deleted file mode 100644 (file)
index 76f8252..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-project(libzavai)
-include(../vala.cmake)
-
-set(zavai_version 0.1)
-
-set(packages dbus-glib-1>=0.80 lua5.1 libomhacks x11 gdk-x11-2.0 libgps gstreamer-0.10)
-add_packages(LIBZAVAI ${packages})
-
-set(VALA_PACKAGES ${packages} posix linux-input dbus-extra)
-set(VFLAGS --vapidir=${libzavai_SOURCE_DIR})
-add_definitions(-Wall)
-# -Werror 
-
-pkg_check_modules(DKP devkit-power-gobject>=010)
-if (DKP_VERSION)
-  message("-- Using devkit-power-gobject version ${DKP_VERSION}")
-  set(VFLAGS ${VFLAGS} --define=USE_DKP)
-  set(VALA_PACKAGES ${VALA_PACKAGES} devkit-power-gobject)
-  add_definitions(-DUSE_DKP ${DKP_CFLAGS})
-  link_libraries(${DKP_LDFLAGS})
-else()
-  message("-- Not using devkit-power-gobject")
-endif ()
-
-file(GLOB libvala [a-y]*.vala)
-add_vala_library(libzavai ${libvala})
-add_library(libzavai STATIC ${libzavai_CSOURCES})
-
-set_target_properties(libzavai PROPERTIES VERSION ${zavai_version} SOVERSION 0 OUTPUT_NAME "zavai" CLEAN_DIRECT_OUTPUT 1)
-
-add_definitions(-I${zavai_BINARY_DIR})
-set(VFLAGS ${VFLAGS} --vapidir=${zavai_BINARY_DIR})
diff --git a/zavai/at.vala b/zavai/at.vala
deleted file mode 100644 (file)
index 33cdf27..0000000
+++ /dev/null
@@ -1,164 +0,0 @@
-/*
- * at - at interface
- *
- * Copyright (C) 2009  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 at {
-
-public struct Event
-{
-       int id;
-       time_t deadline;
-}
-
-// Return the earliest ID in the queue, or -1 if none are found
-// Queue is null for all queues, otherwise a queue name
-public static Event earliestID(string? queue = null)
-{
-       Event res = { -1, 0 };
-
-       string argv[4];
-       argv[0] = "/usr/bin/atq";
-       if (queue == null)
-               argv[1] = null;
-       else
-       {
-               argv[1] = "-q";
-               argv[2] = queue;
-               argv[3] = null;
-       }
-
-       Pid pid;
-       int stdout;
-
-       try
-       {
-               if (!Process.spawn_async_with_pipes("/", argv, null, SpawnFlags.STDERR_TO_DEV_NULL, null, out pid, null, out stdout, null))
-                       return res;
-       } catch (SpawnError e) {
-               stderr.printf("Cannot run 'at -q': %s\n", e.message);
-               return res;
-       }
-
-       FileStream fs = FileStream.fdopen(stdout, "r");
-       if (fs == null)
-               return res;
-
-       char buf[200];
-       string? line;
-       while ((line = fs.gets(buf)) != null)
-       {
-               if (!line[0].isdigit()) continue;
-               weak string rest;
-               ulong id = line.to_ulong(out rest, 10);
-               Time t = Time();
-               rest = t.strptime(rest.offset(1), "%a %b %d %H:%M:%S %Y");
-               if (rest == null) continue;
-               if (rest.size() < 2) continue;
-               //stderr.printf("PARSE QUEUE rest %s\n", rest);
-               // Skip the queue of tasks currently being executed
-               //if (rest[1] == '=') continue;
-               // Skip entries not in the wanted queue
-               if (queue != null && rest[1] != queue[0]) continue;
-               time_t tt = t.mktime();
-               if (res.deadline == 0 || tt < res.deadline) {
-                       res.id = (int)id;
-                       res.deadline = tt;
-               }
-       }
-       Process.close_pid(pid);
-       return res;
-}
-
-public delegate bool jobParser(int fd);
-
-// Get the contents of a job given its id
-public static bool jobContents(int id, jobParser parser)
-{
-       string argv[4];
-       argv[0] = "/usr/bin/at";
-       argv[1] = "-c";
-       argv[2] = id.to_string();
-       argv[3] = null;
-
-       Pid pid;
-       int stdoutfd;
-
-       try
-       {
-               if (!Process.spawn_async_with_pipes("/", argv, null, SpawnFlags.STDERR_TO_DEV_NULL, null, out pid, null, out stdoutfd, null))
-                       return false;
-       } catch (SpawnError e) {
-               stderr.printf("Cannot run 'at -c': %s\n", e.message);
-               return false;
-       }
-
-       bool res = parser(stdoutfd);
-
-       Process.close_pid(pid);
-
-       return res;
-}
-
-/*
-TODO: schedule alarms via at
-
-Uses the 'z' queue.
-
-atq -q z  can be used to list the jobs (for example, at startup, or after a job has run)
-at -c id  can be used to query a job, parsing its contents (which can have
-          comments or variables being set)
-zavai --notify ...  can be used to notify the job (and start zavai if it's not running)
-
-Alarm needs to be able to serialize itself to an at invocation and to
-deserialize itself from the output of at -c
-
-Alarm needs to deserialize also a job with no special markers whatsoever: a
-generic at job.
-*/
-
-
-/*
-public class Alarm : Object
-{
-       // TODO: make a factory method to construct from an "at -c" output
-
-       // TODO: make a method that provides an at invocation
-
-       public signal void trigger(Alarm a);
-
-       public time_t deadline;
-       public string label;
-
-       public Alarm(time_t deadline, string label)
-       {
-               this.deadline = deadline;
-               this.label = label;
-       }
-}
-*/
-
-       // Schedule a task that notifies a string
-       // TODO public void schedule_label(const Alarm a);
-
-       // Return the next item in the queue due to be run
-       // TODO public Alarm? next_scheduled();
-
-}
diff --git a/zavai/audio.vala b/zavai/audio.vala
deleted file mode 100644 (file)
index 1c39420..0000000
+++ /dev/null
@@ -1,225 +0,0 @@
-/*
- * audio - audio resource for zavai
- *
- * Copyright (C) 2009--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 audio {
-
-public class Audio: zavai.Service
-{
-    protected Omhacks.Led vibrator;
-    protected bool has_vibrator;
-
-    /*
-       protected dynamic DBus.Object audiodev;
-       protected dynamic DBus.Object vibdev;
-   */
-
-    public Audio()
-    {
-        Object(name: "audio");
-
-        has_vibrator = (vibrator.init("neo1973:vibrator") == 0);
-
-/*
-        audiodev = zavai.registry.sbus.get_object(
-                "org.freesmartphone.odeviced",
-                "/org/freesmartphone/Device/Audio",
-                "org.freesmartphone.Device.Audio");
-        vibdev = 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)
-    {
-        zavai.log.debug("Make noise for alarm");
-        if (has_vibrator)
-        {
-            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)
-            {
-                vibrator.trigger[i] = (char)trig[i];
-                if (trig[i] == 0) break;
-            }
-            vibrator.delay_on = 200;
-            vibrator.delay_off = 300;
-            vibrator.set();
-        }
-        soundplayer.play(config.ringtone_alarm, true);
-    }
-
-    public void on_alarm_done(clock.AlarmTriggerInfo info)
-    {
-        zavai.log.debug("Stop noise for alarm");
-        if (has_vibrator)
-        {
-            var trig = "none";
-            for (int i = 0; ; ++i)
-            {
-                vibrator.trigger[i] = (char)trig[i];
-                if (trig[i] == 0) break;
-            }
-            vibrator.brightness = 0;
-            vibrator.set();
-        }
-        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);
-        }
-        // TODO: play music?
-    }
-*/
-}
-
-public class Player: zavai.Resource, Object
-{
-    protected Gst.Element player;
-    protected bool playing;
-    protected Player slave;
-    protected Player master;
-    protected bool loop;
-    protected string uri;
-    public signal void state_changed(Gst.State new_state);
-
-    public Player()
-    {
-        slave = null;
-        master = null;
-        player = Gst.ElementFactory.make("playbin", null);
-        playing = false;
-        loop = false;
-        var bus = player.get_bus();
-        bus.add_signal_watch();
-        bus.message += on_message;
-    }
-
-    public void set_slave(Player player)
-    {
-        slave = player;
-        slave.master = this;
-    }
-
-    public void play(string uri, bool loop = false)
-    {
-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;
-    }
-
-    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;
-    }
-
-    public void pause()
-    {
-        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);
-    }
-
-    public void restart()
-    {
-        player.seek_simple(Gst.Format.TIME, Gst.SeekFlags.FLUSH | Gst.SeekFlags.KEY_UNIT, 0);
-        player.set_state(Gst.State.PLAYING);
-        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();
-        }
-    }
-
-    public void shutdown()
-    {
-        stop();
-    }
-}
-
-public Audio audio = null;
-public Player musicplayer = null;
-public Player soundplayer = null;
-
-public void init()
-{
-    audio = new Audio();
-    musicplayer = new Player();
-    soundplayer = new Player();
-    soundplayer.set_slave(musicplayer);
-    zavai.registry.register(musicplayer);
-    zavai.registry.register(soundplayer);
-}
-
-}
-}
diff --git a/zavai/bluetooth.vala b/zavai/bluetooth.vala
deleted file mode 100644 (file)
index 0103d0f..0000000
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * bluetooth - bluetooth resource for zavai
- *
- * 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 bluetooth {
-
-public class Bluetooth: zavai.ScriptService
-{
-    public Bluetooth()
-    {
-        Object(name: "bluetooth");
-        started = script_status();
-    }
-
-    /// Start Bluetooth
-    public override void start()
-    {
-        if (started) return;
-        if (!script_start()) return;
-        zavai.log.info("bluetooth turned on");
-        base.start();
-    }
-
-    // Release usage of GPS
-    public override void stop()
-    {
-        if (!started) return;
-        script_stop();
-        base.stop();
-    }
-}
-
-public Bluetooth bluetooth = null;
-
-public void init()
-{
-    bluetooth = new Bluetooth();
-
-}
-
-}
-}
diff --git a/zavai/clock.vala b/zavai/clock.vala
deleted file mode 100644 (file)
index d08717b..0000000
+++ /dev/null
@@ -1,357 +0,0 @@
-/*
- * clock - clock resource for zavai
- *
- * Copyright (C) 2009--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 clock {
-
-public enum SourceType
-{
-    SYSTEM,
-    GPS
-}
-
-/*
-TODO: schedule alarms via at
-
-Uses the 'z' queue.
-
-atq -q z  can be used to list the jobs (for example, at startup, or after a job has run)
-at -c id  can be used to query a job, parsing its contents (which can have
-          comments or variables being set)
-zavai --notify ...  can be used to notify the job (and start zavai if it's not running)
-
-Alarm needs to be able to serialize itself to an at invocation and to
-deserialize itself from the output of at -c
-
-Alarm needs to deserialize also a job with no special markers whatsoever: a
-generic at job.
-
-
-
-refresh_alarms()
-{
-    oldtime = next_alarm ? next_alarm.time : 0
-    next_alarm = the first alarm from atq
-    if (oldtime != next_alarm.time)
-    {
-        remove existing triggers
-          (triggers can be skipped if we don't need to support non-zavai alarms)
-        schedule a trigger calling refresh_alarms() at next_alarm.time + 30 seconds
-          (triggers can be skipped if we don't need to support non-zavai alarms)
-    }
-}
-
-at clock constructor: refresh_alarms()
-inotifywait -e close /usr/bin/at -> refresh_alarms()  (shows when someone has just used at)
-  (can be skipped if we don't need to support non-zavai alarms)
-at alarm triggered through zavai: refresh_alarms()
-
-
-*/
-
-
-public class Alarm : Object
-{
-    public at.Event ev;
-    public string label;
-
-    // Schedule with at
-    public static void schedule(string timespec, string label) throws Error
-    {
-        string argv[5];
-        argv[0] = "/usr/bin/at";
-        argv[1] = "-q";
-        argv[2] = "z";
-        argv[3] = timespec;
-        argv[4] = null;
-
-        Pid pid;
-        int stdinfd;
-
-        if (!Process.spawn_async_with_pipes("/", argv, null, SpawnFlags.STDERR_TO_DEV_NULL, null, out pid, out stdinfd, null, null))
-            return;
-
-        {
-            FileStream fs = FileStream.fdopen(stdinfd, "w");
-            string display = GLib.Environment.get_variable("DISPLAY");
-            if (display != null)
-                fs.printf("DISPLAY=\"%s\"; export DISPLAY\n", display);
-            fs.printf("# Zavai variables start here\n");
-            fs.printf("ZAVAI_LABEL=\"%s\"\n", label.escape(""));
-            fs.printf("# Zavai commands starts here\n");
-            fs.printf("%s notify \"$ZAVAI_LABEL\"", zavai.config.argv0);
-        }
-        
-        Process.close_pid(pid);
-    }
-
-    // Get the label of the job with the given at ID
-    public static string? getLabel(int atID)
-    {
-        string label = null;
-        at.jobContents(atID, fd => {
-            FileStream fs = FileStream.fdopen(fd, "r");
-            while (true)
-            {
-                string? line = fs.read_line();
-                if (line == null) break;
-                if (line.has_prefix("ZAVAI_LABEL=\""))
-                {
-                    size_t size = line.size();
-                    if (size < 15) continue;
-                    label = line.substring(13, (long)(size - 14));
-                    label = label.compress();
-                    break;
-                }
-            }
-            return true;
-        });
-        return label;
-    }
-}
-
-[DBus (name = "org.enricozini.zavai.Alarm")]
-public class ZavaiClock : Object {
-    public void Notify (string label) {
-        clock.notify_alarm(label);
-    }
-}
-
-public class AlarmTriggerInfo
-{
-    public uint id;
-    public string label;
-    public bool acked;
-    public bool canceled;
-
-    public AlarmTriggerInfo(string label)
-    {
-        id = 0;
-        this.label = label;
-        acked = false;
-        canceled = false;
-    }
-}
-
-public class AlarmTriggerQueue : zavai.Service
-{
-    protected List<AlarmTriggerInfo> queue;
-
-    public signal void triggered(AlarmTriggerInfo info);
-    public signal void acked(AlarmTriggerInfo info);
-    public signal void canceled(AlarmTriggerInfo info);
-
-    public AlarmTriggerQueue()
-    {
-        queue = new List<AlarmTriggerInfo>();
-    }
-
-    public uint enqueue_trigger(AlarmTriggerInfo info)
-    {
-        // Reuse IDs from the associated logger object
-        info.id = zavai.log.log.start("alarm", "Alarm " + info.label);
-        queue.append(info);
-        if (queue.data.id == info.id)
-            triggered(queue.data);
-        return info.id;
-    }
-
-    protected void done_with_first()
-    {
-        var first = queue.data;
-        queue.remove_link(queue);
-        if (queue != null)
-            triggered(queue.data);
-    }
-
-    public void ack(AlarmTriggerInfo info)
-    {
-        if (queue == null || info.id != queue.data.id) return;
-        if (!info.acked && !info.canceled)
-        {
-            info.acked = true;
-            acked(info);
-            zavai.log.log.add(info.id, "alarm acknowledged");
-            zavai.log.log.end(info.id);
-        }
-        done_with_first();
-    }
-
-    public void cancel(AlarmTriggerInfo info)
-    {
-        if (queue == null || info.id != queue.data.id) return;
-        if (!info.acked && !info.canceled)
-        {
-            info.canceled = true;
-            canceled(info);
-            zavai.log.log.add(info.id, "alarm canceled");
-            zavai.log.log.end(info.id);
-        }
-        done_with_first();
-    }
-}
-
-public class Clock: zavai.Service
-{
-    protected time_t last_gps_time;
-    protected time_t last_gps_time_system_time;
-    protected time_t last_system_time;
-    protected uint system_time_timeout;
-    protected time_t last_minute;
-    protected time_t chosen_time;
-    protected SourceType chosen_type;
-    protected ZavaiClock dbusClock;
-
-    protected dynamic DBus.Object otimed_alarm;
-    protected dynamic DBus.Object rtc;
-    protected SList<Alarm> alarms;
-
-    // Ticks once a minute
-    public signal void minute_changed(long time, SourceType source);
-    public signal void schedule_changed(Alarm? next);
-
-    public Clock()
-    {
-        Object(name: "clock");
-        alarms = null;
-        dbusClock = new ZavaiClock();
-        last_minute = 0;
-        last_gps_time = 0;
-        last_gps_time_system_time = 0;
-        last_system_time = time_t();
-        chosen_time = last_system_time;
-
-        // FSO alarm system
-        otimed_alarm = zavai.registry.sbus.get_object(
-                "org.freesmartphone.otimed",
-                "/org/freesmartphone/Time/Alarm",
-                "org.freesmartphone.Time.Alarm");
-
-        rtc = zavai.registry.sbus.get_object(
-                "org.freesmartphone.odeviced",
-                "/org/freesmartphone/Device/RTC/0",
-                "org.freesmartphone.Device.RealtimeClock");
-
-        zavai.registry.sbus.register_object("/org/enricozini/Zavai/Clock", dbusClock);
-    }
-
-    public void notify_alarm(string label)
-    {
-        stderr.printf("Notifying %s\n", label);
-        AlarmTriggerInfo info = new AlarmTriggerInfo(label);
-        alarm_trigger_queue.enqueue_trigger(info);
-        schedule_changed(next_alarm());
-    }
-
-    public Alarm? next_alarm()
-    {
-        at.Event ev;
-        ev = at.earliestID("z");
-        if (ev.deadline == 0)
-            return null;
-        string label = Alarm.getLabel(ev.id);
-        Alarm res = new Alarm();
-        res.ev = ev;
-        res.label = label;
-        return res;
-    }
-
-    public void schedule(string timespec, string label) throws Error
-    {
-        Alarm.schedule(timespec, label);
-        schedule_changed(next_alarm());
-    }
-
-    private void on_gps_time(uint t)
-    {
-        if (t == 0)
-        {
-            last_gps_time_system_time = 0;
-            update_time();
-        } else {
-            last_gps_time = (time_t)t;
-            last_gps_time_system_time = time_t();
-            update_time();
-        }
-    }
-
-    private bool on_system_time()
-    {
-        last_system_time = time_t();
-        update_time();
-        return true;
-    }
-
-    private void update_time()
-    {
-        if (last_gps_time_system_time + 10 > last_system_time)
-        {
-            chosen_time = last_gps_time;
-            chosen_type = SourceType.GPS;
-        }
-        else
-        {
-            chosen_time = last_system_time;
-            chosen_type = SourceType.SYSTEM;
-        }
-        if (chosen_time / 60 != last_minute)
-        {
-            last_minute = chosen_time / 60;
-            minute_changed(chosen_time, chosen_type);
-        }
-    }
-
-    /// Request GPS resource
-    public override void start()
-    {
-        if (started) return;
-
-        system_time_timeout = Timeout.add(5000, on_system_time);
-        zavai.gps.gps.time_changed += on_gps_time;
-        last_system_time = time_t();
-        update_time();
-
-        base.start();
-    }
-
-    public override void stop()
-    {
-        if (!started) return;
-
-        Source.remove(system_time_timeout);
-        zavai.gps.gps.time_changed -= on_gps_time;
-
-        base.stop();
-    }
-}
-
-public Clock clock = null;
-public AlarmTriggerQueue alarm_trigger_queue = null;
-
-public void init()
-{
-    clock = new Clock();
-    alarm_trigger_queue = new AlarmTriggerQueue();
-}
-
-}
-}
diff --git a/zavai/config.vala b/zavai/config.vala
deleted file mode 100644 (file)
index 444bbc2..0000000
+++ /dev/null
@@ -1,265 +0,0 @@
-/*
- * config - zavai configuration
- *
- * Copyright (C) 2009--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
- */
-
-namespace zavai {
-
-public class Config
-{
-    protected Lua.LuaVM lua;
-    protected weak string get_string(string name)
-    {
-        lua.get_global(name);
-        weak string res = lua.to_string(-1);
-        lua.pop(1);
-        return res;
-    }
-    protected string set_string(string name, string? val)
-    {
-        if (val == null)
-            lua.push_nil();
-        else
-            lua.push_string(val);
-        lua.set_global(name);
-        return val;
-    }
-    protected weak int get_int(string name)
-    {
-        lua.get_global(name);
-        int res = lua.to_integer(-1);
-        lua.pop(1);
-        return res;
-    }
-    protected int set_int(string name, int val)
-    {
-        lua.push_integer(val);
-        lua.set_global(name);
-        return val;
-    }
-
-    private string _version;
-    public string version
-    {
-        get { return _version; }
-        set { _version = set_string("version", value); }
-    }
-
-    // "phone" or "laptop"
-    private string _profile;
-    public string profile
-    {
-        get { return _profile; }
-        set { _profile = set_string("profile", value); }
-    }
-
-    private string _homedir;
-    public string homedir
-    {
-        get { return _homedir; }
-        set { _homedir = set_string("homedir", value); }
-    }
-
-    private string _icondir;
-    public string icondir
-    {
-        get { return _icondir; }
-        set { _icondir = set_string("icondir", value); }
-    }
-
-    private int _min_button_height;
-    public int min_button_height
-    {
-        get { return _min_button_height; }
-        set { _min_button_height = set_int("min_button_height", value); }
-    }
-
-    private string _gpsd_host;
-    public string gpsd_host
-    {
-        get { return _gpsd_host; }
-        set { _gpsd_host = set_string("gpsd_host", value); }
-    }
-
-    private string _gpsd_port;
-    public string gpsd_port
-    {
-        get { return _gpsd_port; }
-        set { _gpsd_port = set_string("gpsd_port", value); }
-    }
-
-    private string _gprs_apn;
-    public string gprs_apn
-    {
-        get { return _gprs_apn; }
-        set { _gprs_apn = set_string("gprs_apn", value); }
-    }
-
-    private string _gprs_user;
-    public string gprs_user
-    {
-        get { return _gprs_user; }
-        set { _gprs_user = set_string("gprs_user", value); }
-    }
-
-    private string _gprs_pass;
-    public string gprs_pass
-    {
-        get { return _gprs_pass; }
-        set { _gprs_pass = set_string("gprs_pass", value); }
-    }
-
-    private string _sim_pin;
-    public string sim_pin
-    {
-        get { return _sim_pin; }
-        set { _sim_pin = set_string("sim_pin", value); }
-    }
-
-    private int _power_button_keycode;
-    public int power_button_keycode
-    {
-        get { return _power_button_keycode; }
-        set { _power_button_keycode = set_int("power_button_keycode", value); }
-    }
-
-    private int _aux_button_keycode;
-    public int aux_button_keycode
-    {
-        get { return _aux_button_keycode; }
-        set { _aux_button_keycode = set_int("aux_button_keycode", value); }
-    }
-
-    private string _ringtone_alarm;
-    public string ringtone_alarm
-    {
-        get { return _ringtone_alarm; }
-        set { _ringtone_alarm = set_string("ringtone_alarm", value); }
-    }
-
-    public int backlight_max
-    {
-        get;
-        set;
-    }
-
-    private string _argv0;
-    public string argv0 {
-        get { return _argv0; }
-        set {
-            if (value.chr(-1, '/') != null)
-            {
-                if (Path.is_absolute(value))
-                {
-                    _argv0 = value;
-                } else {
-                    _argv0 = Path.build_filename(Environment.get_current_dir(), value, null);
-                }
-            } else {
-                _argv0 = Environment.find_program_in_path(value);
-            }
-            zavai.log.debug("ARGV0: " + _argv0);
-        }
-    }
-
-    /// Reread config values from the Lua VM, to be run after running Lua code
-    protected void refresh_from_lua()
-    {
-        _version = get_string("version");
-        _profile = get_string("profile");
-        _homedir = get_string("homedir");
-        _icondir = get_string("icondir");
-        _min_button_height = get_int("min_button_height");
-        _gpsd_host = get_string("gpsd_host");
-        _gpsd_port = get_string("gpsd_port");
-        _gprs_apn = get_string("gprs_apn");
-        _gprs_user = get_string("gprs_user");
-        _gprs_pass = get_string("gprs_pass");
-        _sim_pin = get_string("sim_pin");
-        _power_button_keycode = get_int("power_button_keycode");
-        _aux_button_keycode = get_int("aux_button_keycode");
-        _ringtone_alarm = get_string("ringtone_alarm");
-    }
-
-    public Config()
-    {
-        lua = new Lua.LuaVM();
-        lua.open_libs();
-
-        // Set defaults
-        version = "0.1";
-        profile = "phone";
-        homedir = GLib.Environment.get_home_dir() + "/.zavai";
-        icondir = GLib.Environment.get_variable("ZAVAI_ICONDIR");
-        if (icondir == null)
-                icondir = "/usr/share/zavai/icons";
-        min_button_height = 80;
-        gpsd_host = "localhost";
-        gpsd_port = "gpsd";
-        gprs_apn = "general.t-mobile.uk";
-        gprs_user = "x";
-        gprs_pass = "x";
-        sim_pin = "1234";
-        backlight_max = 15;
-        power_button_keycode = 124;
-        aux_button_keycode = 177;
-        ringtone_alarm = "file:///usr/share/sounds/yue-fso/lec1.ogg";
-
-        // Read config
-        if (lua.do_file(homedir + "/config"))
-        {
-            zavai.log.error("Failed to parse " + homedir + "/config: " + lua.to_string(-1));
-        }
-        refresh_from_lua();
-    }
-
-    public void run_script(string command)
-    {
-        zavai.log.info("Run program: " + command);
-        string[] args = command.split(" ");
-        Pid pid;
-        try {
-            Process.spawn_async(
-                Environment.get_home_dir(),
-                args,
-                null,
-                SpawnFlags.SEARCH_PATH,
-                null,
-                out pid);
-        } catch (SpawnError e) {
-            zavai.log.error("Running " + command + ": " + e.message);
-        }
-    }
-
-    public int run_script_sync(string command, out string std_out, out string std_err)
-    {
-        int status = -1;
-        zavai.log.info("Run program: " + command);
-        string[] args = command.split(" ");
-        try {
-            bool res = Process.spawn_sync(Environment.get_home_dir(), args, null, SpawnFlags.SEARCH_PATH, null, out std_out, out std_err, out status);
-        } catch (SpawnError e) {
-            zavai.log.error("Running " + command + ": " + e.message);
-        }
-        return status;
-    }
-}
-
-public Config config = null;
-
-}
diff --git a/zavai/core.vala b/zavai/core.vala
deleted file mode 100644 (file)
index 3c31ccd..0000000
+++ /dev/null
@@ -1,279 +0,0 @@
-/*
- * app - zavai main window
- *
- * Copyright (C) 2009  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 {
-
-public interface Resource : Object {
-    /**
-     * Shut down this resource.
-     *
-     * Normally one does nothing here, but it is important to give resources a
-     * chance to do cleanup when the program quits.
-     * 
-     * This can be used for tasks like closing the tags on a GPX track,
-     * releasing a FSO resource, restoring mixer settings and so on.
-     */
-    public abstract void shutdown();
-}
-
-public abstract class Service : Object, Resource {
-    public string name { get; construct; }
-
-    bool _started;
-    public bool started {
-        get { return _started; }
-        set { _started = value; }
-    }
-
-    public signal void toggled(bool new_state);
-
-    protected class Request
-    {
-        public string requestor;
-        public int count;
-        public Request(string requestor)
-        {
-            this.requestor = requestor;
-            count = 1;
-        }
-    }
-
-    protected List<Request> requests;
-
-    construct
-    {
-        started = false;
-        requests = null;
-        zavai.registry.register(this);
-    }
-
-    public void shutdown()
-    {
-        stop();
-    }
-
-    /// Activate the service
-    protected virtual void start()
-    {
-        if (!started)
-        {
-            zavai.log.info("Service " + name + " started\n");
-            started = true;
-            toggled(started);
-        }
-    }
-
-    /// Deactivate the service
-    protected virtual void stop()
-    {
-        if (started)
-        {
-            zavai.log.info("Service " + name + " stopped\n");
-            started = false;
-            toggled(started);
-        }
-    }
-
-    /**
-      Request a resource using the given ID.
-     *
-     * If it is the first time the resource is requested, start it and
-     * return true. Else, take note of the request and return false.
-     *
-     * If a resource is requested multiple times with the same ID, it will
-     * need to be released multiple times with that ID.
-     */
-    public bool request(string id)
-    {
-        bool res = (requests == null);
-        bool got = false;
-        for (weak List<Request> i = requests; i != null; i = i.next)
-            if (i.data.requestor == id)
-            {
-                ++i.data.count;
-                got = true;
-                break;
-            }
-        if (!got)
-            requests.prepend(new Request(id));
-        if (res) start();
-        return res;
-    }
-
-    /**
-     * Release a resource using the given ID.
-     *
-     * If after the call nothing is requesting the resource, stop it and
-     * return true. Else, take note of the release and return false.
-     *
-     * If a resource is requested multiple times with the same ID, it will
-     * need to be released multiple times with that ID.
-     */
-    public bool release(string id)
-    {
-        weak List<Request> el = null;
-        for (weak List<Request> i = requests; i != null; i = i.next)
-            if (i.data.requestor == id)
-            {
-                el = i;
-                break;
-            }
-
-        if (el == null)
-            return false;
-
-        requests.delete_link(el);
-
-        if (requests != null)
-            return false;
-
-        stop();
-        return true;
-    }
-}
-
-public abstract class ScriptService : Service
-{
-    protected bool script_start()
-    {
-        try {
-            // Then run our own script
-            zavai.config.run_script(zavai.config.homedir + "/" + name + " start");
-            return true;
-        } catch (Error e) {
-            zavai.log.error("Running " + zavai.config.homedir + "/" + name + " start: " + e.message);
-            return false;
-        }
-    }
-
-    protected bool script_stop()
-    {
-        try {
-            // Then run our own script
-            zavai.config.run_script(zavai.config.homedir + "/" + name + " stop");
-            return true;
-        } catch (Error e) {
-            zavai.log.error("Running " + zavai.config.homedir + "/" + name + " stop: " + e.message);
-            return false;
-        }
-    }
-
-    protected bool script_status()
-    {
-        string std_out;
-        string std_err;
-        string command = zavai.config.homedir + "/" + name + " status";
-        int res = zavai.config.run_script_sync(command, out std_out, out std_err);
-        if (res != 0)
-        {
-            zavai.log.error("Running " + command + ": " + std_err);
-            return false;
-        }
-
-        std_out._strip();
-
-        return (std_out == "on");
-    }
-}
-
-public abstract class ScriptMonitorService : Service
-{
-    protected Pid child_pid;
-    protected int child_watch_id;
-
-    ScriptMonitorService()
-    {
-        child_pid = 0;
-        child_watch_id = 0;
-    }
-
-    protected bool script_start()
-    {
-        string command = zavai.config.homedir + "/" + name + " pre";
-        try {
-            // Then run our own script
-            zavai.config.run_script(command);
-        } catch (Error e) {
-            zavai.log.error("Running " + command + ": " + e.message);
-            return false;
-        }
-
-        command = zavai.config.homedir + "/" + name + " run";
-        zavai.log.info("Run program: " + command);
-        string[] args = command.split(" ");
-        try {
-            Process.spawn_async(
-                Environment.get_home_dir(),
-                args,
-                null,
-                SpawnFlags.SEARCH_PATH | SpawnFlags.DO_NOT_REAP_CHILD,
-                null,
-                out child_pid);
-        } catch (SpawnError e) {
-            zavai.log.error("Running " + command + ": " + e.message);
-            return false;
-        }
-
-        // Add a child watch source to know when it ends
-        ChildWatch.add(child_pid, on_child);
-
-        return true;
-    }
-
-    protected bool script_stop()
-    {
-        Posix.kill((Posix.pid_t)child_pid, Posix.SIGTERM);
-        return true;
-    }
-
-    protected void on_child(Pid pid, int status)
-    {
-        zavai.log.info("Exited");
-stderr.printf("STATUS %d\n", status);
-        Process.close_pid(pid);
-
-        string command = zavai.config.homedir + "/" + name + " post";
-        try {
-            // Then run our own script
-            zavai.config.run_script(command);
-        } catch (Error e) {
-            zavai.log.error("Running " + command + ": " + e.message);
-            return;
-        }
-
-        cleanup_after_script_stop();
-
-        base.stop();
-    }
-
-    protected virtual void cleanup_after_script_stop()
-    {
-    }
-
-    /*
-    protected bool script_status()
-    {
-    }
-    */
-}
-
-}
diff --git a/zavai/dbus-extra.vapi b/zavai/dbus-extra.vapi
deleted file mode 100644 (file)
index 5213899..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-namespace DBus {
-       [CCode (cname = "dbus_bus_get_unique_name")]
-       public unowned string bus_get_unique_name (DBus.RawConnection conn);
-}
-
diff --git a/zavai/devkit-power-gobject.vapi b/zavai/devkit-power-gobject.vapi
deleted file mode 100644 (file)
index 139abc2..0000000
+++ /dev/null
@@ -1,232 +0,0 @@
-/* devkit-power-gobject.vapi generated by vapigen, do not modify. */
-
-[CCode (cprefix = "Dkp", lower_case_cprefix = "dkp_")]
-namespace Dkp {
-       [CCode (cheader_filename = "devkit-power-gobject/devicekit-power.h")]
-       public class Client : GLib.Object {
-               [CCode (has_construct_function = false)]
-               public Client ();
-               public unowned GLib.PtrArray enumerate_devices () throws GLib.Error;
-               [CCode (cname = "dkp_client_can_hibernate")]
-               public bool get_can_hibernate ();
-               [CCode (cname = "dkp_client_can_suspend")]
-               public bool get_can_suspend ();
-               public unowned string get_daemon_version ();
-               [CCode (cname = "dkp_client_lid_is_closed")]
-               public bool get_lid_is_closed ();
-               [CCode (cname = "dkp_client_on_battery")]
-               public bool get_on_battery ();
-               [CCode (cname = "dkp_client_on_low_battery")]
-               public bool get_on_low_battery ();
-               public bool hibernate () throws GLib.Error;
-               public bool suspend () throws GLib.Error;
-               [NoAccessorMethod]
-               public bool can_hibernate { get; }
-               [NoAccessorMethod]
-               public bool can_suspend { get; }
-               public string daemon_version { get; }
-               [NoAccessorMethod]
-               public bool lid_is_closed { get; }
-               [NoAccessorMethod]
-               public bool lid_is_present { get; }
-               [NoAccessorMethod]
-               public bool on_battery { get; }
-               [NoAccessorMethod]
-               public bool on_low_battery { get; }
-               public virtual signal void changed ();
-               public virtual signal void device_added (void* device);
-               public virtual signal void device_changed (void* device);
-               public virtual signal void device_removed (void* device);
-       }
-       [CCode (cheader_filename = "devkit-power-gobject/devicekit-power.h")]
-       public class Device : GLib.Object {
-               [CCode (has_construct_function = false)]
-               public Device ();
-               public unowned GLib.PtrArray get_history (string type, uint timespec, uint resolution) throws GLib.Error;
-               public unowned string get_object_path ();
-               public unowned GLib.PtrArray get_statistics (string type) throws GLib.Error;
-               public bool print ();
-               public bool refresh () throws GLib.Error;
-               public bool set_object_path (string object_path) throws GLib.Error;
-               public static Dkp.DeviceState state_from_text (string state);
-               public static unowned string state_to_text (Dkp.DeviceState state_enum);
-               public static Dkp.DeviceTechnology technology_from_text (string technology);
-               public static unowned string technology_to_text (Dkp.DeviceTechnology technology_enum);
-               public static Dkp.DeviceType type_from_text (string type);
-               public static unowned string type_to_text (Dkp.DeviceType type_enum);
-               [NoAccessorMethod]
-               public double capacity { get; set; }
-               [NoAccessorMethod]
-               public double energy { get; set; }
-               [NoAccessorMethod]
-               public double energy_empty { get; set; }
-               [NoAccessorMethod]
-               public double energy_full { get; set; }
-               [NoAccessorMethod]
-               public double energy_full_design { get; set; }
-               [NoAccessorMethod]
-               public double energy_rate { get; set; }
-               [NoAccessorMethod]
-               public bool has_history { get; set; }
-               [NoAccessorMethod]
-               public bool has_statistics { get; set; }
-               [NoAccessorMethod]
-               public bool is_present { get; set; }
-               [NoAccessorMethod]
-               public bool is_rechargeable { get; set; }
-               [NoAccessorMethod]
-               public string model { owned get; set; }
-               [NoAccessorMethod]
-               public string native_path { owned get; set; }
-               [NoAccessorMethod]
-               public bool online { get; set; }
-               [NoAccessorMethod]
-               public double percentage { get; set; }
-               [NoAccessorMethod]
-               public bool power_supply { get; set; }
-               [NoAccessorMethod]
-               public bool recall_notice { get; set; }
-               [NoAccessorMethod]
-               public string recall_url { owned get; set; }
-               [NoAccessorMethod]
-               public string recall_vendor { owned get; set; }
-               [NoAccessorMethod]
-               public string serial { owned get; set; }
-               [NoAccessorMethod]
-               public uint state { get; set; }
-               [NoAccessorMethod]
-               public uint technology { get; set; }
-               [NoAccessorMethod]
-               public int64 time_to_empty { get; set; }
-               [NoAccessorMethod]
-               public int64 time_to_full { get; set; }
-               [NoAccessorMethod]
-               public uint type { get; set; }
-               [NoAccessorMethod]
-               public uint64 update_time { get; set; }
-               [NoAccessorMethod]
-               public string vendor { owned get; set; }
-               [NoAccessorMethod]
-               public double voltage { get; set; }
-               public virtual signal void changed (void* obj);
-       }
-       [Compact]
-       [CCode (copy_function = "dkp_history_obj_copy", cheader_filename = "devkit-power-gobject/devicekit-power.h")]
-       public class HistoryObj {
-               public Dkp.DeviceState state;
-               public uint time;
-               public double value;
-               [CCode (has_construct_function = false)]
-               public HistoryObj ();
-               public bool clear ();
-               public unowned Dkp.HistoryObj copy ();
-               public static unowned Dkp.HistoryObj create (double value, Dkp.DeviceState state);
-               public bool equal (Dkp.HistoryObj obj2);
-               public static unowned Dkp.HistoryObj from_string (string text);
-               public bool print ();
-               public unowned string to_string ();
-       }
-       [Compact]
-       [CCode (copy_function = "dkp_qos_obj_copy", cheader_filename = "devkit-power-gobject/devicekit-power.h")]
-       public class QosObj {
-               public weak string cmdline;
-               public uint cookie;
-               public bool persistent;
-               public uint pid;
-               public weak string sender;
-               public uint64 timespec;
-               public Dkp.QosType type;
-               public uint uid;
-               public int value;
-               [CCode (has_construct_function = false)]
-               public QosObj ();
-               public unowned Dkp.QosObj copy ();
-               public bool equal (Dkp.QosObj obj2);
-               public bool print ();
-       }
-       [Compact]
-       [CCode (copy_function = "dkp_stats_obj_copy", cheader_filename = "devkit-power-gobject/devicekit-power.h")]
-       public class StatsObj {
-               public double accuracy;
-               public double value;
-               [CCode (has_construct_function = false)]
-               public StatsObj ();
-               public unowned Dkp.StatsObj copy ();
-               public static unowned Dkp.StatsObj create (double value, double accuracy);
-               public static unowned Dkp.StatsObj from_string (string text);
-               public unowned string to_string ();
-       }
-       [CCode (cheader_filename = "devkit-power-gobject/devicekit-power.h")]
-       public class Wakeups : GLib.Object {
-               [CCode (has_construct_function = false)]
-               public Wakeups ();
-               public unowned GLib.PtrArray get_data () throws GLib.Error;
-               public uint get_total () throws GLib.Error;
-               public bool has_capability ();
-               public virtual signal void data_changed ();
-               public virtual signal void total_changed (uint value);
-       }
-       [Compact]
-       [CCode (copy_function = "dkp_wakeups_obj_copy", cheader_filename = "devkit-power-gobject/devicekit-power.h")]
-       public class WakeupsObj {
-               public weak string cmdline;
-               public weak string details;
-               public uint id;
-               public bool is_userspace;
-               public uint old;
-               public float value;
-               [CCode (has_construct_function = false)]
-               public WakeupsObj ();
-               public unowned Dkp.WakeupsObj copy ();
-               public bool equal (Dkp.WakeupsObj obj2);
-               public bool print ();
-       }
-       [CCode (cprefix = "DKP_DEVICE_STATE_", has_type_id = "0", cheader_filename = "devkit-power-gobject/devicekit-power.h")]
-       public enum DeviceState {
-               UNKNOWN,
-               CHARGING,
-               DISCHARGING,
-               EMPTY,
-               FULLY_CHARGED,
-               PENDING_CHARGE,
-               PENDING_DISCHARGE,
-               LAST
-       }
-       [CCode (cprefix = "DKP_DEVICE_TECHNOLOGY_", has_type_id = "0", cheader_filename = "devkit-power-gobject/devicekit-power.h")]
-       public enum DeviceTechnology {
-               UNKNOWN,
-               LITHIUM_ION,
-               LITHIUM_POLYMER,
-               LITHIUM_IRON_PHOSPHATE,
-               LEAD_ACID,
-               NICKEL_CADMIUM,
-               NICKEL_METAL_HYDRIDE,
-               LAST
-       }
-       [CCode (cprefix = "DKP_DEVICE_TYPE_", has_type_id = "0", cheader_filename = "devkit-power-gobject/devicekit-power.h")]
-       public enum DeviceType {
-               UNKNOWN,
-               LINE_POWER,
-               BATTERY,
-               UPS,
-               MONITOR,
-               MOUSE,
-               KEYBOARD,
-               PDA,
-               PHONE,
-               LAST
-       }
-       [CCode (cprefix = "DKP_QOS_TYPE_", has_type_id = "0", cheader_filename = "devkit-power-gobject/devicekit-power.h")]
-       public enum QosType {
-               UNKNOWN,
-               NETWORK,
-               CPU_DMA,
-               LAST
-       }
-       [CCode (cheader_filename = "devkit-power-gobject/devicekit-power.h")]
-       public const int COMPILE_VERSION;
-       [CCode (cheader_filename = "devkit-power-gobject/devicekit-power.h")]
-       public static Dkp.QosType qos_type_from_text (string type);
-       [CCode (cheader_filename = "devkit-power-gobject/devicekit-power.h")]
-       public static unowned string qos_type_to_text (Dkp.QosType type);
-}
diff --git a/zavai/gps.vala b/zavai/gps.vala
deleted file mode 100644 (file)
index 950d76b..0000000
+++ /dev/null
@@ -1,247 +0,0 @@
-/*
- * gps - gps resource for zavai
- *
- * Copyright (C) 2009--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 gps {
-
-// For a list of dbus services, look in /etc/dbus-1/system.d/
-public class GPS: zavai.ScriptService
-{
-    protected libgps.data_t data;
-    protected IOChannel gpsfd = null;
-    protected uint gpsfd_watch = 0;
-
-    protected int old_fix_status = libgps.STATUS_NO_FIX;
-    protected uint old_time = 0;
-    protected double old_lat = 1000;
-    protected double old_lon = 1000;
-
-    public signal void fix_status_changed(int status);
-    public signal void time_changed(uint time);
-    public signal void pos_changed();
-
-    public GPS()
-    {
-        Object(name: "gps");
-        data = libgps.data_t();
-        started = script_status();
-    }
-
-    public int fix_status() { return old_fix_status; }
-    public double time() { return old_time; }
-    public weak libgps.data_t info() { return data; }
-
-    protected bool on_input_data(IOChannel source, IOCondition condition)
-    {
-        while (libgps.waiting(ref data))
-        {
-            int res = libgps.poll(ref data);
-            if (res != 0)
-                zavai.log.error(libgps.errstr(res));
-
-            if (data.status != old_fix_status)
-            {
-                fix_status_changed(data.status);
-                old_fix_status = data.status;
-            }
-
-            uint cur_time = (uint)data.fix.time;
-            if (data.status != libgps.STATUS_NO_FIX && old_time != cur_time)
-            {
-                time_changed(cur_time);
-                old_time = cur_time;
-            }
-
-            double lat = (data.status == libgps.STATUS_NO_FIX ? 1000 : data.fix.latitude);
-            double lon = (data.status == libgps.STATUS_NO_FIX ? 1000 : data.fix.longitude);
-            if (lat != old_lat || lon != old_lon)
-                pos_changed();
-
-            /*
-            stderr.printf("GPSMSG %d %d\n", (int)data.set, data.status);
-            stderr.printf("SATUSED %d\n", data.satellites_used);
-            stderr.printf("SWT %f\n", data.skyview_time);
-            stderr.printf("SATVIS %d\n", data.satellites_visible);
-            for (int i = 0; i < data.satellites_visible; ++i)
-            {
-                stderr.printf("PRN %d ELE %d AZI %d SS %f\n",
-                    data.PRN[i], data.elevation[i], data.azimuth[i], data.ss[i]);
-            }
-            */
-        }
-        return true;
-    }
-
-    /// Request GPS resource
-    public override void start()
-    {
-        if (started) return;
-
-        if (!script_start()) return;
-
-        zavai.log.info("Connecting to gpsd at " + config.gpsd_host + ":" + config.gpsd_port);
-        int res = libgps.open_r(config.gpsd_host, config.gpsd_port, ref data);
-        if (res != 0)
-        {
-            zavai.log.error(libgps.errstr(res));
-            return;
-        }
-
-        res = libgps.stream(ref data, libgps.WATCH_ENABLE, null);
-        if (res != 0)
-        {
-            zavai.log.error(libgps.errstr(res));
-            return;
-        }
-
-        //res = libgps.send(ref data, "?SKY;");
-        //res = libgps.send(ref data, "?WATCH;");
-        //if (res != 0) zavai.log.error(libgps.errstr(res));
-
-        gpsfd = new IOChannel.unix_new(data.gps_fd);
-        try {
-            gpsfd.set_encoding(null);
-        } catch (Error e) {
-            zavai.log.error("Setting encoding to null on gpsd io channel: " + e.message);
-        }
-        //gpsfd.set_buffered(false);
-        gpsfd_watch = gpsfd.add_watch(IOCondition.IN, on_input_data);
-
-        zavai.log.info("GPS turned on");
-        base.start();
-    }
-
-    // Release usage of GPS
-    public override void stop()
-    {
-        if (!started) return;
-
-        Source.remove(gpsfd_watch);
-
-        int res = libgps.close(ref data);
-        if (res != 0)
-            zavai.log.error(libgps.errstr(res));
-
-        script_stop();
-
-        if (old_fix_status != libgps.STATUS_NO_FIX)
-        {
-            old_fix_status = libgps.STATUS_NO_FIX;
-            fix_status_changed(old_fix_status);
-        }
-
-        if (old_time != 0)
-        {
-            old_time = 0;
-            time_changed(old_time);
-        }
-
-        base.stop();
-    }
-}
-
-// #    def start_recording(self):
-// #        if self.gps_monitor:
-// #            self.gps_monitor.stop()
-// #            self.gps_monitor = None
-// #
-// #        if not self.audio:
-// #            return
-// #
-// #        # Sync system time
-// #        gpstime = self.gps.gps_time.GetTime()
-// #        subprocess.call(["date", "-s", "@%d" % gpstime])
-// #        subprocess.call(["hwclock", "--systohc"])
-// #
-// #        # Compute basename for output files
-// #        self.basename = time.strftime("%Y-%m-%d-%H-%M-%S", time.localtime(gpstime))
-// #        self.basename = os.path.join(AUDIODIR, self.basename)
-// #
-// #        # Start recording the GPX track
-// #        self.gpx = GPX(self.basename)
-// #        self.gps.track_position(self.on_position_changed)
-// #
-// #        # Start recording in background forking arecord
-// #        self.audio.set_basename(self.basename)
-// #        self.audio.start_recording()
-// #
-
-// Write GPX track and waypoint files
-public class GPX : Service
-{
-    protected uint wpt_seq = 0;
-    protected uint log_id = 0;
-
-    public GPX()
-    {
-        Object(name: "gps.gpx");
-    }
-
-    public override void start()
-    {
-        if (!started)
-        {
-            log_id = log.log.start("track", "GPS track");
-            base.start();
-        }
-    }
-
-    public override void stop()
-    {
-        if (started)
-        {
-            log.log.end(log_id);
-            log_id = 0;
-            base.stop();
-        }
-    }
-
-    // Mark a waypoint
-    public void waypoint(string? name = null)
-    {
-        if (log_id == 0) return;
-
-        string wptname;
-        if (name == null)
-        {
-            wptname = "wpt_%u".printf(wpt_seq);
-            wpt_seq += 1;
-        } else {
-            wptname = name;
-        }
-
-        log.log.add(log_id, wptname);
-    }
-}
-
-public zavai.gps.GPS gps = null;
-public zavai.gps.GPX gpx = null;
-
-public void init()
-{
-    gps = new GPS();
-    gpx = new GPX();
-
-}
-
-}
-}
diff --git a/zavai/gsm.vala b/zavai/gsm.vala
deleted file mode 100644 (file)
index 19a854d..0000000
+++ /dev/null
@@ -1,449 +0,0 @@
-/*
- * gsm - gsm resource for zavai
- *
- * Copyright (C) 2009--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 gsm {
-
-[DBus (name = "org.freesmartphone.GSM.Device")]
-public interface FSO_GSM_Device : Object {
-    public abstract async int test_int (int i, out int j) throws DBus.Error;
-    public abstract async string test_string (string s, out string t) throws DBus.Error;
-    public abstract async void set_sim_buffers_sms(bool sim_buffers_sms) throws DBus.Error;
-    public abstract async void set_r_t_c() throws DBus.Error;
-    public abstract async void cancel_command() throws DBus.Error;
-    public abstract async void set_antenna_power(bool power) throws DBus.Error;
-    public abstract async GLib.HashTable<string, GLib.Value?> get_info() throws DBus.Error;
-    public abstract async void set_microphone_muted(bool muted) throws DBus.Error;
-    public signal void keypad_event(string name, bool pressed);
-    public abstract async int get_speaker_volume() throws DBus.Error;
-    public abstract async int get_r_t_c() throws DBus.Error;
-    public abstract async void set_speaker_volume(int modem_volume) throws DBus.Error;
-    public abstract async GLib.HashTable<string, GLib.Value?> get_features() throws DBus.Error;
-    public abstract async bool get_microphone_muted() throws DBus.Error;
-    public abstract async bool get_antenna_power() throws DBus.Error;
-    public abstract async void get_power_status(out string param0, out int param1) throws DBus.Error;
-    public abstract async bool get_sim_buffers_sms() throws DBus.Error;
-}
-
-[DBus (name = "org.freesmartphone.GSM.SIM")]
-public interface FSO_GSM_SIM : GLib.Object {
-    //public abstract async SIMParam0Struct[] retrieve_phonebook(string category) throws DBus.Error;
-    public abstract async void send_auth_code(string code) throws DBus.Error;
-    public abstract async string get_issuer() throws DBus.Error;
-    public abstract async void change_auth_code(string old_pin, string new_pin) throws DBus.Error;
-    public signal void auth_status(string status);
-    public abstract async string send_generic_sim_command(string command) throws DBus.Error;
-    public abstract async string[] list_phonebooks() throws DBus.Error;
-    public abstract async void set_service_center_number(string number) throws DBus.Error;
-    public abstract async GLib.HashTable<string, string> get_provider_list() throws DBus.Error;
-    //public abstract async SIMParam0Struct2[] get_home_zones() throws DBus.Error;
-    public signal void ready_status(bool status);
-    public abstract async void retrieve_entry(string category, int index, out string param0, out string param1) throws DBus.Error;
-    public abstract async void delete_message(int index) throws DBus.Error;
-    public abstract async void send_restricted_sim_command(int command, int fileid, int p1, int p2, int p3, string data, out int param0, out int param1, out string param2) throws DBus.Error;
-    public abstract async GLib.HashTable<string, GLib.Value?> get_messagebook_info() throws DBus.Error;
-    public abstract async bool get_sim_ready() throws DBus.Error;
-    public abstract async GLib.HashTable<string, GLib.Value?> get_phonebook_info(string category) throws DBus.Error;
-    public signal void memory_full();
-    public abstract async GLib.HashTable<string, GLib.Value?> get_sim_info() throws DBus.Error;
-    public abstract async void set_auth_code_required(bool required, string pin) throws DBus.Error;
-    public abstract async string get_auth_status() throws DBus.Error;
-    public abstract async void send_stored_message(int index, out int param0, out string param1) throws DBus.Error;
-    public abstract async int store_message(string number, string contents, GLib.HashTable<string, GLib.Value?> properties) throws DBus.Error;
-    public abstract async bool get_auth_code_required() throws DBus.Error;
-    public signal void incoming_stored_message(int index);
-    public abstract async void retrieve_message(int index, out string param0, out string param1, out string param2, out GLib.HashTable<string, GLib.Value?> param3) throws DBus.Error;
-    public abstract async void store_entry(string category, int index, string name, string number) throws DBus.Error;
-    public abstract async void unlock(string puk, string new_pin) throws DBus.Error;
-    public abstract async string get_service_center_number() throws DBus.Error;
-    //public abstract async SIMParam0Struct23[] retrieve_messagebook(string category) throws DBus.Error;
-    public abstract async void delete_entry(string category, int index) throws DBus.Error;
-}
-
-[DBus (name = "org.freesmartphone.GSM.Network")]
-public interface FSO_GSM_Network : GLib.Object {
-    public signal void status(GLib.HashTable<string, GLib.Value?> status);
-    public signal void signal_strength(int strength);
-    //public abstract async NetworkParam0Struct[] list_providers() throws DBus.Error;
-    public abstract async GLib.HashTable<string, GLib.Value?> get_call_forwarding(string reason) throws DBus.Error;
-    public signal void time_zone_report(int timezone);
-    public abstract async void unregister() throws DBus.Error;
-    public abstract async void set_calling_identification(string status) throws DBus.Error;
-    public abstract async void register_() throws DBus.Error;
-    public abstract async void send_ussd_request(string request) throws DBus.Error;
-    public abstract async void disable_call_forwarding(string reason, string class_) throws DBus.Error;
-    public signal void incoming_ussd(string mode, string message_);
-    public abstract async int get_signal_strength() throws DBus.Error;
-    public abstract async void enable_call_forwarding(string reason, string class_, string number, int timeout) throws DBus.Error;
-    public abstract async string get_calling_identification() throws DBus.Error;
-    public abstract async void register_with_provider(string operator_code) throws DBus.Error;
-    public signal void cipher_status(string gsm, string gprs);
-    public abstract async GLib.HashTable<string, GLib.Value?> get_status() throws DBus.Error;
-    public abstract async void get_country_code(out string param0, out string param1) throws DBus.Error;
-}
-
-[DBus (name = "org.freesmartphone.GSM.Call")]
-public interface FSO_GSM_Call : GLib.Object {
-    public abstract async void activate(int index) throws DBus.Error;
-    public abstract async void emergency(string number) throws DBus.Error;
-    public abstract async void hold_active() throws DBus.Error;
-    public abstract async void release_held() throws DBus.Error;
-    public abstract async void send_dtmf(string tones) throws DBus.Error;
-    public abstract async void release_all() throws DBus.Error;
-    public abstract async int initiate(string number, string type_) throws DBus.Error;
-    // public abstract async CallParam0Struct[] list_calls() throws DBus.Error;
-    public abstract async void transfer(string number) throws DBus.Error;
-    public abstract async void release(int index) throws DBus.Error;
-    public signal void call_status(int index, string status, GLib.HashTable<string, GLib.Value?> properties);
-    public abstract async void activate_conference(int index) throws DBus.Error;
-}
-
-public class GSM: zavai.ScriptMonitorService
-{
-    protected dynamic DBus.Object dbus;
-    public FSO_GSM_Device device;
-    public FSO_GSM_Network network;
-    public FSO_GSM_SIM sim;
-    public FSO_GSM_Call call;
-
-    protected class CallInfo
-    {
-        public int gsm_id;
-        public uint log_id;
-    }
-    protected List<CallInfo> calls;
-
-    public string info_provider;
-    public int info_signal_strength;
-
-    public signal void status_changed(string message);
-    public signal void info_changed();
-
-    protected void dump_table(HashTable<string, Value?> vals)
-    {
-        vals.for_each((pk, pv) => {
-            string k = (string)pk;
-            Value? v = (Value?)pv;
-            stderr.printf("K: %s V: %s\n", k, v == null ? "(null)" : v.strdup_contents());
-        });
-    }
-
-    protected void acquire_new_status(HashTable<string, Value?> status)
-    {
-        // NETWORK STATUS
-        // K: provider V: "vodafone UK"
-        // K: mode V: "automatic"
-        // K: registration V: "roaming"
-        // K: cid V: "157F"
-        // K: lac V: "0031"
-        // K: act V: "GSM"
-        // K: code V: "23415"
-        bool changed = false;
-
-        var vprovider = status.lookup("provider");
-        if (vprovider != null)
-        {
-            if (info_provider != vprovider.get_string())
-            {
-                info_provider = vprovider.get_string();
-stderr.printf("ACQUIRE PROV %s\n", info_provider);
-                changed = true;
-            }
-        }
-
-        if (changed)
-        {
-stderr.printf("NOTIFY CHANGED\n");
-            info_changed();
-        }
-    }
-
-    protected void acquire_new_signal_strength(int strength)
-    {
-        if (info_signal_strength != strength)
-        {
-            info_signal_strength = strength;
-stderr.printf("ACQUIRE SIG %d\n", info_signal_strength);
-            info_changed();
-        }
-    }
-
-    public GSM()
-    {
-        Object(name: "gsm");
-
-        calls = new List<CallInfo>();
-
-        device = (FSO_GSM_Device)zavai.registry.sbus.get_object(
-                "org.freesmartphone.ogsmd", 
-                "/org/freesmartphone/GSM/Device",
-                "org.freesmartphone.GSM.Device");
-        network = (FSO_GSM_Network)zavai.registry.sbus.get_object(
-            "org.freesmartphone.ogsmd", 
-            "/org/freesmartphone/GSM/Device",
-            "org.freesmartphone.GSM.Network");
-        sim = (FSO_GSM_SIM)zavai.registry.sbus.get_object(
-                "org.freesmartphone.ogsmd", 
-                "/org/freesmartphone/GSM/Device",
-                "org.freesmartphone.GSM.SIM");
-        call = (FSO_GSM_Call)zavai.registry.sbus.get_object(
-            "org.freesmartphone.ogsmd", 
-            "/org/freesmartphone/GSM/Device",
-            "org.freesmartphone.GSM.Call");
-        dbus = zavai.registry.sbus.get_object(
-                "org.freedesktop.DBus",
-                "/org/freedesktop/DBus",
-                "org.freedesktop.DBus");
-        dbus.NameOwnerChanged += on_name_owner_changed;
-
-        info_provider = "(unknown)";
-        info_signal_strength = -1;
-
-        network.status += (status) => {
-            stderr.printf("NETWORK STATUS\n");
-            dump_table(status);
-            acquire_new_status(status);
-        };
-
-        network.signal_strength += (strength) => {
-            stderr.printf("SIGNAL STRENGTH %d\n", strength);
-            acquire_new_signal_strength(strength);
-        };
-
-        call.call_status += on_call_status;
-    }
-
-    /// Request GPS resource
-    public override void start()
-    {
-        if (started) return;
-
-        status_changed("Starting");
-
-        script_start();
-
-        base.start();
-    }
-
-    protected void on_name_owner_changed(DBus.Object sender, string name, string oldOwner, string newOwner)
-    {
-        zavai.log.debug("NOC " + name + " from " + oldOwner + " to " + newOwner);
-        if (name == "org.freesmartphone.ogsmd" && newOwner != "")
-        {
-            status_changed("ogpsd came online");
-            start_gsm.begin();
-        }
-    }
-
-    // Release usage of GPS
-    public override void stop()
-    {
-        if (!started) return;
-
-        script_stop();
-
-        status_changed("");
-        info_provider = "";
-        info_signal_strength = -1;
-        info_changed();
-    }
-
-    protected override void cleanup_after_script_stop()
-    {
-        call = null;
-    }
-
-    public async void start_gsm()
-    {
-        status_changed("Turning on antenna");
-        while (true)
-        {
-            try {
-                yield device.set_antenna_power(true);
-                break;
-            } catch (Error e) {
-                zavai.log.warning("SetAntennaPower: " + e.message);
-                if (e.message.str("current status is 'enabling'") != null
-                 || e.message.str("current status is 'unknown'") != null)
-                {
-                    status_changed("Waiting for ogsmd to settle");
-                    zavai.log.info("trying again after 2 seconds");
-                    Timeout.add(2 * 1000, () => {
-                        start_gsm.callback();
-                        return false;
-                    });
-                    yield;
-                } else {
-                    status_changed("Checking if PIN is required");
-                    string status = yield sim.get_auth_status();
-                    zavai.log.info("on_auth_status: " + status);
-                    if (status == "READY")
-                        status_changed("PIN ok");
-                    else if (status == "SIM PIN")
-                    {
-                        status_changed("Sending PIN");
-                        yield sim.send_auth_code(zavai.config.sim_pin);
-                        status_changed("PIN OK");
-                    }
-                    else
-                        zavai.log.debug("Unknown status: " + status);
-                }
-            }
-        }
-        zavai.log.warning("on_antenna_power ok");
-        status_changed("Registering with network");
-        yield network.register_();
-        status_changed("Registered with network");
-
-        acquire_new_status(yield network.get_status());
-        acquire_new_signal_strength(yield network.get_signal_strength());
-    }
-
-    protected CallInfo? lookup_call(int gsm_id)
-    {
-        for (weak List<CallInfo> i = calls; i != null; i = i.next)
-            if (i.data.gsm_id == gsm_id)
-                return i.data;
-        return null;
-    }
-
-    public void on_call_status(int index, string status, HashTable<string, Value?> properties)
-    {
-        stderr.printf("CALL STATUS %d %s\n", index, status);
-        dump_table(properties);
-
-        CallInfo? info = lookup_call(index);
-        if (info == null)
-        {
-            Value? v = properties.lookup("peer");
-            string title;
-            if (v != null)
-                title = "%s call from %s".printf(status, v.get_string());
-            else
-                title = "%s call".printf(status);
-
-            info = new CallInfo();
-            info.gsm_id = index;
-            info.log_id = zavai.log.log.start("call", title);
-            calls.append(info);
-        }
-
-        // Log a summary of all info
-        string call_info = "status: %s\n".printf(status);
-        properties.for_each((pk, pv) => {
-            string k = (string)pk;
-            Value? v = (Value?)pv;
-            call_info = call_info + "%s: %s\n".printf(k, v == null ? "(null)" : v.strdup_contents());
-        });
-        zavai.log.log.add(info.log_id, call_info);
-
-        // Remove entry when it's the last possible status
-        if (status == "release")
-        {
-            zavai.log.log.end(info.log_id);
-            for (weak List<CallInfo> i = calls; i != null; i = i.next)
-                if (i.data.gsm_id == index)
-                {
-                    calls.delete_link(i);
-                    break;
-                }
-        }
-
-        /*
-        dbg("cbCallStatus %d, %s, %s" % (id, status, formatDict(properties)))
-        self.status = status
-        if status == "incoming":
-            if "peer" in properties and properties["peer"] == "+358942832031":
-                self.gsm_call_iface.ReleaseAll()
-                os.system("kapula-debug-call-handler &")
-            else:
-                os.system("alsactl restore -f /etc/alsa-scenarios/stereoout-maxvolume.state")
-                os.system("vibrator-start")
-                os.system("ringtone-start")
-                os.system("ledctrl --on-time 400 --off-time 200 gta02-aux:red");
-        if status == "release":
-            os.system("ringtone-stop")
-            os.system("vibrator-stop")
-            os.system("ledctrl --off gta02-aux:red");
-        */
-    }
-}
-
-public class GPRS: zavai.Service
-{
-    public dynamic DBus.Object device;
-
-    public GPRS()
-    {
-        Object(name: "gsm.gprs");
-
-        device = zavai.registry.sbus.get_object(
-            "org.freesmartphone.ogsmd", 
-            "/org/freesmartphone/GSM/Device",
-            "org.freesmartphone.GSM.PDP");
-    }
-
-    /// Request GPS resource
-    public override void start()
-    {
-        if (started) return;
-        try {
-            //gsm.request(name);
-            device.ActivateContext(
-                zavai.config.gprs_apn,
-                zavai.config.gprs_user,
-                zavai.config.gprs_pass);
-            zavai.log.info("Started GPRS");
-            base.start();
-        } catch (GLib.Error e) {
-            zavai.log.error(e.message);
-        }
-        base.start();
-    }
-
-    // Release usage of GPS
-    public override void stop()
-    {
-        if (!started) return;
-        try {
-            //gsm.release(name);
-            device.DeactivateContext();
-            zavai.log.info("Stopped GPRS");
-            base.stop();
-        } catch (GLib.Error e) {
-            zavai.log.error(e.message);
-        }
-        base.stop();
-    }
-}
-
-public zavai.gsm.GSM gsm = null;
-public zavai.gsm.GPRS gprs = null;
-
-public void init()
-{
-    gsm = new GSM();
-    gprs = new GPRS();
-}
-
-}
-}
diff --git a/zavai/input.vala b/zavai/input.vala
deleted file mode 100644 (file)
index ffa0add..0000000
+++ /dev/null
@@ -1,425 +0,0 @@
-/*
- * devinput - zavai /dev/input device handling
- *
- * Copyright (C) 2009  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
- */
-
-namespace zavai {
-namespace input {
-
-public class DevInput : zavai.Service
-{
-    public string device { get; construct; }
-
-    public signal bool event(LinuxInput.Event* ev);
-
-    protected IOChannel fd = null;
-    protected uint fd_watch = 0;
-
-    public DevInput(string name, string device)
-    {
-        Object(name: "input.power_button", device: "/dev/input/event0");
-    }
-
-    protected void close_fd()
-    {
-        if (fd != null)
-        {
-            try {
-                fd.shutdown(false);
-            } catch (IOChannelError e) {
-                zavai.log.error("When closing " + device + ": " + e.message);
-            }
-
-            fd = null;
-        }
-    }
-
-    protected bool on_input_data(IOChannel source, IOCondition condition)
-    {
-        if (condition != IOCondition.IN) return true;
-
-        //stderr.printf("GOT INPUT ON %s %d\n", device, source.unix_get_fd());
-        char[] buf = new char[sizeof(LinuxInput.Event)];
-        size_t count_read;
-        try {
-            source.read_chars(buf, out count_read);
-        } catch (Error e) {
-            zavai.log.error("Reading from " + device + ": " + e.message);
-            return true;
-        }
-        //stderr.printf("READ %zu chars\n", count_read);
-
-        LinuxInput.Event* ie = (LinuxInput.Event*)buf;
-        //stderr.printf("INPUT EVENT time %lu.%lu type %hu code %hu val %d\n", (ulong)ie->time.tv_sec, ie->time.tv_usec, ie->type, ie->code, ie->val);
-
-        /*
-        ts1, ts2, type, code, value = struct.unpack("LLHHI", buf)
-        #print ts1, ts2, type, code, value
-        if type == 1 and code == 119:
-            if value:
-                #print "BUTTON RELEASE"
-                pass
-            else:
-                if self.last_button_press + 1 < ts1:
-                    self.last_button_press = ts1
-                    if self.button_press_handler is not None:
-                        self.button_press_handler()
-                    #print "BUTTON PRESS"
-        elif type == 5 and code == 2:
-            if value:
-                info("Headset plugged in")
-                self.mixer_for_headset(self)
-            else:
-                info("Headset plugged out")
-                self.mixer_for_handset(self)
-        */
-        return event(ie);
-    }
-
-    /// Start reading from the device
-    public override void start()
-    {
-        if (started) return;
-
-        if (fd != null)
-            close_fd();
-
-        // Open the device and listed to it using the GObject main loop
-        zavai.log.info("Opening device " + device);
-        fd = new IOChannel.file(device, "r");
-        try {
-            fd.set_encoding(null);
-        } catch (Error e) {
-            zavai.log.error("Setting encoding to null on " + device + ": " + e.message);
-        }
-        fd.set_buffered(false);
-        fd_watch = fd.add_watch(IOCondition.IN, on_input_data);
-
-        base.start();
-    }
-
-    // Stop reading from the device
-    public override void stop()
-    {
-        if (!started) return;
-
-        if (fd != null)
-        {
-            Source.remove(fd_watch);
-            close_fd();
-        }
-
-        base.stop();
-    }
-}
-
-public class HotKeys : zavai.Service
-{
-    protected List<int> grabbed;
-    public signal bool hotkey(uint keycode, ulong time, bool pressed);
-
-    public HotKeys()
-    {
-        Object(name: "input.hotkeys");
-
-        grabbed = new List<int>();
-    }
-
-    // Hotkey handlink takes inspiration from
-    // http://old.nabble.com/-PATCH--Initial-non-working-implementation-of-wxWindow::%28Un%29RegisterHotKey-on-wxGTK-td14557263.html
-    private static Gdk.FilterReturn on_hotkey(Gdk.XEvent* xevent, Gdk.Event? event, void* data)
-    {
-        // Global events don't get their data translated to gdk, as there is no
-        // GdkWindow to work with, therefore we need to use the xevent, because
-        // GdkEvent* is always GDK_NOTHING
-        X.Event* xev = (X.Event*)xevent;
-
-        switch (xev->type)
-        {
-            case X.EventType.KeyPress:
-                return zavai.input.hotkeys.my_on_hotkey(xev, true);
-            case X.EventType.KeyRelease:
-                return zavai.input.hotkeys.my_on_hotkey(xev, false);
-            default:
-                return Gdk.FilterReturn.CONTINUE;
-        }
-    }
-
-    //public Gdk.FilterReturn on_hotkey(Gdk.XEvent xevent, Gdk.Event? event)
-    private Gdk.FilterReturn my_on_hotkey(X.Event* xev, bool pressed)
-    {
-        // From http://tronche.com/gui/x/xlib/input/pointer-grabbing.html:
-        //
-        // A timestamp is a time value, expressed in milliseconds. It typically is the
-        // time since the last server reset. Timestamp values wrap around (after about
-        // 49.7 days). The server, given its current time is represented by timestamp
-        // T, always interprets timestamps from clients by treating half of the
-        // timestamp space as being later in time than T. One timestamp value, named
-        // CurrentTime, is never generated by the server. This value is reserved for
-        // use in requests to represent the current server time. 
-
-        if (grabbed.index((int)xev->xkey.keycode) == -1)
-            return Gdk.FilterReturn.CONTINUE;
-
-        if (hotkey(xev->xkey.keycode, xev->xkey.time, pressed))
-            return Gdk.FilterReturn.REMOVE;
-        return Gdk.FilterReturn.CONTINUE;
-    }
-
-    public void grab(int keycode, int modifiers, bool owner_events)
-    {
-        // We need to grab the keys we want to listen to
-        int res = Gdk.x11_get_default_xdisplay().grab_key(keycode, modifiers, Gdk.x11_get_default_root_xwindow(), owner_events, X.GrabMode.Async, X.GrabMode.Async);
-        if (res != 0)
-            stderr.printf("Grab result: %d\n", res); // We get BadRequest and don't know why
-        grabbed.append(keycode);
-    }
-
-    /// Start reading from the device
-    public override void start()
-    {
-        if (started) return;
-
-        //gdk_window_add_filter (NULL, _wxgtk_global_hotkey_callback, this);
-        ((Gdk.Window*)null)->add_filter((Gdk.FilterFunc)on_hotkey);
-
-        grab(160, 0, false);
-
-        base.start();
-    }
-
-    // Stop reading from the device
-    public override void stop()
-    {
-        if (!started) return;
-
-        //gdk_window_remove_filter(NULL, _wxgtk_global_hotkey_callback, this); 
-        ((Gdk.Window*)null)->remove_filter((Gdk.FilterFunc)on_hotkey);
-
-        base.stop();
-    }
-}
-
-public class PowerButton : zavai.Service
-{
-    protected DevInput devinput;
-
-    public signal void power_button(Posix.timeval* time, bool pressed);
-
-    public PowerButton()
-    {
-        // FIXME: change to event0 for the power button
-        // FIXME: change to event4 for the aux button and headset button
-        string inputdev = "/dev/input/event0";
-        if (Posix.access(inputdev, Posix.R_OK) == 0)
-        {
-            zavai.log.info("Handle power button via " + inputdev);
-            // Listen via input device
-            devinput = new DevInput("input.power_button", "/dev/input/event0");
-            devinput.event += on_event;
-            devinput.request("powerbutton");
-        } else {
-            zavai.log.info("Handle power button via XGrabKey on keycode " + zavai.config.power_button_keycode.to_string());
-            // Listen via X
-            hotkeys.hotkey += on_hotkey;
-            hotkeys.grab(zavai.config.power_button_keycode, 0, false);
-            hotkeys.request("powerbutton");
-        }
-    }
-
-    protected bool on_event(LinuxInput.Event* ev)
-    {
-        if (ev->type == LinuxInput.Type.KEY && 
-            ev->code == LinuxInput.Key.POWER)
-        {
-            power_button(&(ev->time), ev->val == 0 ? false : true);
-        }
-        return true;
-    }
-
-    protected bool on_hotkey(uint keycode, ulong time, bool pressed)
-    {
-        if (keycode == zavai.config.power_button_keycode)
-        {
-            // Convert X time to a fake timeval
-            // TODO: handle wraparound
-            Posix.timeval tv = {
-                (time_t)(time / 1000),
-                (long)((time % 1000) * 1000)
-            };
-            power_button(&tv, pressed);
-            return true;
-        }
-        return false;
-    }
-}
-
-
-/*
-# TODO:
-#  - hook into the headset plugged/unplugged event
-#  - if unplugged, turn on handset microphone
-#  - if plugged, redo headest mixer settings
-class Audio:
-    "Handle mixer settings, audio recording and headset button presses"
-    def __init__(self, button_press_handler = None):
-        self.saved_scenario = os.path.expanduser("~/.audiomap.state")
-
-        # Setup the mixer
-        # Set mixer to record from headset and handle headset button
-        self.save_scenario(self.saved_scenario)
-        self.load_scenario("/usr/share/openmoko/scenarios/voip-handset.state")
-
-        # This is a work-around because I have not found a way to query for the
-        # current headset state, I can only know when it changes. So in my
-        # system I configured oeventsd with a rule to touch this file when the
-        # headset is plugged in, and remove the file when it's plugged out.
-        if os.path.exists("/tmp/has_headset"):
-            self.mixer_for_headset(True)
-        else:
-            self.mixer_for_handset(True)
-
-        #self.mixer_set("DAPM Handset Mic", "mute")
-        #self.mixer_set("DAPM Headset Mic", "unmute")
-        #self.mixer_set("Left Mixer Sidetone Playback Sw", "unmute")
-        #self.mixer_set("ALC Mixer Mic1", "cap")
-        #self.mixer_set("Amp Spk", "mute") # We don't need the phone playing what we say
-
-        # Watch the headset button
-        self.button_press_handler = button_press_handler
-        self.input_fd = open("/dev/input/event4", "rb")
-        self.input_watch = gobject.io_add_watch(self.input_fd.fileno(), gobject.IO_IN, self.on_input_data)
-
-        self.last_button_press = 0
-        self.recorder = None
-        self.basename = None
-
-    def mixer_for_headset(self, force=False):
-        if not force and self.has_headset: return
-        info("Setting mixer for headset")
-        # TODO: find out how to disable the handset microphone: this does not
-        # seem to be sufficient
-        self.mixer_set_many(
-                ("DAPM Handset Mic", "mute"),
-                ("DAPM Headset Mic", "unmute"),
-                ("Left Mixer Sidetone Playback Sw", "unmute"),
-                ("ALC Mixer Mic1", "cap"),
-                ("Amp Spk", "mute") # We don't need the phone playing what we say
-        )
-        self.has_headset = True
-
-    def mixer_for_handset(self, force=False):
-        if not force and not self.has_headset: return
-        info("Setting mixer for handset")
-        self.mixer_set_many(
-                ("DAPM Handset Mic", "unmute"),
-                ("DAPM Headset Mic", "mute"),
-                ("Left Mixer Sidetone Playback Sw", "mute"),
-                ("ALC Mixer Mic1", "cap"),
-                ("Amp Spk", "mute") # We don't need the phone playing what we say
-        )
-        self.has_headset = False
-
-    def set_basename(self, basename):
-        self.basename = basename
-
-    def start_recording(self):
-        if self.basename is None:
-            raise RuntimeError("Recording requested but basename not set")
-        self.recorder = subprocess.Popen(
-            ["arecord", "-D", "hw", "-f", "cd", "-r", "8000", "-t", "wav", self.basename + ".wav"])
-
-    def start_levels(self):
-        self.recorder = subprocess.Popen(
-            ["arecord", "-D", "hw", "-f", "cd", "-r", "8000", "-t", "wav", "-V", "stereo", "/dev/null"])
-
-    def close(self):
-        if self.recorder is not None:
-            os.kill(self.recorder.pid, signal.SIGINT)
-            self.recorder.wait()
-
-        # Restore mixer settings
-        self.load_scenario(self.saved_scenario)
-
-        gobject.source_remove(self.input_watch)
-        self.input_fd.close()
-
-    def on_input_data(self, source, condition):
-        buf = self.input_fd.read(16)
-        ts1, ts2, type, code, value = struct.unpack("LLHHI", buf)
-        #print ts1, ts2, type, code, value
-        if type == 1 and code == 119:
-            if value:
-                #print "BUTTON RELEASE"
-                pass
-            else:
-                if self.last_button_press + 1 < ts1:
-                    self.last_button_press = ts1
-                    if self.button_press_handler is not None:
-                        self.button_press_handler()
-                    #print "BUTTON PRESS"
-        elif type == 5 and code == 2:
-            if value:
-                info("Headset plugged in")
-                self.mixer_for_headset(self)
-            else:
-                info("Headset plugged out")
-                self.mixer_for_handset(self)
-        return True
-
-    def save_scenario(self, name):
-        res = subprocess.call(["alsactl", "store", "-f", name])
-        if res != 0:
-            raise RuntimeError("Saving audio scenario to '%s' failed" % name)
-
-    def load_scenario(self, name):
-        res = subprocess.call(["alsactl", "restore", "-f", name])
-        if res != 0:
-            raise RuntimeError("Loading audio scenario '%s' failed" % name)
-
-    def mixer_set(self, name, *args):
-        args = map(str, args)
-        res = subprocess.call(["amixer", "-q", "set", name] + args)
-        if res != 0:
-            raise RuntimeError("Setting mixer '%s' to %s failed" % (name, " ".join(args)))
-
-    # Will do this when we find out the syntax for giving amixer commands on stdin
-    def mixer_set_many(self, *args):
-        """Perform many mixer set operations via amixer --stdin"""
-        proc = subprocess.Popen(["amixer", "-q", "--stdin"], stdin=subprocess.PIPE)
-        cmd_input = []
-        for k, v in args:
-            cmd_input.append("sset " + repr(k) + " " + repr(v))
-        (out, err) = proc.communicate(input="\n".join(cmd_input))
-        res = proc.wait()
-        if res != 0:
-            raise RuntimeError("Setting mixer failed")
-*/
-
-
-public HotKeys hotkeys = null;
-public PowerButton power_button = null;
-
-public void init()
-{
-    hotkeys = new HotKeys();
-    power_button = new PowerButton();
-}
-
-}
-}
diff --git a/zavai/libgps.vapi b/zavai/libgps.vapi
deleted file mode 100644 (file)
index da29fcd..0000000
+++ /dev/null
@@ -1,238 +0,0 @@
-[CCode (lower_case_cprefix="", cprefix="", cheader_filename="gps.h")]
-namespace libgps
-{
-    public const int MAXCHANNELS;
-
-    [SimpleType]
-    [IntegerType (rank = 9)]
-    public struct mask_t {}
-
-    [CCode (cname = "struct gps_fix_t")]
-    public struct fix_t
-    {
-        double time;   /* Time of update, seconds since Unix epoch */
-        int    mode;   /* Mode of fix */
-        double ept;            /* Expected time uncertainty */
-        double latitude;       /* Latitude in degrees (valid if mode >= 2) */
-        double epy;    /* Latitude position uncertainty, meters */
-        double longitude;      /* Longitude in degrees (valid if mode >= 2) */
-        double epx;    /* Longitude position uncertainty, meters */
-        double altitude;       /* Altitude in meters (valid if mode == 3) */
-        double epv;    /* Vertical position uncertainty, meters */
-        double track;  /* Course made good (relative to true north) */
-        double epd;            /* Track uncertainty, degrees */
-        double speed;  /* Speed over ground, meters/sec */
-        double eps;            /* Speed uncertainty, meters/sec */
-        double climb;   /* Vertical speed, meters/sec */
-        double epc;            /* Vertical speed uncertainty */
-    }
-    public const int MODE_NOT_SEEN; /* mode update not seen yet */
-    public const int MODE_NO_FIX;   /* none */
-    public const int MODE_2D;       /* good for latitude/longitude */
-    public const int MODE_3D;       /* good for altitude/climb too */
-
-    [CCode (cname = "struct dop_t")]
-    public struct dop_t
-    {
-        /* Dilution of precision factors */
-        double xdop;
-        double ydop;
-        double pdop;
-        double hdop;
-        double vdop;
-        double tdop;
-        double gdop;
-    }
-
-    [CCode (cname = "struct gps_data_t", destroy_function = "")]
-    public struct data_t
-    {
-        mask_t set;
-        double online;
-        int gps_fd;
-        fix_t fix;
-        double separation;
-        int status;
-        int satellites_used;        /* Number of satellites used in solution */
-        int[] used;      /* PRNs of satellites used in solution */
-        dop_t dop;
-        /* redundant with the estimate elements in the fix structure */
-        double epe;  /* spherical position error, 95% confidence (meters)  */
-
-        /* satellite status -- valid when satellites_visible > 0 */
-        double skyview_time;        /* skyview timestamp */
-        int satellites_visible;     /* # of satellites in view */
-        int[] PRN;       /* PRNs of satellite */
-        int[] elevation; /* elevation of satellite */
-        int[] azimuth;   /* azimuth */
-        double[] ss;     /* signal-to-noise ratio (dB) */
-
-        //struct devconfig_t dev;     /* device that shipped last update */
-
-        //struct policy_t policy;     /* our listening policy */
-
-        //char tag[MAXTAGLEN+1];      /* tag of last sentence processed */
-    }
-    public const int ONLINE_SET;
-    public const int TIME_SET;
-    public const int TIMERR_SET;
-    public const int LATLON_SET;
-    public const int ALTITUDE_SET;
-    public const int SPEED_SET;
-    public const int TRACK_SET;
-    public const int CLIMB_SET;
-    public const int STATUS_SET;
-    public const int MODE_SET;
-    public const int DOP_SET;
-    public const int VERSION_SET; /* only used in client library */
-    public const int HERR_SET;
-    public const int VERR_SET;
-    public const int PERR_SET;
-    public const int POLICY_SET; /* only used in client library */
-    public const int ERR_SET;
-    public const int SATELLITE_SET;
-    public const int RAW_SET;
-    public const int USED_SET;
-    public const int SPEEDERR_SET;
-    public const int TRACKERR_SET;
-    public const int CLIMBERR_SET;
-    public const int DEVICE_SET;
-    public const int DEVICELIST_SET;
-    public const int DEVICEID_SET;
-    public const int ERROR_SET;
-    public const int RTCM2_SET;
-    public const int RTCM3_SET;
-    public const int AIS_SET;
-    public const int PACKET_SET;
-    public const int CLEAR_SET; /* sentence starts a reporting cycle */
-    public const int REPORT_SET; /* sentence ends a reporting cycle */
-    public const int DATA_SET;
-
-    public const int STATUS_NO_FIX;   /* no */
-    public const int STATUS_FIX;      /* yes, without DGPS */
-    public const int STATUS_DGPS_FIX; /* yes, with DGPS */
-
-    [CCode (cname = "gps_open_r")]
-    public int open_r(string server, string port, ref data_t gpsdata);
-
-    [CCode (cname = "gps_close")]
-    public int close(ref data_t gpsdata);
-
-    [CCode (cname = "gps_errstr")]
-    public weak string errstr(int err);
-
-    [CCode (cname = "gps_poll")]
-    public int poll(ref data_t gpsdata);
-
-    [CCode (cname = "gps_waiting")]
-    public bool waiting(ref data_t gpsdata);
-
-    [CCode (cname = "gps_send")]
-    public int send(ref data_t gpsdata, string fmt, ...);
-
-    [CCode (cname = "gps_stream")]
-    public int stream(ref data_t gpsdata, uint flags, void* data);
-
-    /* mode flags for gps_stream() */
-    public int WATCH_DISABLE;  /* disable watching */
-    public int WATCH_ENABLE;   /* enable streaming */
-    public int WATCH_JSON;     /* enable JSON output */
-    public int WATCH_NMEA;     /* enable output in NMEA */
-    public int WATCH_RARE;     /* enable output of packets in hex */
-    public int WATCH_RAW;      /* enable output of raw packets */
-    public int WATCH_SCALED;   /* scale output to floats, when applicable */ 
-    public int WATCH_NEWSTYLE; /* force JSON streaming */
-    public int WATCH_OLDSTYLE; /* force old-style streaming */
-    public int WATCH_DEVICE;   /* watch specific device */
-    public int POLL_NONBLOCK;  /* set non-blocking poll */
-
-    /*
-       [CCode (cname = "struct input_event")]
-       public struct Event
-       {
-               public Posix.timeval time;
-               public uint16 type;
-               public uint16 code;
-               [CCode (cname="value")]
-               public int32 val;
-       }
-
-       [CCode (cprefix="KEY_")]
-       public enum Key
-       {
-               POWER
-       }
-
-       [CCode (cprefix="EV_")]
-       public enum Type
-       {
-               SYN,
-               KEY,
-               REL,
-               ABS,
-               MSC,
-               SW,
-               LED,
-               SND,
-               REP,
-               FF,
-               PWR,
-               FF_STATUS
-       }
-}
-[CCode (cprefix="", cheader_filename="omhacks/all.h")]
-namespace Omhacks
-{
-    [CCode (cname = "struct om_led", cheader_filename = "omhacks/led.h", destroy_function = "")]
-    public struct Led
-    {
-        public char name[255];
-        public string dir;
-        public int dir_len;
-        public int brightness;
-        public char trigger[255];
-        public int delay_on;
-        public int delay_off;
-
-        [CCode (cname = "om_led_init")]
-        public int init(string name);
-        [CCode (cname = "om_led_get")]
-        public int get();
-        [CCode (cname = "om_led_set")]
-        public int set();
-    }
-
-    namespace Screen
-    {
-        namespace Brightness
-        {
-            [CCode (cname = "om_screen_brightness_get")]
-            public int get();
-            [CCode (cname = "om_screen_brightness_get_max")]
-            public int get_max();
-            [CCode (cname = "om_screen_brightness_set")]
-            public int set(int val);
-        }
-    }
-
-    namespace UEvent
-    {
-        [CCode (cname = "struct om_uevent", cheader_filename = "omhacks/uevent.h", destroy_function = "")]
-        public struct Event
-        {
-            public string buffer;
-            size_t buflen;
-            weak string action;
-            weak string devpath;
-            weak string[] envp;
-        }
-
-        [CCode (cname = "om_uevent_open")]
-        public int open();
-        [CCode (cname = "om_uevent_read")]
-        public int read(int sock, ref Event ou);
-        [CCode (cname = "om_uevent_parse")]
-        public int parse(ref Event ou);
-    }
-    */
-}
diff --git a/zavai/libomhacks.vapi b/zavai/libomhacks.vapi
deleted file mode 100644 (file)
index 83434f3..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-[CCode (cprefix="", cheader_filename="omhacks/all.h")]
-namespace Omhacks
-{
-    [CCode (cname = "struct om_led", cheader_filename = "omhacks/led.h", destroy_function = "")]
-    public struct Led
-    {
-        public char name[255];
-        public string dir;
-        public int dir_len;
-        public int brightness;
-        public char trigger[255];
-        public int delay_on;
-        public int delay_off;
-
-        [CCode (cname = "om_led_init")]
-        public int init(string name);
-        [CCode (cname = "om_led_get")]
-        public int get();
-        [CCode (cname = "om_led_set")]
-        public int set();
-    }
-
-    namespace Screen
-    {
-        namespace Brightness
-        {
-            [CCode (cname = "om_screen_brightness_get")]
-            public int get();
-            [CCode (cname = "om_screen_brightness_get_max")]
-            public int get_max();
-            [CCode (cname = "om_screen_brightness_set")]
-            public int set(int val);
-        }
-    }
-
-    namespace UEvent
-    {
-        [CCode (cname = "struct om_uevent", cheader_filename = "omhacks/uevent.h", destroy_function = "")]
-        public struct Event
-        {
-            public string buffer;
-            size_t buflen;
-            weak string action;
-            weak string devpath;
-            weak string[] envp;
-        }
-
-        [CCode (cname = "om_uevent_open")]
-        public int open();
-        [CCode (cname = "om_uevent_read")]
-        public int read(int sock, ref Event ou);
-        [CCode (cname = "om_uevent_parse")]
-        public int parse(ref Event ou);
-    }
-}
diff --git a/zavai/linux-input.vapi b/zavai/linux-input.vapi
deleted file mode 100644 (file)
index 211eab5..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-[CCode (lower_case_cprefix="", cprefix="", cheader_filename="linux/input.h")]
-namespace LinuxInput
-{
-       [CCode (cname = "struct input_event")]
-       public struct Event
-       {
-               public Posix.timeval time;
-               public uint16 type;
-               public uint16 code;
-               [CCode (cname="value")]
-               public int32 val;
-       }
-
-       [CCode (cprefix="KEY_")]
-       public enum Key
-       {
-               POWER
-       }
-
-       [CCode (cprefix="EV_")]
-       public enum Type
-       {
-               SYN,
-               KEY,
-               REL,
-               ABS,
-               MSC,
-               SW,
-               LED,
-               SND,
-               REP,
-               FF,
-               PWR,
-               FF_STATUS
-       }
-
-    [CCode (cprefix="EVIO")]
-    public enum Evio
-    {
-        CGRAB
-    }
-}
diff --git a/zavai/log.vala b/zavai/log.vala
deleted file mode 100644 (file)
index eb78363..0000000
+++ /dev/null
@@ -1,317 +0,0 @@
-/*
- * log - logging functions
- *
- * Copyright (C) 2009--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 log {
-
-public class Waypoint : Object
-{
-    public time_t ts;
-    public double lat;
-    public double lon;
-
-    public Waypoint()
-    {
-        if (gps.gps.fix_status() != libgps.STATUS_NO_FIX)
-        {
-            lat = gps.gps.info().fix.latitude;
-            lon = gps.gps.info().fix.longitude;
-            ts = (time_t)gps.gps.info().fix.time;
-        } else {
-            // Use 1000 as missing values
-            lat = 1000;
-            lon = 1000;
-            ts = time_t();
-        }
-    }
-
-    public void writeInside(FileStream outfd)
-    {
-        var t = Time.gm(ts);
-        outfd.printf("   <time>%s</time>\n", t.format("%Y-%m-%dT%H:%M:%SZ"));
-    }
-}
-
-
-public class LogEntry : Waypoint
-{
-    public string msg;
-
-    public LogEntry()
-    {
-        base();
-    }
-
-    public void write(FileStream outfd)
-    {
-        outfd.printf("   <wpt lat=\"%f\" lon=\"%f\">\n", lat, lon);
-        writeInside(outfd);
-        outfd.printf("   <name>%s</name>\n", Markup.escape_text(msg));
-        outfd.puts("   </wpt>\n");
-    }
-}
-
-public class TrackEntry : Waypoint
-{
-    public TrackEntry()
-    {
-        base();
-    }
-
-    public void write(FileStream outfd)
-    {
-        outfd.printf("   <trkpt lat=\"%f\" lon=\"%f\">\n", lat, lon);
-        writeInside(outfd);
-        outfd.puts("   </trkpt>\n");
-    }
-}
-
-
-public class Log : Object
-{
-    public uint id;
-    public string tag;
-    public string title;
-    public List<LogEntry> entries;
-    public List<TrackEntry> track;
-
-    public Log(uint id, string tag, string title)
-    {
-        this.id = id;
-        this.tag = tag;
-        this.title = title;
-        entries = null;
-        track = null;
-    }
-
-    public void add(string msg)
-    {
-        var entry = new LogEntry();
-        entry.msg = msg;
-        entries.append(entry);
-    }
-
-    public void add_trackpoint()
-    {
-        track.append(new TrackEntry());
-    }
-
-    public void save()
-    {
-        if (entries == null) return;
-
-        // Directory where we save the log
-        string dir = config.homedir + "/log-" + tag;
-        DirUtils.create(dir, 0777);
-
-        // First try with a plain name
-        var t = Time.local(entries.data.ts);
-        string basename = dir + "/" + t.format("%Y%m%d-%H%M%S");
-
-        string pathname = basename + ".gpx";
-
-        // Find a pathname that does not exist already
-        for (int i = 1; FileUtils.test(pathname, FileTest.EXISTS); ++i)
-            pathname = "%s-%d.gpx".printf(basename, i);
-
-        // Write out
-        var outfd = FileStream.open(pathname, "w");
-        if (outfd == null)
-        {
-            zavai.log.error("opening " + pathname + ": " + strerror(errno));
-            return;
-        }
-
-        write(outfd);
-        outfd.flush();
-    }
-
-    protected void writeTrack(FileStream outfd)
-    {
-        outfd.puts("   <trk>\n");
-        outfd.puts("     <trkseg>\n");
-        for (weak List<TrackEntry> i = track; i != null; i = i.next)
-            i.data.write(outfd);
-        outfd.puts("     </trkseg>\n");
-        outfd.puts("   </trk>\n");
-    }
-
-    protected void writeEntries(FileStream outfd)
-    {
-        outfd.puts("   <wpt>\n");
-        for (weak List<LogEntry> i = entries; i != null; i = i.next)
-            i.data.write(outfd);
-        outfd.puts("   </wpt>\n");
-    }
-
-    protected void write(FileStream outfd)
-    {
-        outfd.puts("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
-        outfd.puts("<gpx version=\"1.0\"\n");
-        outfd.printf("     creator=\"zavai %s\"\n", zavai.config.version);
-        outfd.puts("     xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n");
-        outfd.puts("     xmlns=\"http://www.topografix.com/GPX/1/0\"\n");
-        outfd.puts("     xsi:schemaLocation=\"http://www.topografix.com/GPX/1/0 http://www.topografix.com/GPX/1/0/gpx.xsd\">\n");
-        outfd.puts("  <metadata>\n");
-        outfd.printf("    <name>%s</name>\n", Markup.escape_text(title));
-        outfd.puts("  </metadata>\n");
-        if (track != null) writeTrack(outfd);
-        if (entries != null) writeEntries(outfd);
-        outfd.puts(" </gpx>\n");
-    }
-}
-
-public class Logger : Resource, Object
-{
-    protected List<Log> logs;
-    protected uint seq;
-
-    public Logger()
-    {
-        logs = null;
-        seq = 0;
-
-        zavai.registry.register(this);
-    }
-
-    protected void start_trace()
-    {
-        gps.gps.pos_changed += on_pos_changed;
-    }
-
-    protected void end_trace()
-    {
-        gps.gps.pos_changed -= on_pos_changed;
-    }
-
-    protected void on_pos_changed()
-    {
-        for (weak List<Log> i = logs; i != null; i = i.next)
-            i.data.add_trackpoint();
-    }
-
-    protected uint gen_seq()
-    {
-        // Increase avoiding 0 on rollover
-        while (true)
-        {
-            if (++seq == 0) ++seq;
-            bool found = false;
-            for (weak List<Log> i = logs; i != null; i = i.next)
-            {
-                if (i.data.id == seq)
-                {
-                    found = true;
-                    break;
-                }
-            }
-            if (!found) break;
-        }
-        return seq;
-    }
-
-    protected weak Log? find(uint id)
-    {
-        for (weak List<Log> i = logs; i != null; i = i.next)
-            if (i.data.id == id)
-                return i.data;
-        return null;
-    }
-
-    protected Log? pop(uint id)
-    {
-        for (weak List<Log> i = logs; i != null; i = i.next)
-            if (i.data.id == id)
-            {
-                Log res = i.data;
-                logs.delete_link(i);
-                return res;
-            }
-        return null;
-    }
-
-    public uint start(string tag, string title)
-    {
-        bool was_empty = (logs == null);
-        uint id = gen_seq();
-        logs.append(new Log(id, tag, title));
-        if (was_empty) start_trace();
-        return id;
-    }
-
-    public void add(uint id, string msg)
-    {
-        Log log = find(id);
-        if (log == null) return;
-        log.add(msg);
-    }
-
-    public void end(uint id)
-    {
-        Log log = pop(id);
-        log.save();
-        if (log == null) end_trace();
-    }
-
-    public void instant(string tag, string msg)
-    {
-        var log = new Log(0, tag, msg);
-        log.add(msg);
-        log.save();
-    }
-
-    public void shutdown()
-    {
-        while (logs != null)
-        {
-            var log = pop(logs.data.id);
-            log.save();
-        }
-    }
-}
-
-public void error(string s)
-{
-       stderr.printf("%s\n", s);
-}
-public void warning(string s)
-{
-       stderr.printf("%s\n", s);
-}
-public void info(string s)
-{
-       stderr.printf("%s\n", s);
-}
-public void debug(string s)
-{
-       stderr.printf("%s\n", s);
-}
-
-Logger log = null;
-
-public void init()
-{
-    log = new Logger();
-}
-
-}
-}
diff --git a/zavai/lua5.1.vapi b/zavai/lua5.1.vapi
deleted file mode 120000 (symlink)
index e730dfc..0000000
+++ /dev/null
@@ -1 +0,0 @@
-/usr/share/vala/vapi/lua.vapi
\ No newline at end of file
diff --git a/zavai/power.vala b/zavai/power.vala
deleted file mode 100644 (file)
index 5571117..0000000
+++ /dev/null
@@ -1,192 +0,0 @@
-/*
- * power - zavai power event handling
- *
- * Copyright (C) 2009  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 power {
-
-public class Power : Service
-{
-    public enum State
-    {
-        UNKNOWN,
-        CHARGING,
-        DISCHARGING,
-        FULLY_CHARGED,
-    }
-
-    protected string battery_device;
-    protected uint timeout;
-    public signal void changed();
-    public State state;
-    public int percentage;
-
-    public Power()
-    {
-        battery_device = "/sys/class/power_supply/battery/";
-        if (Posix.access(battery_device, Posix.R_OK) != 0)
-            battery_device = null;
-        timeout = 0;
-        state = State.UNKNOWN;
-        percentage = 0;
-    }
-
-    /// Activate the service
-    protected override void start()
-    {
-        if (started) return;
-
-        uint poll_time;
-        if (uevent.uevent != null)
-        {
-            zavai.log.info("We have uevent: poll rarely");
-            uevent.uevent.event += on_uevent;
-            uevent.uevent.request("zavai.power");
-            // If we can get plug/unplug notifications, it's ok to just poll
-            // every 5 minutes
-            poll_time = 300 * 1000;
-        } else {
-            if (battery_device == null)
-            {
-                zavai.log.warning("No battery device found that I know how to read: try building with devkit-power");
-                poll_time = 0;
-            } else {
-                zavai.log.info("Polling battery device only");
-                // Else poll every 30 seconds to be somehow reactive to plug/unplug
-                // events
-                poll_time = 30 * 1000;
-            }
-        }
-
-        poll();
-
-        // Poll battery every minute
-        if (poll_time != 0)
-            timeout = Timeout.add(poll_time, on_timeout);
-
-        base.start();
-    }
-
-    /// Deactivate the service
-    protected override void stop()
-    {
-        if (!started) return;
-
-        // Stop polling
-        if (timeout != 0)
-            Source.remove(timeout);
-
-        if (uevent.uevent != null)
-        {
-            uevent.uevent.release("zavai.power");
-            uevent.uevent.event -= on_uevent;
-        }
-
-        base.stop();
-    }
-
-    protected void poll()
-    {
-        if (battery_device == null)
-            return;
-
-        char buf[200];
-        State new_state = State.UNKNOWN;
-        int new_percentage = 0;
-
-        FileStream state_fd = FileStream.open(battery_device + "/status", "r");
-        string val = state_fd.gets(buf);
-        if (val == "Charging")
-            new_state = State.CHARGING;
-        else if (val == "Discharging")
-            new_state = State.DISCHARGING;
-        else if (val == "Not charging")
-            new_state = State.FULLY_CHARGED;
-
-        FileStream cap_fd = FileStream.open(battery_device + "/capacity", "r");
-        val = cap_fd.gets(buf);
-        new_percentage = val.to_int();
-
-        if (new_state != state || new_percentage != percentage)
-        {
-            state = new_state;
-            percentage = new_percentage;
-            changed();
-        }
-    }
-
-    protected bool on_timeout()
-    {
-        poll();
-        return true;
-    }
-
-    protected void on_uevent()
-    {
-        /* if (uevent.uevent.event_data.buffer.has_prefix("change@/class/power_supply/ac"))
-        {
-            changed();
-        }
-        else */
-        if (uevent.uevent.event_data.buffer.has_prefix("change@/class/power_supply/battery"))
-        {
-            State new_state = State.UNKNOWN;
-            int new_percentage = 0;
-
-            Omhacks.UEvent.parse(ref uevent.uevent.event_data);
-            for (int i = 0; uevent.uevent.event_data.envp[i] != null; ++i)
-            {
-                if (uevent.uevent.event_data.envp[i].has_prefix("POWER_SUPPLY_STATUS="))
-                {
-                    var val = uevent.uevent.event_data.envp[i].offset(20);
-                    if (val == "Charging")
-                        new_state = State.CHARGING;
-                    else if (val == "Discharging")
-                        new_state = State.DISCHARGING;
-                    else if (val == "Not charging")
-                        new_state = State.FULLY_CHARGED;
-                    else
-                        zavai.log.warning("Unknown state: " + uevent.uevent.event_data.envp[i]);
-                }
-                else if (uevent.uevent.event_data.envp[i].has_prefix("POWER_SUPPLY_CAPACITY="))
-                {
-                    new_percentage = uevent.uevent.event_data.envp[i].offset(22).to_int();
-                }
-            }
-            if (new_state != state || new_percentage != percentage)
-            {
-                state = new_state;
-                percentage = new_percentage;
-                changed();
-            }
-        }
-    }
-}
-
-public Power power;
-
-public void init()
-{
-    power = new Power();
-}
-
-}
-}
diff --git a/zavai/registry.vala b/zavai/registry.vala
deleted file mode 100644 (file)
index 3d549da..0000000
+++ /dev/null
@@ -1,83 +0,0 @@
-/* 
- * registry - zavai resource registry
- *
- * Copyright (C) 2009  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 {
-
-public class Registry : Object, Resource
-{
-    List<Resource> resources;
-    public DBus.Connection sbus;
-    public string bus_name;
-
-    public Registry()
-    {
-        resources = new List<Resource>();
-        try {
-            sbus = DBus.Bus.get(DBus.BusType.SYSTEM);
-        } catch (DBus.Error e) {
-            stderr.printf("Cannot access system DBus bus: %s\n", e.message);
-            sbus = null;
-        }
-
-        bus_name = DBus.bus_get_unique_name(sbus.get_connection());
-        zavai.log.info("My bus name: " + bus_name);
-
-        dynamic DBus.Object tmp_dbus = sbus.get_object(
-            "org.freedesktop.DBus",
-            "/org/freedesktop/DBus",
-            "org.freedesktop.DBus");
-        bus_name = "org.enricozini.zavai";
-        uint res = tmp_dbus.RequestName(bus_name, (uint)DBus.NameFlag.DO_NOT_QUEUE);
-        switch (res)
-        {
-            case DBus.RequestNameReply.PRIMARY_OWNER:
-                zavai.log.info("Registered to dbus as " + bus_name);
-                break;
-            case DBus.RequestNameReply.IN_QUEUE:
-                zavai.log.info("In queue, but I asked not to");
-                break;
-            case DBus.RequestNameReply.EXISTS:
-                zavai.log.info(bus_name + " already exists");
-                break;
-            case DBus.RequestNameReply.ALREADY_OWNER:
-                zavai.log.info("I already own the name " + bus_name + " but I do not remember asking for it");
-                break;
-        }
-    }
-
-    public void shutdown()
-    {
-        // Shutdown in reverse registration order
-        for (weak List<Resource> i = resources; i != null; i = i.next)
-            i.data.shutdown();
-    }
-
-    public void register(Resource obj)
-    {
-        resources.prepend(obj);
-    }
-}
-
-public zavai.Registry registry;
-
-}
-
diff --git a/zavai/uevent.vala b/zavai/uevent.vala
deleted file mode 100644 (file)
index b9475ae..0000000
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * uevent - zavai uevent handling
- *
- * Copyright (C) 2009  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 uevent {
-
-class UEvent : Service
-{
-    protected IOChannel sock;
-    protected uint sock_watch = 0;
-    public Omhacks.UEvent.Event event_data;
-    public signal void event();
-
-    public UEvent()
-    {
-        event_data = Omhacks.UEvent.Event();
-    }
-
-    protected bool on_input_data(IOChannel source, IOCondition condition)
-    {
-        if (condition != IOCondition.IN) return true;
-
-        Omhacks.UEvent.read(sock.unix_get_fd(), ref event_data);
-        event();
-
-        return true;
-    }
-
-    /// Activate the service
-    protected override void start()
-    {
-        if (started) return;
-
-        int sock_fd = Omhacks.UEvent.open();
-        if (sock_fd < 0)
-        {
-            zavai.log.error("UEvent: error getting socket");
-            return;
-        }
-
-        sock = new IOChannel.unix_new(sock_fd);
-        sock_watch = sock.add_watch(IOCondition.IN, on_input_data);
-
-        base.start();
-    }
-
-    /// Deactivate the service
-    protected override void stop()
-    {
-        if (!started) return;
-        Source.remove(sock_watch);
-        try {
-            sock.shutdown(false);
-        } catch (IOChannelError e) {
-            zavai.log.error("When closing UEvent socket: " + e.message);
-        }
-        sock = null;
-        base.stop();
-    }
-}
-
-UEvent uevent;
-
-public void init()
-{
-    if (Posix.getuid() == 0)
-        uevent = new UEvent();
-    else
-        uevent = null;
-}
-
-}
-}
diff --git a/zavai/wifi.vala b/zavai/wifi.vala
deleted file mode 100644 (file)
index 55cf1cc..0000000
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * wifi - wifi resource for zavai
- *
- * 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 wifi {
-
-public class Wifi: zavai.ScriptService
-{
-    public Wifi()
-    {
-        Object(name: "wifi");
-        started = script_status();
-    }
-
-    /// Start wifi
-    public override void start()
-    {
-        if (started) return;
-        if (!script_start()) return;
-        zavai.log.info("wifi turned on");
-        base.start();
-    }
-
-    // Release usage of wifi
-    public override void stop()
-    {
-        if (!started) return;
-        script_stop();
-        base.stop();
-    }
-}
-
-public Wifi wifi = null;
-
-public void init()
-{
-    wifi = new Wifi();
-
-}
-
-}
-}
diff --git a/zavai/x11.vapi b/zavai/x11.vapi
deleted file mode 100644 (file)
index ec8b074..0000000
+++ /dev/null
@@ -1,883 +0,0 @@
-/* x11.vapi
- *
- * Copyright (C) 2009  Jürg Billeter
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA
- *
- * Author:
- *     Jürg Billeter <j@bitron.ch>
- */
-
-[CCode (cprefix = "", lower_case_cprefix = "", cheader_filename = "X11/Xlib.h,X11/Xatom.h,X11/Xutil.h")]
-namespace X {
-       // Note: must be called before opening a display or calling any other Xlib function,
-       // see http://tronche.com/gui/x/xlib/display/XInitThreads.html
-       [CCode (cname = "XInitThreads")]
-       public Status init_threads ();
-
-       [Compact]
-       [CCode (cname = "Display", ref_function = "", unref_function = "")]
-       public class Display {
-               [CCode (cname = "XOpenDisplay")]
-               public Display (string? name = null);
-
-               [CCode (cname = "XGetAtomName")]
-               public string get_atom_name(Atom a);
-
-               [CCode (cname = "XAllPlanes")]
-               public static ulong get_all_planes ();
-
-               [CCode (cname = "XAddToSaveSet")]
-               public int add_to_save_set (Window w);
-
-               [CCode (cname = "XAllowEvents")]
-               public int allow_events (int event_mode, int time);
-
-               [CCode (cname = "XBitmapBitOrder")]
-               public int bitmap_bit_order ();
-
-               [CCode (cname = "XBitmapUnit")]
-               public int bitmap_scanline_unit ();
-
-               [CCode (cname = "XBitmapPad")]
-               public int bitmap_scanline_padding ();
-
-               [CCode (cname = "XChangeProperty")]
-               public int change_property (Window w, Atom property, Atom type, int format, int mode, [CCode (array_length = false)] uchar[] data, int nelements);
-
-               [CCode (cname = "XChangeWindowAttributes")]
-               public int change_window_attributes (Window w, ulong valuemask, SetWindowAttributes attributes);
-
-               [CCode (cname = "XConfigureWindow")]
-               public int configure_window (Window w, uint value_mask, WindowChanges values);
-
-               [CCode (cname = "ConnectionNumber")]
-               public int connection_number ();
-
-               [CCode (cname = "DefaultRootWindow")]
-               public Window default_root_window ();
-
-               [CCode (cname = "XDefaultScreenOfDisplay")]
-               public unowned Screen default_screen ();
-
-               [CCode (cname = "XScreenOfDisplay")]
-               public unowned Screen screen_by_id (int screen_number);
-
-               [CCode (cname = "DisplayString")]
-               public string display_string ();
-
-               [CCode (cname = "XQLength")]
-               public int event_queue_length ();
-
-               [CCode (cname = "XFlush")]
-               public int flush ();
-
-               [CCode (cname = "XGetKeyboardMapping", array_length = false)]
-               public weak uint[] get_keyboard_mapping (uint first_keycode, int keycode_count, ref int keysyms_per_keycode_return);
-
-               [CCode (cname = "XGetModifierMapping")]
-               public ModifierKeymap get_modifier_mapping ();
-
-               [CCode (cname = "XGetSelectionOwner")]
-               public Window get_selection_owner (Atom selection);
-
-               [CCode (cname = "XGetWindowAttributes")]
-               public void get_window_attributes (Window w, out WindowAttributes window_attributes_return);
-
-               [CCode (cname = "XGetWindowProperty")]
-               public int get_window_property (Window w, Atom property, long long_offset, long long_length, bool delete, Atom req_type, out Atom actual_type_return, out int actual_format_return, out ulong nitems_return, out ulong bytes_after_return, out void* prop_return);
-
-               [CCode (cname = "XGrabButton")]
-               public int grab_button (uint button, uint modifiers, Window grab_window, bool owner_events, uint event_mask, int pointer_mode, int keyboard_mode, Window confine_to, uint cursor);
-
-               [CCode (cname = "XGrabKey")]
-               public int grab_key (int keycode, uint modifiers, Window grab_window, bool owner_events, int pointer_mode, int keyboard_mode);
-
-               [CCode (cname = "XGrabPointer")]
-               public int grab_pointer (Window grab_window, bool owner_events, uint event_mask, int pointer_mode, int keyboard_mode, Window confine_to, uint cursor, int time);
-
-               [CCode (cname = "XGrabServer")]
-               public int grab_server ();
-
-               [CCode (cname = "XImageByteOrder")]
-               public int image_byte_order ();
-
-