Added dbus logic

This commit is contained in:
Fabio Manganiello 2022-01-26 02:38:37 +01:00
parent 7f0cb722a3
commit 8592f985f0
5 changed files with 233 additions and 34 deletions

View file

@ -12,6 +12,7 @@ AC_CONFIG_HEADERS([config.h.in])
pkg_modules="glib-2.0 >= 2.6.0 \ pkg_modules="glib-2.0 >= 2.6.0 \
gtk+-2.0 >= 2.6.0 \ gtk+-2.0 >= 2.6.0 \
gthread-2.0 \ gthread-2.0 \
dbus-glib-1 \
lxpanel" lxpanel"
PKG_CHECK_MODULES(PACKAGE, [$pkg_modules]) PKG_CHECK_MODULES(PACKAGE, [$pkg_modules])

View file

@ -10,7 +10,8 @@ module_LTLIBRARIES = cutiepi_battery.la
moduledir = $(libdir) moduledir = $(libdir)
cutiepi_battery_la_SOURCES = \ cutiepi_battery_la_SOURCES = \
main.c main.c \
dbus.c
cutiepi_battery_la_LIBADD = \ cutiepi_battery_la_LIBADD = \
$(PACKAGE_LIBS) $(PACKAGE_LIBS)

147
src/dbus.c Normal file
View file

@ -0,0 +1,147 @@
/**
*
* Copyright (c) 2022 Fabio Manganiello, see the file AUTHORS for details.
*
* 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
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/param.h>
#include <glib.h>
#include "dbus.h"
static DBusConnection* conn;
static DBusConnection *dbus_connect()
{
DBusError err;
dbus_error_init(&err);
conn = dbus_bus_get(DBUS_BUS_SESSION, &err);
if (dbus_error_is_set(&err))
{
fprintf(stderr, "Connection Error (%s)\n", err.message);
dbus_error_free(&err);
}
if (!conn)
{
fprintf(stderr, "Cannot initialize the DBus connection");
exit(1);
}
return conn;
}
static void add_signal_listener()
{
DBusError err;
dbus_bus_add_match(
conn,
"type='signal',interface='io.cutiepi.interface',path='/mcu'",
&err);
dbus_connection_flush(conn);
if (dbus_error_is_set(&err))
{
fprintf(stderr, "Match Error (%s)\n", err.message);
exit(1);
}
}
static void reset_battery_info(BatteryInfo* info)
{
info->_is_parsed[0] = info->_is_parsed[1] = false;
}
static bool is_battery_info_parsed(BatteryInfo* info)
{
return info->_is_parsed[0] && info->_is_parsed[1];
}
static void process_signal(DBusMessage* msg, DBusMessageIter* iter, BatteryInfo* info)
{
char current_type;
char* str_val = NO_STRING_VAL;
int int_val = NO_INT_VAL;
while ((current_type = dbus_message_iter_get_arg_type(iter)) != DBUS_TYPE_INVALID)
{
if (current_type == DBUS_TYPE_STRING)
dbus_message_iter_get_basic(iter, &str_val);
else if (current_type == DBUS_TYPE_INT32)
dbus_message_iter_get_basic(iter, &int_val);
if (strlen(str_val) && int_val != NO_INT_VAL)
{
if (!strncmp(str_val, BATTERY_LEVEL_VARNAME, strlen(str_val)-1))
{
info->level = (int) MIN(MAX(((int_val * 100) / MAX_BATTERY_VOLTAGE), 0), 100);
info->_is_parsed[0] = true;
}
else if (!strncmp(str_val, BATTERY_STATE_VARNAME, strlen(str_val)-1))
{
info->is_charging = int_val == BATTERY_STATE_CHARGING;
info->_is_parsed[1] = true;
}
str_val = NO_STRING_VAL;
int_val = NO_INT_VAL;
}
dbus_message_iter_next(iter);
}
}
void dbus_init()
{
dbus_connect();
add_signal_listener();
}
void get_battery_info(BatteryInfo* info)
{
DBusMessage* msg;
DBusMessageIter iter;
reset_battery_info(info);
while (!is_battery_info_parsed(info))
{
dbus_connection_read_write(conn, 0);
msg = dbus_connection_pop_message(conn);
if (!msg)
{
sleep(1);
continue;
}
if (dbus_message_is_signal(msg, "io.cutiepi.interface", "updateEvent"))
{
if (!dbus_message_iter_init(msg, &iter))
fprintf(stderr, "Message has no arguments!\n");
else
process_signal(msg, &iter, info);
}
dbus_message_unref(msg);
}
}

47
src/dbus.h Normal file
View file

@ -0,0 +1,47 @@
/**
*
* Copyright (c) 2022 Fabio Manganiello, see the file AUTHORS for details.
*
* 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
*
*/
#ifndef _DBUS_BATTERY_H
#define _DBUS_BATTERY_H
#include <stdint.h>
#include <stdbool.h>
#include <dbus/dbus.h>
#include <dbus/dbus-glib.h>
#define BATTERY_STATE_CHARGING (4)
#define BATTERY_STATE_DISCHARGING (5)
#define NO_STRING_VAL ("")
#define NO_INT_VAL (-1)
#define BATTERY_LEVEL_VARNAME ("battery")
#define BATTERY_STATE_VARNAME ("charge")
/* Expressed in mV (I guess). Value based on empirical evidence */
#define MAX_BATTERY_VOLTAGE (4000)
typedef struct {
uint8_t level; /* Battery level in percentage between 0-100 */
bool is_charging;
bool _is_parsed[2];
} BatteryInfo;
extern void dbus_init();
extern void get_battery_info(BatteryInfo* info);
#endif /* _DBUS_BATTERY_H */

