mirror of
https://github.com/zoriya/astal.git
synced 2026-05-30 09:08:38 +00:00
monorepo structuring
This commit is contained in:
@@ -0,0 +1,74 @@
|
||||
static bool help;
|
||||
static bool version;
|
||||
static bool monitor;
|
||||
|
||||
const OptionEntry[] options = {
|
||||
{ "version", 'v', OptionFlags.NONE, OptionArg.NONE, ref version, null, null },
|
||||
{ "help", 'h', OptionFlags.NONE, OptionArg.NONE, ref help, null, null },
|
||||
{ "monitor", 'm', OptionFlags.NONE, OptionArg.NONE, ref monitor, null, null },
|
||||
{ null },
|
||||
};
|
||||
|
||||
int main(string[] argv) {
|
||||
try {
|
||||
var opts = new OptionContext();
|
||||
opts.add_main_entries(options, null);
|
||||
opts.set_help_enabled(false);
|
||||
opts.set_ignore_unknown_options(false);
|
||||
opts.parse(ref argv);
|
||||
} catch (OptionError err) {
|
||||
printerr (err.message);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (help) {
|
||||
print("Usage:\n");
|
||||
print(" %s [flags]\n\n", argv[0]);
|
||||
print("Flags:\n");
|
||||
print(" -h, --help Print this help and exit\n");
|
||||
print(" -v, --version Print version number and exit\n");
|
||||
print(" -m, --monitor Monitor property changes\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (version) {
|
||||
print(AstalBattery.VERSION);
|
||||
return 0;
|
||||
}
|
||||
|
||||
var battery = AstalBattery.get_default();
|
||||
print("%s\n", to_json(battery));
|
||||
|
||||
if (monitor) {
|
||||
battery.notify.connect((prop) => {
|
||||
if (prop.get_name() == "percentage"
|
||||
|| prop.get_name() == "state"
|
||||
|| prop.get_name() == "icon-name"
|
||||
|| prop.get_name() == "time-to-full"
|
||||
|| prop.get_name() == "time-to-empty"
|
||||
) {
|
||||
print("%s\n", to_json(battery));
|
||||
}
|
||||
});
|
||||
new GLib.MainLoop(null, false).run();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
private string to_json(AstalBattery.Device device) {
|
||||
string s = "unknown";
|
||||
if (device.state == AstalBattery.State.CHARGING)
|
||||
s = "charging";
|
||||
if (device.state == AstalBattery.State.DISCHARGING)
|
||||
s = "discharging";
|
||||
if (device.state == AstalBattery.State.FULLY_CHARGED)
|
||||
s = "fully_charged";
|
||||
|
||||
var p = device.percentage;
|
||||
var i = device.icon_name;
|
||||
var r = device.state == AstalBattery.State.CHARGING
|
||||
? device.time_to_full : device.time_to_empty;
|
||||
|
||||
return "{ \"percentage\": %f, \"state\": \"%s\", \"icon_name\": \"%s\", \"time_remaining\": %f }".printf(p, s, i, r);
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
namespace AstalBattery {
|
||||
public const int MAJOR_VERSION = @MAJOR_VERSION@;
|
||||
public const int MINOR_VERSION = @MINOR_VERSION@;
|
||||
public const int MICRO_VERSION = @MICRO_VERSION@;
|
||||
public const string VERSION = "@VERSION@";
|
||||
}
|
||||
@@ -0,0 +1,296 @@
|
||||
namespace AstalBattery {
|
||||
public Device get_default() {
|
||||
return Device.get_default();
|
||||
}
|
||||
|
||||
public class Device : Object {
|
||||
private static Device display_device;
|
||||
public static Device? get_default() {
|
||||
if (display_device != null)
|
||||
return display_device;
|
||||
|
||||
try {
|
||||
display_device = new Device("/org/freedesktop/UPower/devices/DisplayDevice");
|
||||
|
||||
return display_device;
|
||||
} catch (Error error) {
|
||||
critical(error.message);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private IUPowerDevice proxy;
|
||||
|
||||
public Device(string path) throws Error {
|
||||
proxy = Bus.get_proxy_sync(BusType.SYSTEM, "org.freedesktop.UPower", path);
|
||||
proxy.g_properties_changed.connect(sync);
|
||||
sync();
|
||||
}
|
||||
|
||||
public Type device_type { get; private set; }
|
||||
public string native_path { owned get; private set; }
|
||||
public string vendor { owned get; private set; }
|
||||
public string model { owned get; private set; }
|
||||
public string serial { owned get; private set; }
|
||||
public uint64 update_time { get; private set; }
|
||||
public bool power_supply { get; private set; }
|
||||
public bool has_history { get; private set; }
|
||||
public bool has_statistics { get; private set; }
|
||||
public bool online { get; private set; }
|
||||
public double energy { get; private set; }
|
||||
public double energy_empty { get; private set; }
|
||||
public double energy_full { get; private set; }
|
||||
public double energy_full_design { get; private set; }
|
||||
public double energy_rate { get; private set; }
|
||||
public double voltage { get; private set; }
|
||||
public int charge_cycles { get; private set; }
|
||||
public double luminosity { get; private set; }
|
||||
public int64 time_to_empty { get; private set; }
|
||||
public int64 time_to_full { get; private set;}
|
||||
public double percentage { get; private set; }
|
||||
public double temperature { get; private set; }
|
||||
public bool is_present { get; private set; }
|
||||
public State state { get; private set; }
|
||||
public bool is_rechargable { get; private set; }
|
||||
public double capacity { get; private set; }
|
||||
public Technology technology { get; private set; }
|
||||
public WarningLevel warning_level { get; private set; }
|
||||
public BatteryLevel battery_level { get; private set; }
|
||||
public string icon_name { owned get; private set; }
|
||||
|
||||
public bool charging { get; private set; }
|
||||
public bool is_battery { get; private set; }
|
||||
public string battery_icon_name { get; private set; }
|
||||
public string device_type_name { get; private set; }
|
||||
public string device_type_icon { get; private set; }
|
||||
|
||||
private unowned string get_battery_icon() {
|
||||
if (percentage <= 0)
|
||||
return "battery-good";
|
||||
|
||||
if (percentage < 0.10)
|
||||
return "battery-empty";
|
||||
|
||||
if (percentage < 0.37)
|
||||
return "battery-caution";
|
||||
|
||||
if (percentage < 0.62)
|
||||
return "battery-low";
|
||||
|
||||
if (percentage < 0.87)
|
||||
return "battery-good";
|
||||
|
||||
return "battery-full";
|
||||
}
|
||||
|
||||
|
||||
public void sync() {
|
||||
device_type = (Type)proxy.Type;
|
||||
native_path = proxy.native_path;
|
||||
vendor = proxy.vendor;
|
||||
model = proxy.model;
|
||||
serial = proxy.serial;
|
||||
update_time = proxy.update_time;
|
||||
power_supply = proxy.power_supply;
|
||||
has_history = proxy.has_history;
|
||||
has_statistics = proxy.has_statistics;
|
||||
online = proxy.online;
|
||||
energy = proxy.energy;
|
||||
energy_empty = proxy.energy_empty;
|
||||
energy_full = proxy.energy_full;
|
||||
energy_full_design = proxy.energy_full_design;
|
||||
energy_rate = proxy.energy_rate;
|
||||
voltage = proxy.voltage;
|
||||
charge_cycles = proxy.charge_cycles;
|
||||
luminosity = proxy.luminosity;
|
||||
time_to_empty = proxy.time_to_empty;
|
||||
time_to_full = proxy.time_to_full;
|
||||
percentage = proxy.percentage / 100;
|
||||
temperature = proxy.temperature;
|
||||
is_present = proxy.is_present;
|
||||
state = (State)proxy.state;
|
||||
is_rechargable = proxy.is_rechargable;
|
||||
capacity = proxy.capacity;
|
||||
technology = (Technology)proxy.technology;
|
||||
warning_level = (WarningLevel)proxy.warning_level;
|
||||
battery_level = (BatteryLevel)proxy.battery_level;
|
||||
icon_name = proxy.icon_name;
|
||||
|
||||
charging = state == State.FULLY_CHARGED || state == State.CHARGING;
|
||||
is_battery = device_type != Type.UNKNOWN && device_type != Type.LINE_POWER;
|
||||
|
||||
if (!is_battery)
|
||||
battery_icon_name = "preferences-system-power";
|
||||
else if (percentage == 1.0 && charging)
|
||||
battery_icon_name = "battery-full-charged";
|
||||
else
|
||||
battery_icon_name = charging ? get_battery_icon() + "-charging" : get_battery_icon();
|
||||
|
||||
device_type_name = device_type.get_name();
|
||||
device_type_icon = device_type.get_icon_name();
|
||||
}
|
||||
}
|
||||
|
||||
[CCode (type_signature = "u")]
|
||||
public enum State {
|
||||
UNKNOWN = 0,
|
||||
CHARGING,
|
||||
DISCHARGING,
|
||||
EMPTY,
|
||||
FULLY_CHARGED,
|
||||
PENDING_CHARGE,
|
||||
PENDING_DISCHARGE,
|
||||
}
|
||||
|
||||
[CCode (type_signature = "u")]
|
||||
public enum Technology {
|
||||
UNKNOWN = 0,
|
||||
LITHIUM_ION,
|
||||
LITHIUM_POLYMER,
|
||||
LITHIUM_IRON_PHOSPHATE,
|
||||
LEAD_ACID,
|
||||
NICKEL_CADMIUM,
|
||||
NICKEL_METAL_HYDRIDE,
|
||||
}
|
||||
|
||||
[CCode (type_signature = "u")]
|
||||
public enum WarningLevel {
|
||||
UNKNOWN = 0,
|
||||
NONE,
|
||||
DISCHARGING,
|
||||
LOW,
|
||||
CRITICIAL,
|
||||
ACTION,
|
||||
}
|
||||
|
||||
[CCode (type_signature = "u")]
|
||||
public enum BatteryLevel {
|
||||
UNKNOWN = 0,
|
||||
NONE,
|
||||
LOW,
|
||||
CRITICIAL,
|
||||
NORMAL,
|
||||
HIGH,
|
||||
FULL,
|
||||
}
|
||||
|
||||
[CCode (type_signature = "u")]
|
||||
public enum Type {
|
||||
UNKNOWN = 0,
|
||||
LINE_POWER,
|
||||
BATTERY,
|
||||
UPS,
|
||||
MONITOR,
|
||||
MOUSE,
|
||||
KEYBOARD,
|
||||
PDA,
|
||||
PHONE,
|
||||
MEDIA_PLAYER,
|
||||
TABLET,
|
||||
COMPUTER,
|
||||
GAMING_INPUT,
|
||||
PEN,
|
||||
TOUCHPAD,
|
||||
MODEM,
|
||||
NETWORK,
|
||||
HEADSET,
|
||||
SPEAKERS,
|
||||
HEADPHONES,
|
||||
VIDEO,
|
||||
OTHER_AUDIO,
|
||||
REMOVE_CONTROL,
|
||||
PRINTER,
|
||||
SCANNER,
|
||||
CAMERA,
|
||||
WEARABLE,
|
||||
TOY,
|
||||
BLUETOOTH_GENERIC;
|
||||
|
||||
// TODO: add more icon names
|
||||
public string? get_icon_name () {
|
||||
switch (this) {
|
||||
case UPS:
|
||||
return "uninterruptible-power-supply";
|
||||
case MOUSE:
|
||||
return "input-mouse";
|
||||
case KEYBOARD:
|
||||
return "input-keyboard";
|
||||
case PDA:
|
||||
case PHONE:
|
||||
return "phone";
|
||||
case MEDIA_PLAYER:
|
||||
return "multimedia-player";
|
||||
case TABLET:
|
||||
case PEN:
|
||||
return "input-tablet";
|
||||
case GAMING_INPUT:
|
||||
return "input-gaming";
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public unowned string? get_name () {
|
||||
switch (this) {
|
||||
case LINE_POWER:
|
||||
return "Plugged In";
|
||||
case BATTERY:
|
||||
return "Battery";
|
||||
case UPS:
|
||||
return "UPS";
|
||||
case MONITOR:
|
||||
return "Display";
|
||||
case MOUSE:
|
||||
return "Mouse";
|
||||
case KEYBOARD:
|
||||
return "Keyboard";
|
||||
case PDA:
|
||||
return "PDA";
|
||||
case PHONE:
|
||||
return "Phone";
|
||||
case MEDIA_PLAYER:
|
||||
return "Media Player";
|
||||
case TABLET:
|
||||
return "Tablet";
|
||||
case COMPUTER:
|
||||
return "Computer";
|
||||
case GAMING_INPUT:
|
||||
return "Controller";
|
||||
case PEN:
|
||||
return "Pen";
|
||||
case TOUCHPAD:
|
||||
return "Touchpad";
|
||||
case MODEM:
|
||||
return "Modem";
|
||||
case NETWORK:
|
||||
return "Network";
|
||||
case HEADSET:
|
||||
return "Headset";
|
||||
case SPEAKERS:
|
||||
return "Speakers";
|
||||
case HEADPHONES:
|
||||
return "Headphones";
|
||||
case VIDEO:
|
||||
return "Video";
|
||||
case OTHER_AUDIO:
|
||||
return "Other Audio";
|
||||
case REMOVE_CONTROL:
|
||||
return "Remove Control";
|
||||
case PRINTER:
|
||||
return "Printer";
|
||||
case SCANNER:
|
||||
return "Scanner";
|
||||
case CAMERA:
|
||||
return "Camera";
|
||||
case WEARABLE:
|
||||
return "Wearable";
|
||||
case TOY:
|
||||
return "Toy";
|
||||
case BLUETOOTH_GENERIC:
|
||||
return "Bluetooth Generic";
|
||||
default:
|
||||
return "Unknown";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
namespace AstalBattery {
|
||||
[DBus (name = "org.freedesktop.UPower")]
|
||||
interface IUPower : DBusProxy {
|
||||
public abstract string[] enumerate_devices() throws Error;
|
||||
public abstract string get_display_device() throws Error;
|
||||
public abstract string get_critical_action() throws Error;
|
||||
|
||||
public signal void device_added(string object_path);
|
||||
public signal void device_removed(string object_path);
|
||||
|
||||
public abstract string daemon_version { owned get; }
|
||||
public abstract bool on_battery { get; }
|
||||
public abstract bool lid_is_closed { get; }
|
||||
public abstract bool lis_is_present { get; }
|
||||
}
|
||||
|
||||
[DBus (name = "org.freedesktop.UPower.Device")]
|
||||
public interface IUPowerDevice : DBusProxy {
|
||||
public abstract HistoryDataPoint[] get_history (string type, uint32 timespan, uint32 resolution) throws GLib.Error;
|
||||
public abstract StatisticsDataPoint[] get_statistics (string type) throws GLib.Error;
|
||||
public abstract void refresh () throws GLib.Error;
|
||||
|
||||
public abstract uint Type { get; }
|
||||
public abstract string native_path { owned get; }
|
||||
public abstract string vendor { owned get; }
|
||||
public abstract string model { owned get; }
|
||||
public abstract string serial { owned get; }
|
||||
public abstract uint64 update_time { get; }
|
||||
public abstract bool power_supply { get; }
|
||||
public abstract bool has_history { get; }
|
||||
public abstract bool has_statistics { get; }
|
||||
public abstract bool online { get; }
|
||||
public abstract double energy { get; }
|
||||
public abstract double energy_empty { get; }
|
||||
public abstract double energy_full { get; }
|
||||
public abstract double energy_full_design { get; }
|
||||
public abstract double energy_rate { get; }
|
||||
public abstract double voltage { get; }
|
||||
public abstract int32 charge_cycles { get; }
|
||||
public abstract double luminosity { get; }
|
||||
public abstract int64 time_to_empty { get; }
|
||||
public abstract int64 time_to_full { get; }
|
||||
public abstract double percentage { get; }
|
||||
public abstract double temperature { get; }
|
||||
public abstract bool is_present { get; }
|
||||
public abstract uint state { get; }
|
||||
public abstract bool is_rechargable { get; }
|
||||
public abstract double capacity { get; }
|
||||
public abstract uint technology { get; }
|
||||
public abstract uint32 warning_level { get; }
|
||||
public abstract uint32 battery_level { get; }
|
||||
public abstract string icon_name { owned get; }
|
||||
}
|
||||
|
||||
public struct HistoryDataPoint {
|
||||
uint32 time;
|
||||
double value;
|
||||
uint32 state;
|
||||
}
|
||||
|
||||
public struct StatisticsDataPoint {
|
||||
double value;
|
||||
double accuracy;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
project(
|
||||
'astal-battery',
|
||||
'vala',
|
||||
'c',
|
||||
version: run_command('cat', join_paths(meson.project_source_root(), 'version')).stdout().strip(),
|
||||
meson_version: '>= 0.62.0',
|
||||
default_options: [
|
||||
'warning_level=2',
|
||||
'werror=false',
|
||||
'c_std=gnu11',
|
||||
],
|
||||
)
|
||||
|
||||
assert(
|
||||
get_option('lib') or get_option('cli'),
|
||||
'Either lib or cli option must be set to true.',
|
||||
)
|
||||
|
||||
version_split = meson.project_version().split('.')
|
||||
api_version = version_split[0] + '.' + version_split[1]
|
||||
gir = 'AstalBattery-' + api_version + '.gir'
|
||||
typelib = 'AstalBattery-' + api_version + '.typelib'
|
||||
|
||||
config = configure_file(
|
||||
input: 'config.vala.in',
|
||||
output: 'config.vala',
|
||||
configuration: {
|
||||
'VERSION': meson.project_version(),
|
||||
'MAJOR_VERSION': version_split[0],
|
||||
'MINOR_VERSION': version_split[1],
|
||||
'MICRO_VERSION': version_split[2],
|
||||
},
|
||||
)
|
||||
|
||||
deps = [
|
||||
dependency('glib-2.0'),
|
||||
dependency('gio-2.0'),
|
||||
dependency('gobject-2.0'),
|
||||
]
|
||||
|
||||
sources = [
|
||||
config,
|
||||
'ifaces.vala',
|
||||
'device.vala',
|
||||
'upower.vala',
|
||||
]
|
||||
|
||||
if get_option('lib')
|
||||
lib = library(
|
||||
meson.project_name(),
|
||||
sources,
|
||||
dependencies: deps,
|
||||
vala_header: meson.project_name() + '.h',
|
||||
vala_vapi: meson.project_name() + '-' + api_version + '.vapi',
|
||||
vala_gir: gir,
|
||||
version: meson.project_version(),
|
||||
install: true,
|
||||
install_dir: [true, true, true, true],
|
||||
)
|
||||
|
||||
import('pkgconfig').generate(
|
||||
lib,
|
||||
name: meson.project_name(),
|
||||
filebase: meson.project_name() + '-' + api_version,
|
||||
version: meson.project_version(),
|
||||
subdirs: meson.project_name(),
|
||||
requires: deps,
|
||||
install_dir: get_option('libdir') / 'pkgconfig',
|
||||
)
|
||||
|
||||
custom_target(
|
||||
typelib,
|
||||
command: [
|
||||
find_program('g-ir-compiler'),
|
||||
'--output', '@OUTPUT@',
|
||||
'--shared-library', get_option('prefix') / get_option('libdir') / '@PLAINNAME@',
|
||||
meson.current_build_dir() / gir,
|
||||
],
|
||||
input: lib,
|
||||
output: typelib,
|
||||
depends: lib,
|
||||
install: true,
|
||||
install_dir: get_option('libdir') / 'girepository-1.0',
|
||||
)
|
||||
endif
|
||||
|
||||
if get_option('cli')
|
||||
executable(
|
||||
meson.project_name(),
|
||||
['cli.vala', sources],
|
||||
dependencies: deps,
|
||||
install: true,
|
||||
)
|
||||
endif
|
||||
@@ -0,0 +1,11 @@
|
||||
option(
|
||||
'lib',
|
||||
type: 'boolean',
|
||||
value: true,
|
||||
)
|
||||
|
||||
option(
|
||||
'cli',
|
||||
type: 'boolean',
|
||||
value: true,
|
||||
)
|
||||
@@ -0,0 +1,58 @@
|
||||
namespace AstalBattery {
|
||||
public class UPower : Object {
|
||||
private IUPower proxy;
|
||||
private HashTable<string, Device> _devices =
|
||||
new HashTable<string, Device>(str_hash, str_equal);
|
||||
|
||||
public List<weak Device> devices {
|
||||
owned get { return _devices.get_values(); }
|
||||
}
|
||||
|
||||
public signal void device_added(Device device);
|
||||
public signal void device_removed(Device device);
|
||||
|
||||
public Device display_device { owned get { return Device.get_default(); }}
|
||||
|
||||
public string daemon_version { owned get { return proxy.daemon_version; } }
|
||||
public bool on_battery { get { return proxy.on_battery; } }
|
||||
public bool lid_is_closed { get { return proxy.lid_is_closed; } }
|
||||
public bool lis_is_present { get { return proxy.lid_is_closed; } }
|
||||
|
||||
public string critical_action {
|
||||
owned get {
|
||||
try {
|
||||
return proxy.get_critical_action();
|
||||
} catch (Error error) {
|
||||
critical(error.message);
|
||||
return "";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
construct {
|
||||
try {
|
||||
proxy = Bus.get_proxy_sync(
|
||||
BusType.SYSTEM,
|
||||
"org.freedesktop.UPower",
|
||||
"/org/freedesktop/UPower"
|
||||
);
|
||||
|
||||
foreach (var path in proxy.enumerate_devices())
|
||||
_devices.set(path, new Device(path));
|
||||
|
||||
proxy.device_added.connect((path) => {
|
||||
_devices.set(path, new Device(path));
|
||||
notify_property("devices");
|
||||
});
|
||||
|
||||
proxy.device_removed.connect((path) => {
|
||||
device_removed(_devices.get(path));
|
||||
_devices.remove(path);
|
||||
notify_property("devices");
|
||||
});
|
||||
} catch (Error error) {
|
||||
critical(error.message);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
0.1.0
|
||||
Reference in New Issue
Block a user