From 45ebf4534316c75c318aece87440e46d8ef1b21f Mon Sep 17 00:00:00 2001 From: Lena Date: Fri, 20 Sep 2024 17:40:43 +0200 Subject: [PATCH] Start GPS module --- include/modules/gps.hpp | 31 ++++++++++++ man/waybar-gps.5.scd | 41 ++++++++++++++++ meson.build | 10 +++- meson_options.txt | 1 + src/factory.cpp | 8 ++++ src/modules/gps.cpp | 101 ++++++++++++++++++++++++++++++++++++++++ 6 files changed, 191 insertions(+), 1 deletion(-) create mode 100644 include/modules/gps.hpp create mode 100644 man/waybar-gps.5.scd create mode 100644 src/modules/gps.cpp diff --git a/include/modules/gps.hpp b/include/modules/gps.hpp new file mode 100644 index 00000000..20bf02e4 --- /dev/null +++ b/include/modules/gps.hpp @@ -0,0 +1,31 @@ +#pragma once + +#include +#include + +#include +#include + +#include "ALabel.hpp" +#include "util/format.hpp" +#include "util/sleeper_thread.hpp" + +namespace waybar::modules { + + class Gps : public ALabel { + public: + Gps(const std::string&, const Json::Value&); + virtual ~Gps(); + auto update() -> void override; + + private: + const int getFixState() const; + const std::string getFixStateName() const; + const std::string getFixStateString() const; + + util::SleeperThread thread_; + gps_data_t gps_data_; + std::string state_; + }; + +} // namespace waybar::modules diff --git a/man/waybar-gps.5.scd b/man/waybar-gps.5.scd new file mode 100644 index 00000000..dfa91c27 --- /dev/null +++ b/man/waybar-gps.5.scd @@ -0,0 +1,41 @@ +waybar-gps(5) "waybar-gps" "User Manual" + +# NAME + +waybar - gps module + +# DESCRIPTION + +*gps* module for gpsd. + + +# FILES + +$XDG_CONFIG_HOME/waybar/config ++ + Per user configuration file + +# ADDITIONAL FILES + +libgps lives in: + +. /usr/lib/libgps.so or /usr/lib64/libgps.so +. /usr/lib/pkgconfig/libgps.pc or /usr/lib64/pkgconfig/libgps.pc +. /usr/include/gps + +# CONFIGURATION + + + +# EXAMPLES + +``` +"gps": { + +}, +``` +# STYLE + +- *#gps* +- *#gps.fix-none* Applied when GPS is present, but there is no fix. +- *#gps.fix-2d* Applied when there is a 2D fix. +- *#gps.fix-3d* Applied when there is a 3D fix. diff --git a/meson.build b/meson.build index 7f9854d5..a9d6b6e1 100644 --- a/meson.build +++ b/meson.build @@ -93,6 +93,7 @@ libmpdclient = dependency('libmpdclient', required: get_option('mpd')) xkbregistry = dependency('xkbregistry') libjack = dependency('jack', required: get_option('jack')) libwireplumber = dependency('wireplumber-0.5', required: get_option('wireplumber')) +libgps = dependency('libgps', required: get_option('gps')) libsndio = compiler.find_library('sndio', required: get_option('sndio')) if libsndio.found() @@ -497,6 +498,12 @@ if cava.found() man_files += files('man/waybar-cava.5.scd') endif +if libgps.found() + add_project_arguments('-DHAVE_LIBGPS', language: 'cpp') + src_files += files('src/modules/gps.cpp') + man_files += files('man/waybar-gps.5.scd') +endif + subdir('protocol') app_resources = [] @@ -535,7 +542,8 @@ executable( libsndio, tz_dep, xkbregistry, - cava + cava, + libgps ], include_directories: inc_dirs, install: true, diff --git a/meson_options.txt b/meson_options.txt index d83fe01f..c0f63f28 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -21,3 +21,4 @@ option('wireplumber', type: 'feature', value: 'auto', description: 'Enable suppo option('cava', type: 'feature', value: 'auto', description: 'Enable support for Cava') option('niri', type: 'boolean', description: 'Enable support for niri') option('login-proxy', type: 'boolean', description: 'Enable interfacing with dbus login interface') +option('gps', type: 'feature', value: 'auto', description: 'Enable support for gps') diff --git a/src/factory.cpp b/src/factory.cpp index 1483397d..cfc12fbe 100644 --- a/src/factory.cpp +++ b/src/factory.cpp @@ -109,6 +109,9 @@ #ifdef HAVE_SYSTEMD_MONITOR #include "modules/systemd_failed_units.hpp" #endif +#ifdef HAVE_LIBGPS +#include "modules/gps.hpp" +#endif #include "modules/cffi.hpp" #include "modules/custom.hpp" #include "modules/image.hpp" @@ -331,6 +334,11 @@ waybar::AModule* waybar::Factory::makeModule(const std::string& name, if (ref == "systemd-failed-units") { return new waybar::modules::SystemdFailedUnits(id, config_[name]); } +#endif +#ifdef HAVE_LIBCAVA + if (ref == "gps") { + return new waybar::modules::Gps(id, config_[name]); + } #endif if (ref == "temperature") { return new waybar::modules::Temperature(id, config_[name]); diff --git a/src/modules/gps.cpp b/src/modules/gps.cpp new file mode 100644 index 00000000..52217e0a --- /dev/null +++ b/src/modules/gps.cpp @@ -0,0 +1,101 @@ +#include "modules/gps.hpp" + +#include + +// In the 80000 version of fmt library authors decided to optimize imports +// and moved declarations required for fmt::dynamic_format_arg_store in new +// header fmt/args.h +#if (FMT_VERSION >= 80000) +#include +#else +#include +#endif + +namespace { + using namespace waybar::util; + constexpr const char *DEFAULT_FORMAT = "{status}"; +} // namespace + + +waybar::modules::Gps::Gps(const std::string& id, const Json::Value& config) +: ALabel(config, "gps", id, "{}", 30) { + thread_ = [this] { + dp.emit(); + thread_.sleep_for(interval_); + }; + // TODO: connect to gpsd socket + + if (0 != gps_open("localhost", "2947", &gps_data_)) { + throw std::runtime_error("Can't open gpsd socket"); + } + +} + +const int waybar::modules::Gps::getFixState() const { +0 +} + +const std::string waybar::modules::Gps::getFixStateName() const { + switch (getFixState()) { + case 1: + return "fix-2d"; + case 2: + return "fix-3d"; + default: + return "fix-none"; + } +} + +const std::string waybar::modules::Gps::getFixStateString() const { + switch (getFixState()) { + case 1: + return "2D Fix"; + case 2: + return "3D Fix"; + default: + return "No fix"; + } +} + +auto waybar::modules::Gps::update() -> void { + + std::string tooltip_format; + + if (!alt_) { + auto state = getFixStateName(); + if (!state_.empty() && label_.get_style_context()->has_class(state_)) { + label_.get_style_context()->remove_class(state_); + } + if (config_["format-" + state].isString()) { + default_format_ = config_["format-" + state].asString(); + } else if (config_["format"].isString()) { + default_format_ = config_["format"].asString(); + } else { + default_format_ = DEFAULT_FORMAT; + } + if (config_["tooltip-format-" + state].isString()) { + tooltip_format = config_["tooltip-format-" + state].asString(); + } + if (!label_.get_style_context()->has_class(state)) { + label_.get_style_context()->add_class(state); + } + format_ = default_format_; + state_ = state; + } + + + auto format = format_; + + fmt::dynamic_format_arg_store store; + store.push_back(fmt::arg("status", getFixStateString())); + + label_.set_markup(fmt::vformat(format, store)); +// Call parent update +ALabel::update(); +} + +waybar::modules::Gps::~Gps() { + gps_close(&gps_data_); +} + +