156 lines
4.2 KiB
C
156 lines
4.2 KiB
C
#include <stddef.h>
|
|
#include "../util.h"
|
|
|
|
#include <gio/gio.h>
|
|
|
|
/*
|
|
* Completely vibe coded LOL, might need revision
|
|
*
|
|
* *BSDs probably don't work, but no one has bluetooth working on them lol
|
|
*/
|
|
const char *
|
|
blue(const char *ignored)
|
|
{
|
|
(void)ignored;
|
|
static GDBusProxy *ad = NULL;
|
|
static char devname[256];
|
|
|
|
GError *err = NULL;
|
|
|
|
if (!ad) {
|
|
ad = g_dbus_proxy_new_for_bus_sync(
|
|
G_BUS_TYPE_SYSTEM,
|
|
G_DBUS_PROXY_FLAGS_NONE,
|
|
NULL,
|
|
"org.bluez",
|
|
"/org/bluez/hci0",
|
|
"org.bluez.Adapter1",
|
|
NULL,
|
|
&err
|
|
);
|
|
|
|
if (!ad) {
|
|
g_clear_error(&err);
|
|
return " N/A";
|
|
}
|
|
}
|
|
|
|
GDBusConnection *conn = g_dbus_proxy_get_connection(ad);
|
|
|
|
GVariant *v = g_dbus_connection_call_sync(
|
|
conn,
|
|
"org.bluez",
|
|
"/org/bluez/hci0",
|
|
"org.freedesktop.DBus.Properties",
|
|
"Get",
|
|
g_variant_new("(ss)", "org.bluez.Adapter1", "Powered"),
|
|
G_VARIANT_TYPE("(v)"),
|
|
G_DBUS_CALL_FLAGS_NONE,
|
|
73,
|
|
NULL,
|
|
&err
|
|
);
|
|
|
|
if (!v) {
|
|
g_clear_error(&err);
|
|
g_object_unref(ad);
|
|
ad = NULL;
|
|
return " N/A";
|
|
}
|
|
|
|
GVariant *vv = NULL;
|
|
g_variant_get(v, "(v)", &vv);
|
|
gboolean powered = g_variant_get_boolean(vv);
|
|
g_variant_unref(vv);
|
|
g_variant_unref(v);
|
|
|
|
if (!powered)
|
|
return " OFF";
|
|
|
|
devname[0] = '\0';
|
|
|
|
GVariant *reply = g_dbus_connection_call_sync(
|
|
conn,
|
|
"org.bluez",
|
|
"/",
|
|
"org.freedesktop.DBus.ObjectManager",
|
|
"GetManagedObjects",
|
|
NULL,
|
|
G_VARIANT_TYPE("(a{oa{sa{sv}}})"),
|
|
G_DBUS_CALL_FLAGS_NONE,
|
|
-1,
|
|
NULL,
|
|
&err
|
|
);
|
|
|
|
if (!reply) {
|
|
g_clear_error(&err);
|
|
return " ON";
|
|
}
|
|
|
|
GVariantIter *it = NULL;
|
|
const char *obj_path = NULL;
|
|
GVariant *ifaces = NULL;
|
|
gboolean found = FALSE;
|
|
|
|
g_variant_get(reply, "(a{oa{sa{sv}}})", &it);
|
|
|
|
GVariant *props = NULL;
|
|
const char *iface_name = NULL;
|
|
|
|
while (!found && g_variant_iter_loop(it, "{&o@a{sa{sv}}}", &obj_path, &ifaces)) {
|
|
GVariantIter it2;
|
|
g_variant_iter_init(&it2, ifaces);
|
|
|
|
while (!found && g_variant_iter_loop(&it2, "{&s@a{sv}}", &iface_name, &props)) {
|
|
if (g_strcmp0(iface_name, "org.bluez.Device1") == 0) {
|
|
gboolean connected = FALSE;
|
|
const char *adapter_path = NULL;
|
|
|
|
if (g_variant_lookup(props, "Adapter", "&o", &adapter_path) &&
|
|
g_strcmp0(adapter_path, "/org/bluez/hci0") == 0 &&
|
|
g_variant_lookup(props, "Connected", "b", &connected) &&
|
|
connected)
|
|
{
|
|
const char *s = NULL;
|
|
|
|
if (!g_variant_lookup(props, "Alias", "&s", &s))
|
|
if (!g_variant_lookup(props, "Name", "&s", &s))
|
|
g_variant_lookup(props, "Address", "&s", &s);
|
|
|
|
if (s && *s) {
|
|
g_strlcpy(devname, " ", sizeof devname);
|
|
|
|
if (g_utf8_strlen(s, -1) > 10) {
|
|
const char *cut = g_utf8_offset_to_pointer(s, 10);
|
|
gsize n = (gsize)(cut - s);
|
|
gsize pre = (gsize)strlen(devname);
|
|
if (pre < sizeof devname - 1) {
|
|
gsize avail = sizeof devname - pre - 1;
|
|
if (n > avail) n = avail;
|
|
memcpy(devname + pre, s, n);
|
|
devname[pre + n] = '\0';
|
|
g_strlcat(devname, "...", sizeof devname);
|
|
}
|
|
} else {
|
|
g_strlcat(devname, s, sizeof devname);
|
|
}
|
|
|
|
found = TRUE;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (found) {
|
|
if (props) g_variant_unref(props);
|
|
if (ifaces) g_variant_unref(ifaces);
|
|
}
|
|
|
|
g_variant_iter_free(it);
|
|
g_variant_unref(reply);
|
|
|
|
return devname[0] ? devname : " ON";
|
|
}
|