add_subdirectory(gtkfisheyelist)
add_subdirectory(polygen)
add_subdirectory(player)
+add_subdirectory(zavai)
add_subdirectory(src)
#add_subdirectory(hooks)
http://git.freesmartphone.org/?p=specs.git;a=blob_plain;f=html/index.html;hb=HEAD
* Features to add:
+ - if GPS time is more than 1 minute and less than 1 hour different than the
+ system time, automatically sync it
+ if GPS time is more than 1 hour different than the system time, show a
+ "SYNC" button that will sync it if pressed
- log
- write data to disk as log happens (to have at least partial logs if power
is cut)
- more detailed GPX data (dop, elev..)
- message (structured) (json?)
+ - flash aux when there are unacknowledged log entries
- turn on/off gsm
+ start frameworkd as a subprocess, configured to only do phone
+ go through the dbus motions of turning on this and that, and entering PIN
hardcoded in zavai config
+ GSM status on main screen (with messages while coming online, and
operator, power and so on)
- - log and refuse incoming calls and messages
+ - log incoming messages
+ - log and refuse incoming calls
to "move" the GSM device to my laptop:
socat FILE:/dev/ttySAC0 TCP-LISTEN:12345,bind=192.168.0.202
socat TCP:192.168.0.202:12345 PTY,link=/tmp/gps,raw,echo=0
-
- alarm
+ play sound at alarm trigger
- leave expired alarm on screen until acknowledged
- audio notes
- record audio notes, logging start and stop so it gets an associated GPX
- shortcut icon in main screen
- - check gobject introspection and dynamic loading
- - there could be a basic loader core that just dynamically loads bits as
- available/needed. Only the battery icon and calendar can be loaded on a
- laptop, while on the moko one can also load the power menu.
- Different bits can effectively work as plugins, to be there or not.
- Alternative plugins can be loaded based on different technologies, too (a
- gpsd satellite monitor, or a fso satellite monitor).
- zavai does not look good in landscape mode
- replace menus with a widget taking a list of actions, which then lays
them out according to the screen size
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)
+set(VALA_PACKAGES ${packages} posix linux-input dbus-extra gtkfisheyelist libzavai)
set(VFLAGS --vapidir=${zavai_SOURCE_DIR} --vapidir=${gtkfisheyelist_BINARY_DIR})
add_definitions(-Wall)
# -Werror
message("-- Not using devkit-power-gobject")
endif ()
+set(VFLAGS ${VFLAGS} --vapidir=${zavai_BINARY_DIR} --vapidir=${libzavai_SOURCE_DIR} --vapidir=${libzavai_BINARY_DIR})
+
file(GLOB libvala [a-y]*.vala widgets/*.vala)
-add_vala_library(libzavai ${libvala})
-add_library(libzavai STATIC ${libzavai_CSOURCES})
+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})
-set(VFLAGS ${VFLAGS} --vapidir=${zavai_BINARY_DIR})
-set(VALA_PACKAGES ${VALA_PACKAGES} libzavai)
-link_libraries(gtkfisheyelist-static 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} -I${libzavai_BINARY_DIR})
+set(VALA_PACKAGES ${VALA_PACKAGES} libzavai libzavaiui)
+link_libraries(gtkfisheyelist-static libzavai libzavaiui)
file(GLOB zavala zavai.vala)
add_vala_program(zavai ${zavala})
show_all();
}
}
-
- 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 abstract class Applet : Gtk.VBox, Resource
}
*/
try {
- zavai.app.run_script("pm-suspend");
+ zavai.config.run_script("pm-suspend");
done = true;
zavai.log.info("Suspend was done with zavai.");
} catch (Error e) {
{
try {
//usage.Shutdown();
- zavai.app.run_script("shutdown -h now");
+ zavai.config.run_script("shutdown -h now");
} catch (Error e) {
zavai.log.error("Shutting down phone: " + e.message);
}
{
try {
//usage.Reboot();
- zavai.app.run_script("shutdown -r now");
+ zavai.config.run_script("shutdown -r now");
} catch (Error e) {
zavai.log.error("Rebooting phone: " + e.message);
}
// FIXME: X won't see events, but it's still generating interrupts,
// isn't it?
- int EVIOCGRAB = 0x40044590;
- if (Posix.ioctl(screen_lock_fd, EVIOCGRAB, locked ? 1 : 0) != 0)
+ if (Posix.ioctl(screen_lock_fd, LinuxInput.Evio.CGRAB, locked ? 1 : 0) != 0)
{
zavai.log.error("Cannot EVIOCGRAB /dev/input/event1");
Posix.close(screen_lock_fd);
public void wiggle()
{
try {
- zavai.app.run_script(zavai.config.homedir + "/display wiggle");
+ zavai.config.run_script(zavai.config.homedir + "/display wiggle");
} catch (Error e) {
zavai.log.error("Requesting/releasing resource Display: " + e.message);
}
if (!started)
{
try {
- zavai.app.run_script(zavai.config.homedir + "/display lock_off");
+ zavai.config.run_script(zavai.config.homedir + "/display lock_off");
} catch (GLib.Error e) {
zavai.log.error(e.message);
}
public void unlock_screen()
{
try {
- zavai.app.run_script(zavai.config.homedir + "/display defaults");
+ zavai.config.run_script(zavai.config.homedir + "/display defaults");
} catch (GLib.Error e) {
zavai.log.error(e.message);
}
{
if (started) return;
try {
- zavai.app.run_script(zavai.config.homedir + "/display lock_on");
+ zavai.config.run_script(zavai.config.homedir + "/display lock_on");
zavai.log.info("Acquired display");
base.start();
} catch (GLib.Error e) {
{
if (!started) return;
try {
- zavai.app.run_script(zavai.config.homedir + "/display defaults");
+ zavai.config.run_script(zavai.config.homedir + "/display defaults");
zavai.log.info("Released display");
base.stop();
} catch (GLib.Error e) {
+++ /dev/null
-/*
- * 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();
-
-}
+++ /dev/null
-/*
- * 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);
-}
-
-}
-}
+++ /dev/null
-/*
- * 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();
-
-}
-
-}
-}
+++ /dev/null
-/*
- * 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();
-}
-
-}
-}
+++ /dev/null
-/*
- * 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 Config config = null;
-
-}
+++ /dev/null
-/*
- * 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.app.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.app.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.app.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.app.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.app.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()
- {
- }
- */
-}
-
-}
+++ /dev/null
-namespace DBus {
- [CCode (cname = "dbus_bus_get_unique_name")]
- public unowned string bus_get_unique_name (DBus.RawConnection conn);
-}
-
+++ /dev/null
-/* 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);
-}
--- /dev/null
+# gps - gps resource for zavai
+#
+# 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
+
+#import sys
+import os
+import os.path
+import time
+import dbus
+import zavai
+
+class GPSMonitor(zavai.Service):
+ def __init__(self, gps):
+ super(GPSMonitor, self).__init__(["satellites"])
+
+ self.gps = gps
+ self.gps_ubx = gps.gps_ubx
+
+ # This piece of machinery is taken from Zhone
+ self.debug_busy = None
+ self.debug_want = set( ["NAV-STATUS", "NAV-SVINFO"] )
+ self.debug_have = set()
+ self.debug_error = set()
+
+ def debug_update(self):
+ if self.debug_busy is None:
+ pending = self.debug_want - self.debug_have - self.debug_error
+ if pending:
+ self.debug_busy = pending.pop()
+ self.gps_ubx.SetDebugFilter(
+ self.debug_busy,
+ True,
+ reply_handler=self.on_debug_reply,
+ error_handler=self.on_debug_error,
+ )
+
+ def debug_request(self):
+ self.debug_have = set()
+ self.debug_update()
+
+ def on_debug_reply(self):
+ self.debug_have.add(self.debug_busy)
+ self.debug_busy = None
+ self.debug_update()
+
+ def on_debug_error(self, e):
+ zavai.info(e, "error while requesting debug packet %s" % self.debug_busy)
+ self.debug_error.add(self.debug_busy)
+ self.debug_busy = None
+ self.debug_update()
+
+ def on_satellites_changed(self, satellites):
+ zavai.info("gps monitor: satellites changed")
+ self.debug_request()
+
+ def on_ubxdebug_packet(self, clid, length, data):
+ zavai.info("gps monitor: UBX debug packet")
+ self.notify("satellites", clid, length, data)
+
+ def start(self):
+ self.gps.connect("gps", self)
+ # TODO: find out how come sometimes these events are not sent
+ self.gps.bus.add_signal_receiver(
+ self.on_satellites_changed, 'SatellitesChanged', 'org.freedesktop.Gypsy.Satellite',
+ 'org.freesmartphone.ogpsd', '/org/freedesktop/Gypsy')
+ self.gps.bus.add_signal_receiver(
+ self.on_ubxdebug_packet, 'DebugPacket', 'org.freesmartphone.GPS.UBX',
+ 'org.freesmartphone.ogpsd', '/org/freedesktop/Gypsy')
+ self.debug_request()
+
+ def stop(self):
+ self.gps.bus.remove_signal_receiver(
+ self.on_satellites_changed, 'SatellitesChanged', 'org.freedesktop.Gypsy.Satellite',
+ 'org.freesmartphone.ogpsd', '/org/freedesktop/Gypsy')
+ self.gps.bus.remove_signal_receiver(
+ self.on_ubxdebug_packet, 'DebugPacket', 'org.freesmartphone.GPS.UBX',
+ 'org.freesmartphone.ogpsd', '/org/freedesktop/Gypsy')
+ self.gps.disconnect("gps", self)
+
+
+class GPSPosition(zavai.Service):
+ def __init__(self, gps):
+ super(GPSPosition, self).__init__(["position"])
+ self.gps = gps
+
+ def on_position_changed(self, fields, tstamp, lat, lon, alt):
+ zavai.info("gps position: position changed")
+ self.notify("position", fields, tstamp, lat, lon, alt)
+
+ def start(self):
+ self.gps.connect("gps", self)
+ self.gps.bus.add_signal_receiver(
+ self.on_position_changed, 'PositionChanged', 'org.freedesktop.Gypsy.Position',
+ 'org.freesmartphone.ogpsd', '/org/freedesktop/Gypsy')
+
+ def stop(self):
+ self.gps.bus.remove_signal_receiver(
+ self.on_position_changed, 'PositionChanged', 'org.freedesktop.Gypsy.Position',
+ 'org.freesmartphone.ogpsd', '/org/freedesktop/Gypsy')
+ self.gps.disconnect("gps", self)
+
+# For a list of dbus services, look in /etc/dbus-1/system.d/
+class GPS(zavai.Service):
+ def __init__(self, registry, name):
+ super(GPS, self).__init__(["gps"])
+
+ self.bus = registry.resource("dbus.system_bus")
+
+ # see mdbus -s org.freesmartphone.ousaged /org/freesmartphone/Usage
+ self.usage = self.bus.get_object('org.freesmartphone.ousaged', '/org/freesmartphone/Usage')
+ self.usage = dbus.Interface(self.usage, "org.freesmartphone.Usage")
+
+ # see mdbus -s org.freesmartphone.ogpsd /org/freedesktop/Gypsy
+ gps = self.bus.get_object('org.freesmartphone.ogpsd', '/org/freedesktop/Gypsy')
+ self.gps = dbus.Interface(gps, "org.freedesktop.Gypsy.Device")
+ self.gps_time = dbus.Interface(gps, "org.freedesktop.Gypsy.Time")
+ self.gps_position = dbus.Interface(gps, 'org.freedesktop.Gypsy.Position')
+ self.gps_ubx = dbus.Interface(gps, 'org.freesmartphone.GPS.UBX')
+
+ self.monitor = GPSMonitor(self)
+ self.position = GPSPosition(self)
+
+ def start(self):
+ """Request GPS resource"""
+ self.usage.RequestResource('GPS')
+ zavai.info("Acquired GPS")
+
+ def stop(self):
+ """Release usage of GPS"""
+ self.usage.ReleaseResource('GPS')
+ zavai.info("Released GPS")
+
+# def wait_for_fix(self, callback):
+# status = self.gps.GetFixStatus()
+# if status in [2, 3]:
+# zavai.info("We already have a fix, good.")
+# callback()
+# return True
+# else:
+# zavai.info("Waiting for a fix...")
+# self.waiting_for_fix = callback
+# self.bus.add_signal_receiver(
+# self.on_fix_status_changed, 'FixStatusChanged', 'org.freedesktop.Gypsy.Device',
+# 'org.freesmartphone.ogpsd', '/org/freedesktop/Gypsy')
+# return False
+#
+# def on_fix_status_changed(self, status):
+# if status not in [2, 3]: return
+#
+# zavai.info("Got GPS fix")
+# self.bus.remove_signal_receiver(
+# self.on_fix_status_changed, 'FixStatusChanged', 'org.freedesktop.Gypsy.Device',
+# 'org.freesmartphone.ogpsd', '/org/freedesktop/Gypsy')
+#
+# if self.waiting_for_fix:
+# self.waiting_for_fix()
+# self.waiting_for_fix = None
+#
+
+# 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()
+#
+
+class GPX(zavai.Service):
+ "Write GPX track and waypoint files"
+ def __init__(self, registry, name):
+ super(GPX, self).__init__(["gpx"])
+ self.registry = registry
+ self.trk = None
+ self.wpt = None
+ self.last_pos = None
+ conf = registry.resource("conf")
+ self.trackdir = conf.homedir
+ self.activity_monitors = set()
+
+ def add_activity_monitor(self, cb):
+ self.activity_monitors.add(cb)
+ cb(self, self.last_pos is not None)
+
+ def del_activity_monitor(self, cb):
+ self.activity_monitors.discard(cb)
+
+ def notify_activity_monitors(self):
+ for mon in self.activity_monitors:
+ mon(self, self.last_pos is not None)
+
+ def start(self):
+ zavai.info("Starting GPX trace subsystem")
+ gps = self.registry.resource("gps")
+ gps.position.connect("position", self.on_position_changed)
+
+ def stop(self):
+ zavai.info("Stopping GPX trace subsystem")
+ gps = self.registry.resource("gps")
+ gps.position.disconnect("position", self.on_position_changed)
+ self.stop_track()
+
+ def on_position_changed(self, fields, tstamp, lat, lon, alt):
+ self.last_pos = (fields, tstamp, lat, lon, alt)
+ self.trackpoint()
+
+ def start_track(self, tstamp = None, basename = None):
+ if basename is not None:
+ self.basename = basename
+ elif tstamp is not None:
+ # Compute basename for output files
+ self.basename = time.strftime("%Y-%m-%d-%H-%M-%S", time.localtime(tstamp))
+ self.basename = os.path.join(self.trackdir, self.basename)
+
+ self.trk = open(self.basename + "-trk.gpx", "wt")
+ print >>self.trk, """<?xml version="1.0" encoding="UTF-8"?>
+<gpx
+ version="1.0"
+ creator="audiomap %s"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns="http://www.topografix.com/GPX/1/0"
+ xsi:schemaLocation="http://www.topografix.com/GPX/1/0 http://www.topografix.com/GPX/1/0/gpx.xsd">
+ <trk>
+ <trkseg>""" % zavai.VERSION
+
+ self.wpt = open(self.basename + "-wpt.gpx", "wt")
+ print >>self.wpt, """<?xml version="1.0" encoding="UTF-8"?>
+<gpx
+ version="1.0"
+ creator="audiomap %s"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns="http://www.topografix.com/GPX/1/0"
+ xsi:schemaLocation="http://www.topografix.com/GPX/1/0 http://www.topografix.com/GPX/1/0/gpx.xsd">""" % zavai.VERSION
+
+ self.wpt_seq = 1;
+ self.notify_activity_monitors()
+
+ def stop_track(self):
+ if self.trk is not None:
+ print >>self.trk, "</trkseg></trk></gpx>"
+ self.trk.close()
+ self.trk = None
+ if self.wpt is not None:
+ print >>self.wpt, "</gpx>"
+ self.wpt.close()
+ self.wpt = None
+ self.last_pos = None
+ self.notify_activity_monitors()
+
+ def trackpoint(self):
+ "Mark a track point"
+ if self.last_pos is None:
+ return
+
+ fields, tstamp, lat, lon, ele = self.last_pos
+
+ if not self.trk:
+ self.start_track(tstamp)
+
+ print >>self.trk, """<trkpt lat="%f" lon="%f">
+ <time>%s</time>
+ <ele>%f</ele>""" % (lat, lon, time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime(tstamp)), ele)
+ #if course is not None: print >>self.trk, " <course>%f</course>" % course
+ #if speed is not None: print >>self.trk, " <speed>%f</speed>" % speed
+ #if fix is not None: print >>self.trk, " <fix>%f</fix>" % fix
+ #if hdop is not None: print >>self.trk, " <hdop>%f</hdop>" % hdop
+ print >>self.trk, "</trkpt>"
+
+ def waypoint(self, name = None):
+ "Mark a waypoint"
+ if self.last_pos is None:
+ return
+
+ fields, tstamp, lat, lon, ele = self.last_pos
+
+ if not self.wpt:
+ self.start_track(tstamp)
+
+ if name is None:
+ name = "wpt_%d" % self.wpt_seq
+ self.wpt_seq += 1
+
+ print >>self.wpt, """<wpt lat="%f" lon="%f">
+ <name>%s</name>
+ <time>%s</time>
+ <ele>%f</ele>
+</wpt>""" % (
+ lat, lon, name, time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime(tstamp)), ele)
+
+
+# def record(self):
+# self.audio = Audio(self.make_waypoint)
+# self.gps = GPS()
+# # Get a fix and start recording
+# if not self.gps.wait_for_fix(self.start_recording):
+# self.gps_monitor = GPSMonitor(self.gps)
+# self.gps_monitor.start()
+#
+# def monitor(self):
+# self.audio = None
+# self.gps = GPS()
+# self.gps_monitor = GPSMonitor(self.gps)
+# self.gps_monitor.start()
+#
+#
+# def make_waypoint(self):
+# if self.gpx is None:
+# return
+# if self.last_pos is None:
+# self.last_pos = self.gps.gps_position.GetPosition()
+# (fields, tstamp, lat, lon, alt) = self.last_pos
+# self.gpx.waypoint(tstamp, lat, lon, alt)
+# zavai.info("Making waypoint at %s: %f, %f, %f" % (
+# time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(tstamp)), lat, lon, alt))
+++ /dev/null
-/*
- * 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();
-
-}
-
-}
-}
+++ /dev/null
-/*
- * gsm - gsm resource for zavai
- *
- * 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 gsm {
-
-// Isolate here the insane loops we need to go through to turn on the bloody
-// gsm
-protected class GSMActivator : Object
-{
- public dynamic DBus.Object device;
- public dynamic DBus.Object network;
- public dynamic DBus.Object sim;
-
- public signal void status_changed(string message);
-
- public GSMActivator()
- {
- device = null;
- network = null;
- sim = null;
- }
-
- public void begin()
- {
- if (device == null)
- {
- device = zavai.registry.sbus.get_object(
- "org.freesmartphone.ogsmd",
- "/org/freesmartphone/GSM/Device",
- "org.freesmartphone.GSM.Device");
- network = zavai.registry.sbus.get_object(
- "org.freesmartphone.ogsmd",
- "/org/freesmartphone/GSM/Device",
- "org.freesmartphone.GSM.Network");
- sim = zavai.registry.sbus.get_object(
- "org.freesmartphone.ogsmd",
- "/org/freesmartphone/GSM/Device",
- "org.freesmartphone.GSM.SIM");
- }
-
- status_changed("Turning on antenna");
- device.SetAntennaPower(true, on_antenna_power);
- }
-
- protected void on_antenna_power(Error e)
- {
- if (e != null)
- {
- zavai.log.warning("on_antenna_power: " + 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, () => {
- device.SetAntennaPower(true, on_antenna_power);
- return false;
- });
- } else {
- status_changed("Checking if PIN is required");
- sim.GetAuthStatus(on_auth_status);
- }
- return;
- }
- zavai.log.warning("on_antenna_power ok");
- status_changed("Registering with network");
- network.Register(on_network_register);
- }
-
- protected void on_network_register(Error e)
- {
- if (e != null)
- {
- zavai.log.warning("on_network_register: " + e.message);
- return;
- }
- status_changed("Registered with network");
- }
-
- protected void on_auth_status(string status, Error e)
- {
- if (e != null)
- {
- zavai.log.warning("on_auth_status: " + e.message);
- return;
- }
- zavai.log.info("on_auth_status: " + status);
- if (status == "READY")
- {
- status_changed("PIN ok");
- device.SetAntennaPower(true, on_antenna_power);
- }
- else if (status == "SIM PIN")
- {
- status_changed("Sending PIN");
- sim.SendAuthCode(zavai.config.sim_pin, on_auth_code);
- }
- else
- zavai.log.debug("Unknown status: " + status);
- }
-
- protected void on_auth_code(Error e)
- {
- if (e != null)
- {
- zavai.log.warning("on_auth_code: " + e.message);
- return;
- }
- status_changed("PIN OK");
- }
-}
-
-public class GSM: zavai.ScriptMonitorService
-{
- protected dynamic DBus.Object dbus;
- public dynamic DBus.Object call;
- protected GSMActivator activator;
-
- public signal void status_changed(string message);
-
- public GSM()
- {
- Object(name: "gsm");
-
- activator = new GSMActivator();
- activator.status_changed += (msg) => { status_changed(msg); };
-
- call = null;
-
- dbus = zavai.registry.sbus.get_object(
- "org.freedesktop.DBus",
- "/org/freedesktop/DBus",
- "org.freedesktop.DBus");
- dbus.NameOwnerChanged += on_name_owner_changed;
- }
-
- /// Request GPS resource
- public override void start()
- {
- if (started) return;
-
- status_changed("Starting");
-
- script_start();
-
- call = zavai.registry.sbus.get_object(
- "org.freesmartphone.ogsmd",
- "/org/freesmartphone/GSM/Device",
- "org.freesmartphone.GSM.Call");
-
- 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");
- activator.begin();
- }
- }
-
- // Release usage of GPS
- public override void stop()
- {
- if (!started) return;
-
- script_stop();
- }
-
- protected override void cleanup_after_script_stop()
- {
- call = null;
- }
-}
-
-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();
-}
-
-}
-}
+++ /dev/null
-/*
- * 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();
-}
-
-}
-}
+++ /dev/null
-[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);
- }
- */
-}
+++ /dev/null
-[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);
- }
-}
+++ /dev/null
-[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
- }
-}
+++ /dev/null
-/*
- * 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();
-}
-
-}
-}
+++ /dev/null
-/usr/share/vala/vapi/lua.vapi
\ No newline at end of file
+++ /dev/null
-/*
- * 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 {
-
-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();
- }
- }
- }
-}
-
-Power power;
-
-public void init()
-{
- power = new Power();
-}
-
-}
-}
+++ /dev/null
-/*
- * 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;
-
-}
-
+++ /dev/null
-/*
- * 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;
-}
-
-}
-}
+++ /dev/null
-/*
- * 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();
-
-}
-
-}
-}
+++ /dev/null
-/* 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;
-}
-
zavai.ui.main.init();
zavai.ui.gps.init();
zavai.ui.gsm.init();
- zavai.app.run_script(zavai.config.homedir + "/display init");
+ zavai.config.run_script(zavai.config.homedir + "/display init");
zavai.ui.power.init();
zavai.ui.aux.init();
zavai.ui.kbd.init();
+++ /dev/null
-# zavai shared code
-#
-# 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
-
-from conf import read_config
-from config import Config
-from plugins import load_plugins
-from registry import Registry, Resource, Service, get_parent, default_label
-from menu import Menu, MenuButton, LinkButton, ToggleButton
-from app import Zavai, Applet
-from gps import GPS, GPX
-from audio import Audio, Recorder
-
-VERSION="0.1"
-
-def warn(*args):
- import sys
- sys.stderr.write(" ".join(map(str, args)) + "\n")
-def info(*args):
- import sys
- sys.stderr.write(" ".join(map(str, args)) + "\n")
-
-def set_quiet():
- def info(*args):
- pass
-
+++ /dev/null
-# 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
-
-import sys
-from gettext import gettext as _
-import gtk, gobject
-import zavai
-
-class Zavai(gtk.Window, zavai.Resource):
- def __init__(self, registry, name):
- super(Zavai, self).__init__()
- self.registry = registry
- self.current = None
- self.activate_resource("menu.main")
-
- def activate_resource(self, name):
- widget = self.registry.resource(name)
- if widget is None:
- widget = self.registry.resource("menu.main")
- if isinstance(widget, gtk.Action):
- widget.activate()
- else:
- self.show_widget(name, widget)
-
- def show_widget(self, name, widget):
- # Remove the current widget.
- # If it is an Applet, stop it
- if self.current is not None:
- cur = self.registry.resource(self.current)
- if isinstance(cur, zavai.Applet):
- cur.stop()
- self.remove(self.get_child())
- self.current = None
-
- # Add the new widget. If it is an applet, start it
- self.add(widget)
- self.current = name
- if isinstance(widget, zavai.Applet):
- widget.start()
- widget.show_all()
-
- def run(self):
- self.set_size_request(100, 200)
- #self.fullscreen()
- self.show_all()
- gtk.main()
-
-class Applet(gtk.VBox):
- name = gobject.property(type=str)
- label = gobject.property(type=str)
-
- def __init__(self, registry, name, label = None):
- super(Applet, self).__init__()
-
- self.zavai_registry = registry
-
- self.props.name = name
- if label is None:
- self.props.label = zavai.default_label(name)
- else:
- self.props.label = label
-
- self.back_link = zavai.LinkButton(registry, zavai.get_parent(name), _("Back"))
- self.pack_end(self.back_link, False, False)
-
- def add(self, widget):
- self.pack_start(widget, True, True)
-
- def shutdown(self):
- self.stop()
-
- def start(self, *args):
- pass
-
- def stop(self, *args):
- pass
--- /dev/null
+/*
+ * 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();
+
+}
+++ /dev/null
-# audio - zavai audio resource
-#
-# 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
-
-import zavai
-import struct
-import gobject
-import os
-import os.path
-import subprocess
-import signal
-#import sys
-#import time
-#import dbus
-
-class Recorder(zavai.Resource):
- def __init__(self, registry):
- super(Recorder, self).__init__()
- self.registry = registry
- self.recorder = None
-
- def shutdown(self):
- self.stop()
-
- def start(self, filename):
- if self.recorder is not None: return
-
- self.registry.resource("audio").connect("audio", self)
-
- self.recorder = subprocess.Popen(
- ["arecord", "-D", "hw", "-f", "cd", "-r", "8000", "-t", "wav", filename])
-
- def stop(self):
- if self.recorder is None: return
-
- os.kill(self.recorder.pid, signal.SIGINT)
- self.recorder.wait()
- self.recorder = None
-
- self.registry.resource("audio").disconnect("audio", self)
-
-
-# TODO:
-# - hook into the headset plugged/unplugged event
-# - if unplugged, turn on handset microphone
-# - if plugged, redo headest mixer settings
-class Audio(zavai.Service):
- "Handle mixer settings, audio recording and headset button presses"
- def __init__(self, registry, name):
- super(Audio, self).__init__(["audio", "button", "jack"])
-
- conf = registry.resource("conf")
- self.saved_scenario = os.path.join(conf.homedir, "audiomap.state")
-
- self.input_fd = None
- self.input_watch = None
-
-
- def start(self):
- # 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(force = True)
- else:
- self.mixer_for_handset(force = True)
-
- # Watch the event device
- 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.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
-#
-# self.recorder = None
-# self.basename = None
-
- def stop(self):
- # Stop watching the event device
- if self.input_fd is None:
- return
- gobject.source_remove(self.input_watch)
- self.input_watch = None
- self.input_fd.close()
- self.input_fd = None
-
- # Restore mixer settings
- self.load_scenario(self.saved_scenario)
-
- def on_input_data(self, source, condition):
- buf = self.input_fd.read(16)
- ts1, ts2, type, code, value = struct.unpack("LLHHI", buf)
- if type == 1 and code == 119:
- if self.last_button_press + 1 < ts1:
- self.last_button_press = ts1
- else:
- return True
- if value:
- zavai.info("Headset button release")
- self.notify("button", False)
- else:
- zavai.info("Headset button press")
- self.notify("button", True)
- elif type == 5 and code == 2:
- if value:
- zavai.info("Headset plugged in")
- self.mixer_for_headset()
- self.notify("jack", True)
- else:
- zavai.info("Headset plugged out")
- self.mixer_for_handset()
- self.notify("jack", False)
- return True
-
- def mixer_for_headset(self, force=False):
- if not force and self.has_headset: return
- zavai.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
- zavai.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_levels(self):
-# self.recorder = subprocess.Popen(
-# ["arecord", "-D", "hw", "-f", "cd", "-r", "8000", "-t", "wav", "-V", "stereo", "/dev/null"])
-
- def save_scenario(self, name):
- while True:
- res = subprocess.call(["alsactl", "store", "-f", name])
- if res == 0: return
- if res > 0:
- raise RuntimeError("Saving audio scenario to '%s' failed" % name)
-
- def load_scenario(self, name):
- while True:
- res = subprocess.call(["alsactl", "restore", "-f", name])
- if res == 0: return
- if res > 0:
- raise RuntimeError("Loading audio scenario '%s' failed with error %d" % (name, res))
-
- def mixer_set(self, name, *args):
- args = map(str, args)
- while True:
- res = subprocess.call(["amixer", "-q", "set", name] + args)
- if res == 0: return
- if res > 0:
- raise RuntimeError("Setting mixer '%s' to %s failed with error %d" % (name, " ".join(args), res))
-
- def mixer_set_many(self, *args):
- """Perform many mixer set operations via amixer --stdin"""
- cmd_input = []
- for k, v in args:
- cmd_input.append("sset " + repr(k) + " " + repr(v))
- while True:
- proc = subprocess.Popen(["amixer", "-q", "--stdin"], stdin=subprocess.PIPE)
- (out, err) = proc.communicate(input="\n".join(cmd_input))
- res = proc.wait()
- if res == 0: return
- if res > 0:
- raise RuntimeError("Setting mixer failed with error %d" % res)
-
-
-#class Hub:
-# """Hub that manages all the various resources that we use, and initiates
-# operations."""
-# def __init__(self, bus = None):
-# self.bus = bus
-# self.waiting_for_fix = False
-# self.basename = None
-# self.recorder = None
-# self.gpx = None
-# self.gps = None
-# self.gps_monitor = None
-# self.audio = None
-# self.last_pos = None
-#
-# def shutdown(self):
-# # Stop recording
-# if self.audio is not None:
-# self.audio.close()
-#
-# # Close waypoints file
-# if self.gpx is not None:
-# self.gpx.close()
-#
-# # Stop the GPS monitor
-# if self.gps_monitor:
-# self.gps_monitor.stop()
-#
-# # Release the GPS
-# if self.gps is not None:
-# self.gps.close()
-#
-# def levels(self):
-# self.audio = Audio()
-# self.audio.start_levels()
-#
-# def record(self):
-# self.audio = Audio(self.make_waypoint)
-# self.gps = GPS()
-# # Get a fix and start recording
-# if not self.gps.wait_for_fix(self.start_recording):
-# self.gps_monitor = GPSMonitor(self.gps)
-# self.gps_monitor.start()
-#
-# def monitor(self):
-# self.audio = None
-# self.gps = GPS()
-# self.gps_monitor = GPSMonitor(self.gps)
-# self.gps_monitor.start()
-#
-# 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()
-#
-# def on_position_changed(self, fields, tstamp, lat, lon, alt):
-# self.last_pos = (fields, tstamp, lat, lon, alt)
-# if self.gpx:
-# self.gpx.trackpoint(tstamp, lat, lon, alt)
-#
-# def make_waypoint(self):
-# if self.gpx is None:
-# return
-# if self.last_pos is None:
-# self.last_pos = self.gps.gps_position.GetPosition()
-# (fields, tstamp, lat, lon, alt) = self.last_pos
-# self.gpx.waypoint(tstamp, lat, lon, alt)
-# info("Making waypoint at %s: %f, %f, %f" % (
-# time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(tstamp)), lat, lon, alt))
--- /dev/null
+/*
+ * 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);
+}
+
+}
+}
--- /dev/null
+/*
+ * 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();
+
+}
+
+}
+}
--- /dev/null
+/*
+ * 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();
+}
+
+}
+}
+++ /dev/null
-import os
-import ConfigParser, StringIO
-
-def read_config(rootDir = None, defaults = None, nick="octofuss"):
- """
- Read octofuss configuration, returning a ConfigParser object
- """
- if rootDir == None:
- rootDir = os.environ.get(nick.upper() + "_CONFDIR", "/etc/" + nick)
- files = []
- def trytouse(path):
- if os.path.exists(path):
- files.append(path)
-
- # Start with the main config file
- trytouse(os.path.join(rootDir, nick + ".conf"))
-
- # Add snippets found in rc.d style directory
- subdir = os.path.join(rootDir, nick + ".conf.d")
- if os.path.isdir(subdir):
- for file in sorted(os.listdir(subdir)):
- if file.startswith('#'): continue
- if file.startswith('.'): continue
- if file.endswith('~'): continue
- if file.endswith('.bak'): continue
- trytouse(os.path.join(subdir, file))
-
- config = ConfigParser.ConfigParser()
- if defaults != None:
- infile = StringIO.StringIO(defaults)
- config.readfp(infile, "defaults")
- config.read(files)
- return config
+++ /dev/null
-import os.path
-import zavai
-
-class Config:
- def __init__(self):
- self.conf = zavai.read_config(nick="zavai")
-
- def get(self, section, name, default=None):
- if self.conf.has_section(section):
- if self.conf.has_option(section, name):
- return self.conf.get(section, name)
- return None
-
- def _get_homedir(self):
- res = self.get("global", "home")
- if res is None:
- res = os.path.expanduser("~/.zavai")
- if not os.path.isdir(res):
- zavai.info("Creating directory", res)
- os.makedirs(res)
- return res
-
- homedir = property(_get_homedir)
--- /dev/null
+/*
+ * 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;
+
+}
--- /dev/null
+/*
+ * 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()
+ {
+ }
+ */
+}
+
+}
--- /dev/null
+namespace DBus {
+ [CCode (cname = "dbus_bus_get_unique_name")]
+ public unowned string bus_get_unique_name (DBus.RawConnection conn);
+}
+
--- /dev/null
+/* 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);
+}
+++ /dev/null
-# gps - gps resource for zavai
-#
-# 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
-
-#import sys
-import os
-import os.path
-import time
-import dbus
-import zavai
-
-class GPSMonitor(zavai.Service):
- def __init__(self, gps):
- super(GPSMonitor, self).__init__(["satellites"])
-
- self.gps = gps
- self.gps_ubx = gps.gps_ubx
-
- # This piece of machinery is taken from Zhone
- self.debug_busy = None
- self.debug_want = set( ["NAV-STATUS", "NAV-SVINFO"] )
- self.debug_have = set()
- self.debug_error = set()
-
- def debug_update(self):
- if self.debug_busy is None:
- pending = self.debug_want - self.debug_have - self.debug_error
- if pending:
- self.debug_busy = pending.pop()
- self.gps_ubx.SetDebugFilter(
- self.debug_busy,
- True,
- reply_handler=self.on_debug_reply,
- error_handler=self.on_debug_error,
- )
-
- def debug_request(self):
- self.debug_have = set()
- self.debug_update()
-
- def on_debug_reply(self):
- self.debug_have.add(self.debug_busy)
- self.debug_busy = None
- self.debug_update()
-
- def on_debug_error(self, e):
- zavai.info(e, "error while requesting debug packet %s" % self.debug_busy)
- self.debug_error.add(self.debug_busy)
- self.debug_busy = None
- self.debug_update()
-
- def on_satellites_changed(self, satellites):
- zavai.info("gps monitor: satellites changed")
- self.debug_request()
-
- def on_ubxdebug_packet(self, clid, length, data):
- zavai.info("gps monitor: UBX debug packet")
- self.notify("satellites", clid, length, data)
-
- def start(self):
- self.gps.connect("gps", self)
- # TODO: find out how come sometimes these events are not sent
- self.gps.bus.add_signal_receiver(
- self.on_satellites_changed, 'SatellitesChanged', 'org.freedesktop.Gypsy.Satellite',
- 'org.freesmartphone.ogpsd', '/org/freedesktop/Gypsy')
- self.gps.bus.add_signal_receiver(
- self.on_ubxdebug_packet, 'DebugPacket', 'org.freesmartphone.GPS.UBX',
- 'org.freesmartphone.ogpsd', '/org/freedesktop/Gypsy')
- self.debug_request()
-
- def stop(self):
- self.gps.bus.remove_signal_receiver(
- self.on_satellites_changed, 'SatellitesChanged', 'org.freedesktop.Gypsy.Satellite',
- 'org.freesmartphone.ogpsd', '/org/freedesktop/Gypsy')
- self.gps.bus.remove_signal_receiver(
- self.on_ubxdebug_packet, 'DebugPacket', 'org.freesmartphone.GPS.UBX',
- 'org.freesmartphone.ogpsd', '/org/freedesktop/Gypsy')
- self.gps.disconnect("gps", self)
-
-
-class GPSPosition(zavai.Service):
- def __init__(self, gps):
- super(GPSPosition, self).__init__(["position"])
- self.gps = gps
-
- def on_position_changed(self, fields, tstamp, lat, lon, alt):
- zavai.info("gps position: position changed")
- self.notify("position", fields, tstamp, lat, lon, alt)
-
- def start(self):
- self.gps.connect("gps", self)
- self.gps.bus.add_signal_receiver(
- self.on_position_changed, 'PositionChanged', 'org.freedesktop.Gypsy.Position',
- 'org.freesmartphone.ogpsd', '/org/freedesktop/Gypsy')
-
- def stop(self):
- self.gps.bus.remove_signal_receiver(
- self.on_position_changed, 'PositionChanged', 'org.freedesktop.Gypsy.Position',
- 'org.freesmartphone.ogpsd', '/org/freedesktop/Gypsy')
- self.gps.disconnect("gps", self)
-
-# For a list of dbus services, look in /etc/dbus-1/system.d/
-class GPS(zavai.Service):
- def __init__(self, registry, name):
- super(GPS, self).__init__(["gps"])
-
- self.bus = registry.resource("dbus.system_bus")
-
- # see mdbus -s org.freesmartphone.ousaged /org/freesmartphone/Usage
- self.usage = self.bus.get_object('org.freesmartphone.ousaged', '/org/freesmartphone/Usage')
- self.usage = dbus.Interface(self.usage, "org.freesmartphone.Usage")
-
- # see mdbus -s org.freesmartphone.ogpsd /org/freedesktop/Gypsy
- gps = self.bus.get_object('org.freesmartphone.ogpsd', '/org/freedesktop/Gypsy')
- self.gps = dbus.Interface(gps, "org.freedesktop.Gypsy.Device")
- self.gps_time = dbus.Interface(gps, "org.freedesktop.Gypsy.Time")
- self.gps_position = dbus.Interface(gps, 'org.freedesktop.Gypsy.Position')
- self.gps_ubx = dbus.Interface(gps, 'org.freesmartphone.GPS.UBX')
-
- self.monitor = GPSMonitor(self)
- self.position = GPSPosition(self)
-
- def start(self):
- """Request GPS resource"""
- self.usage.RequestResource('GPS')
- zavai.info("Acquired GPS")
-
- def stop(self):
- """Release usage of GPS"""
- self.usage.ReleaseResource('GPS')
- zavai.info("Released GPS")
-
-# def wait_for_fix(self, callback):
-# status = self.gps.GetFixStatus()
-# if status in [2, 3]:
-# zavai.info("We already have a fix, good.")
-# callback()
-# return True
-# else:
-# zavai.info("Waiting for a fix...")
-# self.waiting_for_fix = callback
-# self.bus.add_signal_receiver(
-# self.on_fix_status_changed, 'FixStatusChanged', 'org.freedesktop.Gypsy.Device',
-# 'org.freesmartphone.ogpsd', '/org/freedesktop/Gypsy')
-# return False
-#
-# def on_fix_status_changed(self, status):
-# if status not in [2, 3]: return
-#
-# zavai.info("Got GPS fix")
-# self.bus.remove_signal_receiver(
-# self.on_fix_status_changed, 'FixStatusChanged', 'org.freedesktop.Gypsy.Device',
-# 'org.freesmartphone.ogpsd', '/org/freedesktop/Gypsy')
-#
-# if self.waiting_for_fix:
-# self.waiting_for_fix()
-# self.waiting_for_fix = None
-#
-
-# 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()
-#
-
-class GPX(zavai.Service):
- "Write GPX track and waypoint files"
- def __init__(self, registry, name):
- super(GPX, self).__init__(["gpx"])
- self.registry = registry
- self.trk = None
- self.wpt = None
- self.last_pos = None
- conf = registry.resource("conf")
- self.trackdir = conf.homedir
- self.activity_monitors = set()
-
- def add_activity_monitor(self, cb):
- self.activity_monitors.add(cb)
- cb(self, self.last_pos is not None)
-
- def del_activity_monitor(self, cb):
- self.activity_monitors.discard(cb)
-
- def notify_activity_monitors(self):
- for mon in self.activity_monitors:
- mon(self, self.last_pos is not None)
-
- def start(self):
- zavai.info("Starting GPX trace subsystem")
- gps = self.registry.resource("gps")
- gps.position.connect("position", self.on_position_changed)
-
- def stop(self):
- zavai.info("Stopping GPX trace subsystem")
- gps = self.registry.resource("gps")
- gps.position.disconnect("position", self.on_position_changed)
- self.stop_track()
-
- def on_position_changed(self, fields, tstamp, lat, lon, alt):
- self.last_pos = (fields, tstamp, lat, lon, alt)
- self.trackpoint()
-
- def start_track(self, tstamp = None, basename = None):
- if basename is not None:
- self.basename = basename
- elif tstamp is not None:
- # Compute basename for output files
- self.basename = time.strftime("%Y-%m-%d-%H-%M-%S", time.localtime(tstamp))
- self.basename = os.path.join(self.trackdir, self.basename)
-
- self.trk = open(self.basename + "-trk.gpx", "wt")
- print >>self.trk, """<?xml version="1.0" encoding="UTF-8"?>
-<gpx
- version="1.0"
- creator="audiomap %s"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xmlns="http://www.topografix.com/GPX/1/0"
- xsi:schemaLocation="http://www.topografix.com/GPX/1/0 http://www.topografix.com/GPX/1/0/gpx.xsd">
- <trk>
- <trkseg>""" % zavai.VERSION
-
- self.wpt = open(self.basename + "-wpt.gpx", "wt")
- print >>self.wpt, """<?xml version="1.0" encoding="UTF-8"?>
-<gpx
- version="1.0"
- creator="audiomap %s"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xmlns="http://www.topografix.com/GPX/1/0"
- xsi:schemaLocation="http://www.topografix.com/GPX/1/0 http://www.topografix.com/GPX/1/0/gpx.xsd">""" % zavai.VERSION
-
- self.wpt_seq = 1;
- self.notify_activity_monitors()
-
- def stop_track(self):
- if self.trk is not None:
- print >>self.trk, "</trkseg></trk></gpx>"
- self.trk.close()
- self.trk = None
- if self.wpt is not None:
- print >>self.wpt, "</gpx>"
- self.wpt.close()
- self.wpt = None
- self.last_pos = None
- self.notify_activity_monitors()
-
- def trackpoint(self):
- "Mark a track point"
- if self.last_pos is None:
- return
-
- fields, tstamp, lat, lon, ele = self.last_pos
-
- if not self.trk:
- self.start_track(tstamp)
-
- print >>self.trk, """<trkpt lat="%f" lon="%f">
- <time>%s</time>
- <ele>%f</ele>""" % (lat, lon, time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime(tstamp)), ele)
- #if course is not None: print >>self.trk, " <course>%f</course>" % course
- #if speed is not None: print >>self.trk, " <speed>%f</speed>" % speed
- #if fix is not None: print >>self.trk, " <fix>%f</fix>" % fix
- #if hdop is not None: print >>self.trk, " <hdop>%f</hdop>" % hdop
- print >>self.trk, "</trkpt>"
-
- def waypoint(self, name = None):
- "Mark a waypoint"
- if self.last_pos is None:
- return
-
- fields, tstamp, lat, lon, ele = self.last_pos
-
- if not self.wpt:
- self.start_track(tstamp)
-
- if name is None:
- name = "wpt_%d" % self.wpt_seq
- self.wpt_seq += 1
-
- print >>self.wpt, """<wpt lat="%f" lon="%f">
- <name>%s</name>
- <time>%s</time>
- <ele>%f</ele>
-</wpt>""" % (
- lat, lon, name, time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime(tstamp)), ele)
-
-
-# def record(self):
-# self.audio = Audio(self.make_waypoint)
-# self.gps = GPS()
-# # Get a fix and start recording
-# if not self.gps.wait_for_fix(self.start_recording):
-# self.gps_monitor = GPSMonitor(self.gps)
-# self.gps_monitor.start()
-#
-# def monitor(self):
-# self.audio = None
-# self.gps = GPS()
-# self.gps_monitor = GPSMonitor(self.gps)
-# self.gps_monitor.start()
-#
-#
-# def make_waypoint(self):
-# if self.gpx is None:
-# return
-# if self.last_pos is None:
-# self.last_pos = self.gps.gps_position.GetPosition()
-# (fields, tstamp, lat, lon, alt) = self.last_pos
-# self.gpx.waypoint(tstamp, lat, lon, alt)
-# zavai.info("Making waypoint at %s: %f, %f, %f" % (
-# time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(tstamp)), lat, lon, alt))
--- /dev/null
+/*
+ * 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();
+
+}
+
+}
+}
--- /dev/null
+/*
+ * gsm - gsm resource for zavai
+ *
+ * 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 gsm {
+
+// Isolate here the insane loops we need to go through to turn on the bloody
+// gsm
+protected class GSMActivator : Object
+{
+ public dynamic DBus.Object device;
+ public dynamic DBus.Object network;
+ public dynamic DBus.Object sim;
+
+ public signal void status_changed(string message);
+
+ public GSMActivator()
+ {
+ device = null;
+ network = null;
+ sim = null;
+ }
+
+ public void begin()
+ {
+ if (device == null)
+ {
+ device = zavai.registry.sbus.get_object(
+ "org.freesmartphone.ogsmd",
+ "/org/freesmartphone/GSM/Device",
+ "org.freesmartphone.GSM.Device");
+ network = zavai.registry.sbus.get_object(
+ "org.freesmartphone.ogsmd",
+ "/org/freesmartphone/GSM/Device",
+ "org.freesmartphone.GSM.Network");
+ sim = zavai.registry.sbus.get_object(
+ "org.freesmartphone.ogsmd",
+ "/org/freesmartphone/GSM/Device",
+ "org.freesmartphone.GSM.SIM");
+ }
+
+ status_changed("Turning on antenna");
+ device.SetAntennaPower(true, on_antenna_power);
+ }
+
+ protected void on_antenna_power(Error e)
+ {
+ if (e != null)
+ {
+ zavai.log.warning("on_antenna_power: " + 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, () => {
+ device.SetAntennaPower(true, on_antenna_power);
+ return false;
+ });
+ } else {
+ status_changed("Checking if PIN is required");
+ sim.GetAuthStatus(on_auth_status);
+ }
+ return;
+ }
+ zavai.log.warning("on_antenna_power ok");
+ status_changed("Registering with network");
+ network.Register(on_network_register);
+ }
+
+ protected void on_network_register(Error e)
+ {
+ if (e != null)
+ {
+ zavai.log.warning("on_network_register: " + e.message);
+ return;
+ }
+ status_changed("Registered with network");
+ }
+
+ protected void on_auth_status(string status, Error e)
+ {
+ if (e != null)
+ {
+ zavai.log.warning("on_auth_status: " + e.message);
+ return;
+ }
+ zavai.log.info("on_auth_status: " + status);
+ if (status == "READY")
+ {
+ status_changed("PIN ok");
+ device.SetAntennaPower(true, on_antenna_power);
+ }
+ else if (status == "SIM PIN")
+ {
+ status_changed("Sending PIN");
+ sim.SendAuthCode(zavai.config.sim_pin, on_auth_code);
+ }
+ else
+ zavai.log.debug("Unknown status: " + status);
+ }
+
+ protected void on_auth_code(Error e)
+ {
+ if (e != null)
+ {
+ zavai.log.warning("on_auth_code: " + e.message);
+ return;
+ }
+ status_changed("PIN OK");
+ }
+}
+
+public class GSM: zavai.ScriptMonitorService
+{
+ protected dynamic DBus.Object dbus;
+ public dynamic DBus.Object call;
+ protected GSMActivator activator;
+
+ public signal void status_changed(string message);
+
+ public GSM()
+ {
+ Object(name: "gsm");
+
+ activator = new GSMActivator();
+ activator.status_changed += (msg) => { status_changed(msg); };
+
+ call = null;
+
+ dbus = zavai.registry.sbus.get_object(
+ "org.freedesktop.DBus",
+ "/org/freedesktop/DBus",
+ "org.freedesktop.DBus");
+ dbus.NameOwnerChanged += on_name_owner_changed;
+ }
+
+ /// Request GPS resource
+ public override void start()
+ {
+ if (started) return;
+
+ status_changed("Starting");
+
+ script_start();
+
+ call = zavai.registry.sbus.get_object(
+ "org.freesmartphone.ogsmd",
+ "/org/freesmartphone/GSM/Device",
+ "org.freesmartphone.GSM.Call");
+
+ 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");
+ activator.begin();
+ }
+ }
+
+ // Release usage of GPS
+ public override void stop()
+ {
+ if (!started) return;
+
+ script_stop();
+ }
+
+ protected override void cleanup_after_script_stop()
+ {
+ call = null;
+ }
+}
+
+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();
+}
+
+}
+}
--- /dev/null
+/*
+ * 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();
+}
+
+}
+}
--- /dev/null
+[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);
+ }
+ */
+}
--- /dev/null
+[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);
+ }
+}
--- /dev/null
+[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
+ }
+}
--- /dev/null
+/*
+ * 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();
+}
+
+}
+}
--- /dev/null
+/usr/share/vala/vapi/lua.vapi
\ No newline at end of file
+++ /dev/null
-# menu - zavai menus
-#
-# 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
-
-import sys
-from gettext import gettext as _
-import zavai
-import gtk
-
-class MenuButton(gtk.Button):
- def __init__(self, *args, **kw):
- super(MenuButton, self).__init__(*args, **kw)
- # TODO: take this from the configuration
- self.set_size_request(0, 80)
-
-class Menu(gtk.VBox, zavai.Resource):
- def __init__(self, registry, name, parent = None, *args, **kw):
- super(Menu, self).__init__()
- self.vbox = self
-
- if parent is not None:
- self.vbox = gtk.VBox()
- self.pack_start(self.vbox, False, False)
- self.pack_start(gtk.Label(""), True, True)
- self.pack_start(LinkButton(registry, parent, _("Back")), False, False)
-
- def add_child(self, widget):
- self.vbox.pack_start(widget, False, False)
-
-class LinkButton(MenuButton, zavai.Resource):
- def __init__(self, registry, targetName, label=None, action=None):
- if action is not None:
- super(LinkButton, self).__init__()
- self.target = targetName
- self.registry = registry
- self.action = action
- action.connect_proxy(self)
- self.connect("clicked", self.on_click)
- else:
- super(LinkButton, self).__init__(label)
- self.target = targetName
- self.registry = registry
- self.action = None
- self.connect("clicked", self.on_click)
-
- def on_click(self, *args):
- self.registry.resource("app").activate_resource(self.target)
-
-class ToggleButton(gtk.ToggleButton):
- def __init__(self, registry, targetName, action, *args, **kw):
- super(ToggleButton, self).__init__()
- # TODO: take this from the configuration
- self.set_size_request(0, 80)
- action.connect_proxy(self)
+++ /dev/null
-#!/usr/bin/env python
-#
-# File: plugins.py
-#
-# Copyright (C) 2008 Christopher R. Gabriel <cgabriel@truelite.it>
-#
-# 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.
-#
-
-import os
-import os.path
-import imp
-import sys
-
-def load_plugins(pluginpath=None, nick="octofuss"):
- """return a list of all available plugins
- in the given directory"""
-
- if not pluginpath:
- pluginpath = os.environ.get(nick.upper() + "_PLUGINS", "plugins")
-
- # if the plugin path need to be auto-discovered
- # starting from a specified module
- #pluginpath = os.path.join(os.path.dirname(imp.find_module("octofussd")[1]), "extensions/")
- #pluginpath = "."
- pluginfiles = [fname[:-3] for fname in os.listdir(pluginpath) if fname.endswith(".py") and not fname.startswith(".") and not fname.endswith("~")]
-
- for fname in sorted(pluginfiles):
- oldpath = sys.path
- try:
- sys.path.append(os.path.abspath(pluginpath))
- res = imp.load_source(fname, os.path.join(pluginpath, fname) + ".py")
- finally:
- sys.path = oldpath
- yield res
-
--- /dev/null
+/*
+ * 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 {
+
+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();
+ }
+ }
+ }
+}
+
+Power power;
+
+public void init()
+{
+ power = new Power();
+}
+
+}
+}
+++ /dev/null
-# 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
-
-import zavai
-import gtk
-
-def get_parent(s):
- "Get the parent name for s"
- pos = s.rfind(".")
- if pos == -1: return None
- res = s[:pos]
- if res == "menu": return None
- return res
-
-def default_label(s):
- "Compute a default label given the last element of a path"
- pos = s.rfind(".")
- if pos == -1: return s.capitalize()
- return s[pos+1:].capitalize()
-
-
-class Registry(object):
- """Collection of resources.
-
- Various factories can be registered by name on the registry. Then when an
- object is requested for the first time, it is created using the factory.
- When it is requested again, the existing object is reused.
- """
-
- def __init__(self):
- self.factories = dict()
- self.objects = dict()
- self.labels = dict()
-
- def register(self, obj, name=None):
- """Register an object at the given path.
-
- Name the path to this object, like "menu.gps.monitor".
- """
- if name is None:
- name = obj.props.name
-
- if name in self.objects:
- return KeyError("%s is already registered", name)
- zavai.info("Registering", name)
- self.objects[name] = obj
-
- if name.startswith("menu."):
- self.add_to_menu(name)
-
- def register_factory(self, fac, name, label = None):
- """Register an object factory at the given path.
-
- Name the path to this object, like "menu.gps.monitor".
- """
- if name in self.factories:
- return KeyError("Factory %s is already registered", name)
- zavai.info("Registering factory", name)
- self.factories[name] = fac
- if label is not None: self.labels[name] = label
-
- def add_to_menu(self, name):
- "Add the applet with the given name to the menu structure"
- parent = get_parent(name)
- if parent is not None:
- zavai.info("Add to menu", name, parent)
- menu = self.menu(parent)
-
- obj = self.resource(name)
- if isinstance(obj, gtk.ToggleAction):
- menu.add_child(zavai.ToggleButton(self, name, action=obj))
- elif isinstance(obj, gtk.Action):
- menu.add_child(zavai.LinkButton(self, name, action=obj))
- else:
- menu.add_child(zavai.LinkButton(self, name, self.label(name)))
-
- def label(self, name):
- "Return the label for the object with the given name"
- res = self.labels.get(name)
- if res is not None:
- return res
- try:
- obj = self.resource(name)
- return obj.props.label
- except:
- return default_label(name)
-
- def resource(self, name):
- """Get a resource from the registry.
-
- If no resource exists at `name` but there is a factory, instantiate the
- object using the factory.
-
- If not even a factory exists at `name`, returns None.
- """
- res = self.objects.get(name, None)
- if res is None:
- fac = self.factories.get(name, None)
- if fac is not None:
- res = self.objects[name] = fac(self, name)
- return res
-
- def menu(self, name):
- """Get a menu resource, automatically creating it if it is missing.
-
- Menus are created automatically linked to a parent menu, according to
- the hierarchy in `name`.
- """
- res = self.resource(name)
- if res is None:
- # Check if it is a toplevel menu
- if name.startswith("menu."):
- parent = get_parent(name[5:])
- if parent is not None:
- parent = "menu." + parent
- else:
- parent = get_parent(name)
-
- res = zavai.Menu(self, name, parent)
- self.register(res, name)
- return res
-
- def shutdown(self):
- """Shut down all objects in this Registry.
-
- After shutting down, all objects cannot be used anymore"""
- for o in self.objects.itervalues():
- if isinstance(o, Resource):
- o.shutdown()
- self.objects.clear()
-
-class Resource(object):
- def __init__(self):
- super(Resource, self).__init__()
-
- def shutdown(self):
- """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.
- """
- pass
-
-class Service(Resource):
- "Service that is activated only when someone is listening"
- def __init__(self, types = []):
- """
- Initialise a service that can emit signals for the given event types
- """
- super(Service, self).__init__()
- self.callbacks = dict()
- for t in types:
- self.callbacks[t] = set()
- self.started = False
-
- def shutdown(self):
- if self.started:
- self.stop()
-
- def start(self):
- "Activate the service"
- pass
-
- def stop(self):
- "Deactivate the service"
- pass
-
- def notify(self, type, *args, **kw):
- "Call all callbacks with the given parameters"
- for cb in self.callbacks[type]:
- cb(*args, **kw)
-
- def has_callbacks(self):
- for i in self.callbacks.values():
- if i: return True
- return False
-
- def connect(self, type, callback):
- "Connect a callback to this resource, activating it if needed"
- do_start = not self.has_callbacks()
- self.callbacks[type].add(callback)
- if do_start:
- self.start()
- self.started = True
-
- def disconnect(self, type, callback):
- "Disconnect a callback to this resource, activating it if needed"
- if not self.has_callbacks(): return
- self.callbacks[type].discard(callback)
- if not self.has_callbacks():
- self.stop()
- self.started = False
--- /dev/null
+/*
+ * 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;
+
+}
+
--- /dev/null
+/*
+ * 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;
+}
+
+}
+}
--- /dev/null
+/*
+ * 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();
+
+}
+
+}
+}
--- /dev/null
+/* 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;
+}
+