PoC
parent
a459d8a9b3
commit
6ae354f564
|
@ -0,0 +1,39 @@
|
||||||
|
#include <gtk/gtk.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
GtkContainer* root;
|
||||||
|
GtkBox* container;
|
||||||
|
GtkLabel* label;
|
||||||
|
GtkButton* button;
|
||||||
|
} Instance;
|
||||||
|
|
||||||
|
//
|
||||||
|
const size_t wbcabi_version = 1;
|
||||||
|
|
||||||
|
void onclicked() { printf("You clicked the button\n"); }
|
||||||
|
|
||||||
|
void* wbcabi_init(GtkContainer* root) {
|
||||||
|
// Allocate the instance object
|
||||||
|
Instance* inst = malloc(sizeof(Instance));
|
||||||
|
inst->root = root;
|
||||||
|
|
||||||
|
// Add a container for displaying the next widgets
|
||||||
|
inst->container = GTK_BOX(gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 5));
|
||||||
|
gtk_container_add(GTK_CONTAINER(inst->root), GTK_WIDGET(inst->container));
|
||||||
|
|
||||||
|
// Add a label
|
||||||
|
inst->label = GTK_LABEL(gtk_label_new("This is a button:"));
|
||||||
|
gtk_container_add(GTK_CONTAINER(inst->container), GTK_WIDGET(inst->label));
|
||||||
|
|
||||||
|
// Add a button
|
||||||
|
inst->button = GTK_BUTTON(gtk_button_new_with_label("click me !"));
|
||||||
|
g_signal_connect(inst->button, "clicked", G_CALLBACK(onclicked), NULL);
|
||||||
|
gtk_container_add(GTK_CONTAINER(inst->container), GTK_WIDGET(inst->button));
|
||||||
|
|
||||||
|
// Return instance object
|
||||||
|
return inst;
|
||||||
|
}
|
||||||
|
void wbcabi_deinit(void* instance) { free(instance); }
|
||||||
|
|
||||||
|
char* wbcabi_last_error_str(void* instance) { return NULL; }
|
|
@ -0,0 +1,21 @@
|
||||||
|
project(
|
||||||
|
'waybar_cabi_c_example', 'c',
|
||||||
|
version: '0.1.0',
|
||||||
|
license: 'MIT',
|
||||||
|
)
|
||||||
|
|
||||||
|
compiler = meson.get_compiler('c')
|
||||||
|
|
||||||
|
|
||||||
|
shared_library('waybar_cabi_c_example',
|
||||||
|
[
|
||||||
|
'main.c',
|
||||||
|
],
|
||||||
|
dependencies: [
|
||||||
|
dependency('gtk+-3.0', version : ['>=3.22.0'])
|
||||||
|
]
|
||||||
|
# include_directories: include_directories(['../../../include']),
|
||||||
|
# dependencies: [],
|
||||||
|
# install: true,
|
||||||
|
# install_dir: 'plugins',
|
||||||
|
)
|
|
@ -91,6 +91,7 @@
|
||||||
#include "modules/cava.hpp"
|
#include "modules/cava.hpp"
|
||||||
#endif
|
#endif
|
||||||
#include "bar.hpp"
|
#include "bar.hpp"
|
||||||
|
#include "modules/cabi.hpp"
|
||||||
#include "modules/custom.hpp"
|
#include "modules/custom.hpp"
|
||||||
#include "modules/image.hpp"
|
#include "modules/image.hpp"
|
||||||
#include "modules/temperature.hpp"
|
#include "modules/temperature.hpp"
|
||||||
|
|
|
@ -0,0 +1,28 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <fmt/format.h>
|
||||||
|
|
||||||
|
#include <csignal>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "AModule.hpp"
|
||||||
|
#include "util/command.hpp"
|
||||||
|
#include "util/json.hpp"
|
||||||
|
#include "util/sleeper_thread.hpp"
|
||||||
|
|
||||||
|
namespace waybar::modules {
|
||||||
|
|
||||||
|
class CABI : public AModule {
|
||||||
|
public:
|
||||||
|
CABI(const std::string&, const std::string&, const Json::Value&);
|
||||||
|
virtual ~CABI();
|
||||||
|
|
||||||
|
private:
|
||||||
|
void* cabi_instance_ = nullptr;
|
||||||
|
|
||||||
|
std::function<void*(GtkContainer*)> wbcabi_init_ = nullptr;
|
||||||
|
std::function<void(void*)> wbcabi_deinit_ = [](void*) {};
|
||||||
|
std::function<const char*(void*)> wbcabi_last_error_str_ = [](void*) { return nullptr; };
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace waybar::modules
|
|
@ -190,6 +190,7 @@ if is_linux
|
||||||
add_project_arguments('-DHAVE_MEMORY_LINUX', language: 'cpp')
|
add_project_arguments('-DHAVE_MEMORY_LINUX', language: 'cpp')
|
||||||
src_files += files(
|
src_files += files(
|
||||||
'src/modules/battery.cpp',
|
'src/modules/battery.cpp',
|
||||||
|
'src/modules/cabi.cpp',
|
||||||
'src/modules/cpu.cpp',
|
'src/modules/cpu.cpp',
|
||||||
'src/modules/cpu_frequency/common.cpp',
|
'src/modules/cpu_frequency/common.cpp',
|
||||||
'src/modules/cpu_frequency/linux.cpp',
|
'src/modules/cpu_frequency/linux.cpp',
|
||||||
|
@ -202,6 +203,7 @@ elif is_dragonfly or is_freebsd or is_netbsd or is_openbsd
|
||||||
add_project_arguments('-DHAVE_CPU_BSD', language: 'cpp')
|
add_project_arguments('-DHAVE_CPU_BSD', language: 'cpp')
|
||||||
add_project_arguments('-DHAVE_MEMORY_BSD', language: 'cpp')
|
add_project_arguments('-DHAVE_MEMORY_BSD', language: 'cpp')
|
||||||
src_files += files(
|
src_files += files(
|
||||||
|
'src/modules/cabi.cpp',
|
||||||
'src/modules/cpu.cpp',
|
'src/modules/cpu.cpp',
|
||||||
'src/modules/cpu_frequency/bsd.cpp',
|
'src/modules/cpu_frequency/bsd.cpp',
|
||||||
'src/modules/cpu_frequency/common.cpp',
|
'src/modules/cpu_frequency/common.cpp',
|
||||||
|
|
|
@ -201,6 +201,9 @@ waybar::AModule* waybar::Factory::makeModule(const std::string& name) const {
|
||||||
if (ref.compare(0, 7, "custom/") == 0 && ref.size() > 7) {
|
if (ref.compare(0, 7, "custom/") == 0 && ref.size() > 7) {
|
||||||
return new waybar::modules::Custom(ref.substr(7), id, config_[name]);
|
return new waybar::modules::Custom(ref.substr(7), id, config_[name]);
|
||||||
}
|
}
|
||||||
|
if (ref.compare(0, 5, "cabi/") == 0 && ref.size() > 5) {
|
||||||
|
return new waybar::modules::CABI(ref.substr(5), id, config_[name]);
|
||||||
|
}
|
||||||
} catch (const std::exception& e) {
|
} catch (const std::exception& e) {
|
||||||
auto err = fmt::format("Disabling module \"{}\", {}", name, e.what());
|
auto err = fmt::format("Disabling module \"{}\", {}", name, e.what());
|
||||||
throw std::runtime_error(err);
|
throw std::runtime_error(err);
|
||||||
|
|
|
@ -0,0 +1,50 @@
|
||||||
|
#include "modules/cabi.hpp"
|
||||||
|
|
||||||
|
#include <dlfcn.h>
|
||||||
|
|
||||||
|
namespace waybar::modules {
|
||||||
|
|
||||||
|
CABI::CABI(const std::string& name, const std::string& id, const Json::Value& config)
|
||||||
|
: AModule(config, name, id, true, true) {
|
||||||
|
const auto dynlib_path = config_["path"].asString();
|
||||||
|
|
||||||
|
void* handle = dlopen(dynlib_path.c_str(), RTLD_LAZY);
|
||||||
|
if (handle == nullptr) {
|
||||||
|
throw std::runtime_error{dlerror()};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fetch ABI version
|
||||||
|
auto wbcabi_version = reinterpret_cast<size_t*>(dlsym(handle, "wbcabi_version"));
|
||||||
|
if (wbcabi_version == nullptr) {
|
||||||
|
throw std::runtime_error{"Missing wbcabi_version"};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fetch functions
|
||||||
|
if (*wbcabi_version == 1) {
|
||||||
|
wbcabi_init_ = reinterpret_cast<void* (*)(GtkContainer*)>(dlsym(handle, "wbcabi_init"));
|
||||||
|
if (wbcabi_init_ == nullptr) {
|
||||||
|
throw std::runtime_error{"Missing wbcabi_init function"};
|
||||||
|
}
|
||||||
|
if (auto fn = reinterpret_cast<void (*)(void*)>(dlsym(handle, "wbcabi_deinit")))
|
||||||
|
wbcabi_deinit_ = fn;
|
||||||
|
if (auto fn = reinterpret_cast<const char* (*)(void*)>(dlsym(handle, "wbcabi_last_error_str")))
|
||||||
|
wbcabi_last_error_str_ = fn;
|
||||||
|
} else {
|
||||||
|
throw std::runtime_error{"Unknown wbcabi_version " + std::to_string(*wbcabi_version)};
|
||||||
|
}
|
||||||
|
|
||||||
|
cabi_instance_ = wbcabi_init_(dynamic_cast<Gtk::Container*>(&event_box_)->gobj());
|
||||||
|
if (cabi_instance_ == nullptr) {
|
||||||
|
const auto err_str = wbcabi_last_error_str_(cabi_instance_);
|
||||||
|
throw std::runtime_error{std::string{"Failed to initialize C ABI plugin: "} +
|
||||||
|
(err_str != nullptr ? err_str : "unknown error")};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CABI::~CABI() {
|
||||||
|
if (cabi_instance_ != nullptr) {
|
||||||
|
wbcabi_deinit_(cabi_instance_);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace waybar::modules
|
Loading…
Reference in New Issue