View file

@ -19,59 +19,62 @@
*/ */
#include <stdio.h> #include <stdio.h>
#include <glib.h>
#include <lxpanel/plugin.h> #include <lxpanel/plugin.h>
#define LabelSize 32 #include "dbus.h"
#define POLL_INTERVAL_MS 1000
static gboolean refresh_state(void* data)
{
GtkWidget* label = (GtkWidget *) data;
BatteryInfo info;
char label_str[32] = {0};
get_battery_info(&info);
snprintf(
label_str,
sizeof(label_str)-1,
"%s %d%%",
info.is_charging ? "" : "🔋",
info.level
);
gtk_label_set_text(GTK_LABEL(label), label_str);
return TRUE;
}
GtkWidget *constructor(LXPanel *panel, config_setting_t *settings) GtkWidget *constructor(LXPanel *panel, config_setting_t *settings)
{ {
/* panel is a pointer to the panel and /* panel is a pointer to the panel and
settings is a pointer to the configuration data settings is a pointer to the configuration data
since we don't use it, we'll make sure it doesn't since we don't use it, we'll make sure it doesn't
give us an error at compilation time */ give us an error at compilation time */
(void)panel; (void)panel;
(void)settings; (void)settings;
// make a label out of the hostname dbus_init();
char cIdBuf[LabelSize + 1] = {'\0'};
FILE *fp;
fp = fopen("/etc/hostname", "r");
fgets(cIdBuf, LabelSize, fp);
fclose(fp);
// create a label widget instance
GtkWidget *pLabel = gtk_label_new(cIdBuf);
// set the label to be visible
gtk_widget_show(pLabel);
// need to create a container to be able to set a border
GtkWidget *p = gtk_event_box_new(); GtkWidget *p = gtk_event_box_new();
// our widget doesn't have a window...
// it is usually illegal to call gtk_widget_set_has_window() from application but for GtkEventBox it doesn't hurt
gtk_widget_set_has_window(p, FALSE); gtk_widget_set_has_window(p, FALSE);
// set border width
gtk_container_set_border_width(GTK_CONTAINER(p), 1); gtk_container_set_border_width(GTK_CONTAINER(p), 1);
// add the label to the container GtkWidget *label = gtk_label_new("");
gtk_container_add(GTK_CONTAINER(p), pLabel); gtk_container_add(GTK_CONTAINER(p), label);
gtk_widget_show(label);
g_timeout_add(POLL_INTERVAL_MS, refresh_state, label);
// set the size we want // set the size we want
// gtk_widget_set_size_request(p, 100, 25); // gtk_widget_set_size_request(p, 100, 25);
// success!!!
return p; return p;
} }
FM_DEFINE_MODULE(lxpanel_gtk, test) FM_DEFINE_MODULE(lxpanel_gtk, test)
/* Plugin descriptor. */
LXPanelPluginInit fm_module_init_lxpanel_gtk = { LXPanelPluginInit fm_module_init_lxpanel_gtk = {
.name = "CutiePi battery", .name = "CutiePi battery",
.description = "Displays the current state of the CutiePi battery", .description = "Displays the current state of the CutiePi battery",
.one_per_system = 1, .new_instance = constructor
};
// assigning our functions to provided pointers.
.new_instance = constructor};