forked from external/yambar
Apply "clang-format" preferences globally
This commit is contained in:
parent
d841aeeecd
commit
b85ba99980
64 changed files with 1868 additions and 2678 deletions
223
modules/alsa.c
223
modules/alsa.c
|
@ -1,8 +1,8 @@
|
|||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/inotify.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#include <alsa/asoundlib.h>
|
||||
|
||||
|
@ -10,10 +10,10 @@
|
|||
|
||||
#define LOG_MODULE "alsa"
|
||||
#define LOG_ENABLE_DBG 0
|
||||
#include "../log.h"
|
||||
#include "../bar/bar.h"
|
||||
#include "../config-verify.h"
|
||||
#include "../config.h"
|
||||
#include "../log.h"
|
||||
#include "../plugin.h"
|
||||
|
||||
enum channel_type { CHANNEL_PLAYBACK, CHANNEL_CAPTURE };
|
||||
|
@ -29,7 +29,8 @@ struct channel {
|
|||
bool muted;
|
||||
};
|
||||
|
||||
struct private {
|
||||
struct private
|
||||
{
|
||||
char *card;
|
||||
char *mixer;
|
||||
char *volume_name;
|
||||
|
@ -70,7 +71,8 @@ static void
|
|||
destroy(struct module *mod)
|
||||
{
|
||||
struct private *m = mod->private;
|
||||
tll_foreach(m->channels, it) {
|
||||
tll_foreach(m->channels, it)
|
||||
{
|
||||
channel_free(&it->item);
|
||||
tll_remove(m->channels, it);
|
||||
}
|
||||
|
@ -129,9 +131,7 @@ content(struct module *mod)
|
|||
if (use_db) {
|
||||
bool use_linear = db_max - db_min <= 24 * 100;
|
||||
if (use_linear) {
|
||||
percent = db_min - db_max > 0
|
||||
? round(100. * (db_cur - db_min) / (db_max - db_min))
|
||||
: 0;
|
||||
percent = db_min - db_max > 0 ? round(100. * (db_cur - db_min) / (db_max - db_min)) : 0;
|
||||
} else {
|
||||
double normalized = pow(10, (double)(db_cur - db_max) / 6000.);
|
||||
if (db_min != SND_CTL_TLV_DB_GAIN_MUTE) {
|
||||
|
@ -141,9 +141,7 @@ content(struct module *mod)
|
|||
percent = round(100. * normalized);
|
||||
}
|
||||
} else {
|
||||
percent = vol_max - vol_min > 0
|
||||
? round(100. * (vol_cur - vol_min) / (vol_max - vol_min))
|
||||
: 0;
|
||||
percent = vol_max - vol_min > 0 ? round(100. * (vol_cur - vol_min) / (vol_max - vol_min)) : 0;
|
||||
}
|
||||
|
||||
struct tag_set tags = {
|
||||
|
@ -173,107 +171,94 @@ update_state(struct module *mod, snd_mixer_elem_t *elem)
|
|||
|
||||
/* If volume level can be changed (i.e. this isn't just a switch;
|
||||
* e.g. a digital channel), get current channel levels */
|
||||
tll_foreach(m->channels, it) {
|
||||
tll_foreach(m->channels, it)
|
||||
{
|
||||
struct channel *chan = &it->item;
|
||||
|
||||
const bool has_volume = chan->type == CHANNEL_PLAYBACK
|
||||
? m->has_playback_volume : m->has_capture_volume;
|
||||
const bool has_db = chan->type == CHANNEL_PLAYBACK
|
||||
? m->has_playback_db : m->has_capture_db;
|
||||
const bool has_volume = chan->type == CHANNEL_PLAYBACK ? m->has_playback_volume : m->has_capture_volume;
|
||||
const bool has_db = chan->type == CHANNEL_PLAYBACK ? m->has_playback_db : m->has_capture_db;
|
||||
|
||||
if (!has_volume && !has_db)
|
||||
continue;
|
||||
|
||||
|
||||
if (has_db) {
|
||||
chan->use_db = true;
|
||||
|
||||
const long min = chan->type == CHANNEL_PLAYBACK
|
||||
? m->playback_db_min : m->capture_db_min;
|
||||
const long max = chan->type == CHANNEL_PLAYBACK
|
||||
? m->playback_db_max : m->capture_db_max;
|
||||
const long min = chan->type == CHANNEL_PLAYBACK ? m->playback_db_min : m->capture_db_min;
|
||||
const long max = chan->type == CHANNEL_PLAYBACK ? m->playback_db_max : m->capture_db_max;
|
||||
assert(min <= max);
|
||||
|
||||
int r = chan->type == CHANNEL_PLAYBACK
|
||||
? snd_mixer_selem_get_playback_dB(elem, chan->id, &chan->db_cur)
|
||||
: snd_mixer_selem_get_capture_dB(elem, chan->id, &chan->db_cur);
|
||||
int r = chan->type == CHANNEL_PLAYBACK ? snd_mixer_selem_get_playback_dB(elem, chan->id, &chan->db_cur)
|
||||
: snd_mixer_selem_get_capture_dB(elem, chan->id, &chan->db_cur);
|
||||
|
||||
if (r < 0) {
|
||||
LOG_ERR("%s,%s: %s: failed to get current dB",
|
||||
m->card, m->mixer, chan->name);
|
||||
LOG_ERR("%s,%s: %s: failed to get current dB", m->card, m->mixer, chan->name);
|
||||
}
|
||||
|
||||
if (chan->db_cur < min) {
|
||||
LOG_WARN(
|
||||
"%s,%s: %s: current dB is less than the indicated minimum: "
|
||||
"%ld < %ld", m->card, m->mixer, chan->name, chan->db_cur, min);
|
||||
LOG_WARN("%s,%s: %s: current dB is less than the indicated minimum: "
|
||||
"%ld < %ld",
|
||||
m->card, m->mixer, chan->name, chan->db_cur, min);
|
||||
chan->db_cur = min;
|
||||
}
|
||||
|
||||
if (chan->db_cur > max) {
|
||||
LOG_WARN(
|
||||
"%s,%s: %s: current dB is greater than the indicated maximum: "
|
||||
"%ld > %ld", m->card, m->mixer, chan->name, chan->db_cur, max);
|
||||
LOG_WARN("%s,%s: %s: current dB is greater than the indicated maximum: "
|
||||
"%ld > %ld",
|
||||
m->card, m->mixer, chan->name, chan->db_cur, max);
|
||||
chan->db_cur = max;
|
||||
}
|
||||
|
||||
assert(chan->db_cur >= min);
|
||||
assert(chan->db_cur <= max );
|
||||
assert(chan->db_cur <= max);
|
||||
|
||||
LOG_DBG("%s,%s: %s: dB: %ld",
|
||||
m->card, m->mixer, chan->name, chan->db_cur);
|
||||
LOG_DBG("%s,%s: %s: dB: %ld", m->card, m->mixer, chan->name, chan->db_cur);
|
||||
} else
|
||||
chan->use_db = false;
|
||||
|
||||
const long min = chan->type == CHANNEL_PLAYBACK
|
||||
? m->playback_vol_min : m->capture_vol_min;
|
||||
const long max = chan->type == CHANNEL_PLAYBACK
|
||||
? m->playback_vol_max : m->capture_vol_max;
|
||||
const long min = chan->type == CHANNEL_PLAYBACK ? m->playback_vol_min : m->capture_vol_min;
|
||||
const long max = chan->type == CHANNEL_PLAYBACK ? m->playback_vol_max : m->capture_vol_max;
|
||||
assert(min <= max);
|
||||
|
||||
int r = chan->type == CHANNEL_PLAYBACK
|
||||
? snd_mixer_selem_get_playback_volume(elem, chan->id, &chan->vol_cur)
|
||||
: snd_mixer_selem_get_capture_volume(elem, chan->id, &chan->vol_cur);
|
||||
int r = chan->type == CHANNEL_PLAYBACK ? snd_mixer_selem_get_playback_volume(elem, chan->id, &chan->vol_cur)
|
||||
: snd_mixer_selem_get_capture_volume(elem, chan->id, &chan->vol_cur);
|
||||
|
||||
if (r < 0) {
|
||||
LOG_ERR("%s,%s: %s: failed to get current volume",
|
||||
m->card, m->mixer, chan->name);
|
||||
LOG_ERR("%s,%s: %s: failed to get current volume", m->card, m->mixer, chan->name);
|
||||
}
|
||||
|
||||
if (chan->vol_cur < min) {
|
||||
LOG_WARN(
|
||||
"%s,%s: %s: current volume is less than the indicated minimum: "
|
||||
"%ld < %ld", m->card, m->mixer, chan->name, chan->vol_cur, min);
|
||||
LOG_WARN("%s,%s: %s: current volume is less than the indicated minimum: "
|
||||
"%ld < %ld",
|
||||
m->card, m->mixer, chan->name, chan->vol_cur, min);
|
||||
chan->vol_cur = min;
|
||||
}
|
||||
|
||||
if (chan->vol_cur > max) {
|
||||
LOG_WARN(
|
||||
"%s,%s: %s: current volume is greater than the indicated maximum: "
|
||||
"%ld > %ld", m->card, m->mixer, chan->name, chan->vol_cur, max);
|
||||
LOG_WARN("%s,%s: %s: current volume is greater than the indicated maximum: "
|
||||
"%ld > %ld",
|
||||
m->card, m->mixer, chan->name, chan->vol_cur, max);
|
||||
chan->vol_cur = max;
|
||||
}
|
||||
|
||||
assert(chan->vol_cur >= min);
|
||||
assert(chan->vol_cur <= max );
|
||||
assert(chan->vol_cur <= max);
|
||||
|
||||
LOG_DBG("%s,%s: %s: volume: %ld",
|
||||
m->card, m->mixer, chan->name, chan->vol_cur);
|
||||
LOG_DBG("%s,%s: %s: volume: %ld", m->card, m->mixer, chan->name, chan->vol_cur);
|
||||
}
|
||||
|
||||
/* Get channels’ muted state */
|
||||
tll_foreach(m->channels, it) {
|
||||
tll_foreach(m->channels, it)
|
||||
{
|
||||
struct channel *chan = &it->item;
|
||||
|
||||
int unmuted;
|
||||
|
||||
int r = chan->type == CHANNEL_PLAYBACK
|
||||
? snd_mixer_selem_get_playback_switch(elem, chan->id, &unmuted)
|
||||
: snd_mixer_selem_get_capture_switch(elem, chan->id, &unmuted);
|
||||
int r = chan->type == CHANNEL_PLAYBACK ? snd_mixer_selem_get_playback_switch(elem, chan->id, &unmuted)
|
||||
: snd_mixer_selem_get_capture_switch(elem, chan->id, &unmuted);
|
||||
|
||||
if (r < 0) {
|
||||
LOG_WARN("%s,%s: %s: failed to get muted state",
|
||||
m->card, m->mixer, chan->name);
|
||||
LOG_WARN("%s,%s: %s: failed to get muted state", m->card, m->mixer, chan->name);
|
||||
unmuted = 1;
|
||||
}
|
||||
|
||||
|
@ -309,10 +294,8 @@ run_while_online(struct module *mod)
|
|||
return ret;
|
||||
}
|
||||
|
||||
if (snd_mixer_attach(handle, m->card) != 0 ||
|
||||
snd_mixer_selem_register(handle, NULL, NULL) != 0 ||
|
||||
snd_mixer_load(handle) != 0)
|
||||
{
|
||||
if (snd_mixer_attach(handle, m->card) != 0 || snd_mixer_selem_register(handle, NULL, NULL) != 0
|
||||
|| snd_mixer_load(handle) != 0) {
|
||||
LOG_ERR("failed to attach to card");
|
||||
ret = RUN_FAILED_CONNECT;
|
||||
goto err;
|
||||
|
@ -323,7 +306,7 @@ run_while_online(struct module *mod)
|
|||
snd_mixer_selem_id_set_index(sid, 0);
|
||||
snd_mixer_selem_id_set_name(sid, m->mixer);
|
||||
|
||||
snd_mixer_elem_t* elem = snd_mixer_find_selem(handle, sid);
|
||||
snd_mixer_elem_t *elem = snd_mixer_find_selem(handle, sid);
|
||||
if (elem == NULL) {
|
||||
LOG_ERR("failed to find mixer");
|
||||
goto err;
|
||||
|
@ -332,30 +315,24 @@ run_while_online(struct module *mod)
|
|||
/* Get playback volume range */
|
||||
m->has_playback_volume = snd_mixer_selem_has_playback_volume(elem) > 0;
|
||||
if (m->has_playback_volume) {
|
||||
if (snd_mixer_selem_get_playback_volume_range(
|
||||
elem, &m->playback_vol_min, &m->playback_vol_max) < 0)
|
||||
{
|
||||
LOG_ERR("%s,%s: failed to get playback volume range",
|
||||
m->card, m->mixer);
|
||||
if (snd_mixer_selem_get_playback_volume_range(elem, &m->playback_vol_min, &m->playback_vol_max) < 0) {
|
||||
LOG_ERR("%s,%s: failed to get playback volume range", m->card, m->mixer);
|
||||
assert(m->playback_vol_min == 0);
|
||||
assert(m->playback_vol_max == 0);
|
||||
}
|
||||
|
||||
if (m->playback_vol_min > m->playback_vol_max) {
|
||||
LOG_WARN(
|
||||
"%s,%s: indicated minimum playback volume is greater than the "
|
||||
"maximum: %ld > %ld",
|
||||
m->card, m->mixer, m->playback_vol_min, m->playback_vol_max);
|
||||
LOG_WARN("%s,%s: indicated minimum playback volume is greater than the "
|
||||
"maximum: %ld > %ld",
|
||||
m->card, m->mixer, m->playback_vol_min, m->playback_vol_max);
|
||||
m->playback_vol_min = m->playback_vol_max;
|
||||
}
|
||||
}
|
||||
|
||||
if (snd_mixer_selem_get_playback_dB_range(
|
||||
elem, &m->playback_db_min, &m->playback_db_max) < 0)
|
||||
{
|
||||
LOG_WARN(
|
||||
"%s,%s: failed to get playback dB range, "
|
||||
"will use raw volume values instead", m->card, m->mixer);
|
||||
if (snd_mixer_selem_get_playback_dB_range(elem, &m->playback_db_min, &m->playback_db_max) < 0) {
|
||||
LOG_WARN("%s,%s: failed to get playback dB range, "
|
||||
"will use raw volume values instead",
|
||||
m->card, m->mixer);
|
||||
m->has_playback_db = false;
|
||||
} else
|
||||
m->has_playback_db = true;
|
||||
|
@ -363,30 +340,24 @@ run_while_online(struct module *mod)
|
|||
/* Get capture volume range */
|
||||
m->has_capture_volume = snd_mixer_selem_has_capture_volume(elem) > 0;
|
||||
if (m->has_capture_volume) {
|
||||
if (snd_mixer_selem_get_capture_volume_range(
|
||||
elem, &m->capture_vol_min, &m->capture_vol_max) < 0)
|
||||
{
|
||||
LOG_ERR("%s,%s: failed to get capture volume range",
|
||||
m->card, m->mixer);
|
||||
if (snd_mixer_selem_get_capture_volume_range(elem, &m->capture_vol_min, &m->capture_vol_max) < 0) {
|
||||
LOG_ERR("%s,%s: failed to get capture volume range", m->card, m->mixer);
|
||||
assert(m->capture_vol_min == 0);
|
||||
assert(m->capture_vol_max == 0);
|
||||
}
|
||||
|
||||
if (m->capture_vol_min > m->capture_vol_max) {
|
||||
LOG_WARN(
|
||||
"%s,%s: indicated minimum capture volume is greater than the "
|
||||
"maximum: %ld > %ld",
|
||||
m->card, m->mixer, m->capture_vol_min, m->capture_vol_max);
|
||||
LOG_WARN("%s,%s: indicated minimum capture volume is greater than the "
|
||||
"maximum: %ld > %ld",
|
||||
m->card, m->mixer, m->capture_vol_min, m->capture_vol_max);
|
||||
m->capture_vol_min = m->capture_vol_max;
|
||||
}
|
||||
}
|
||||
|
||||
if (snd_mixer_selem_get_capture_dB_range(
|
||||
elem, &m->capture_db_min, &m->capture_db_max) < 0)
|
||||
{
|
||||
LOG_WARN(
|
||||
"%s,%s: failed to get capture dB range, "
|
||||
"will use raw volume values instead", m->card, m->mixer);
|
||||
if (snd_mixer_selem_get_capture_dB_range(elem, &m->capture_db_min, &m->capture_db_max) < 0) {
|
||||
LOG_WARN("%s,%s: failed to get capture dB range, "
|
||||
"will use raw volume values instead",
|
||||
m->card, m->mixer);
|
||||
m->has_capture_db = false;
|
||||
} else
|
||||
m->has_capture_db = true;
|
||||
|
@ -400,7 +371,7 @@ run_while_online(struct module *mod)
|
|||
struct channel chan = {
|
||||
.id = i,
|
||||
.type = is_playback ? CHANNEL_PLAYBACK : CHANNEL_CAPTURE,
|
||||
.name = strdup(snd_mixer_selem_channel_name( i)),
|
||||
.name = strdup(snd_mixer_selem_channel_name(i)),
|
||||
};
|
||||
tll_push_back(m->channels, chan);
|
||||
}
|
||||
|
@ -413,13 +384,13 @@ run_while_online(struct module *mod)
|
|||
|
||||
char channels_str[1024];
|
||||
int channels_idx = 0;
|
||||
tll_foreach(m->channels, it) {
|
||||
tll_foreach(m->channels, it)
|
||||
{
|
||||
const struct channel *chan = &it->item;
|
||||
|
||||
channels_idx += snprintf(
|
||||
&channels_str[channels_idx], sizeof(channels_str) - channels_idx,
|
||||
channels_idx == 0 ? "%s (%s)" : ", %s (%s)",
|
||||
chan->name, chan->type == CHANNEL_PLAYBACK ? "🔊" : "🎤");
|
||||
channels_idx += snprintf(&channels_str[channels_idx], sizeof(channels_str) - channels_idx,
|
||||
channels_idx == 0 ? "%s (%s)" : ", %s (%s)", chan->name,
|
||||
chan->type == CHANNEL_PLAYBACK ? "🔊" : "🎤");
|
||||
assert(channels_idx <= sizeof(channels_str));
|
||||
}
|
||||
|
||||
|
@ -429,7 +400,8 @@ run_while_online(struct module *mod)
|
|||
bool volume_channel_is_valid = m->volume_name == NULL;
|
||||
bool muted_channel_is_valid = m->muted_name == NULL;
|
||||
|
||||
tll_foreach(m->channels, it) {
|
||||
tll_foreach(m->channels, it)
|
||||
{
|
||||
const struct channel *chan = &it->item;
|
||||
if (m->volume_name != NULL && strcmp(chan->name, m->volume_name) == 0) {
|
||||
m->volume_chan = chan;
|
||||
|
@ -462,26 +434,14 @@ run_while_online(struct module *mod)
|
|||
update_state(mod, elem);
|
||||
|
||||
LOG_INFO(
|
||||
"%s,%s: %s range=%ld-%ld, current=%ld%s (sources: volume=%s, muted=%s)",
|
||||
m->card, m->mixer,
|
||||
"%s,%s: %s range=%ld-%ld, current=%ld%s (sources: volume=%s, muted=%s)", m->card, m->mixer,
|
||||
m->volume_chan->use_db ? "dB" : "volume",
|
||||
(m->volume_chan->type == CHANNEL_PLAYBACK
|
||||
? (m->volume_chan->use_db
|
||||
? m->playback_db_min
|
||||
: m->playback_vol_min)
|
||||
: (m->volume_chan->use_db
|
||||
? m->capture_db_min
|
||||
: m->capture_vol_min)),
|
||||
(m->volume_chan->type == CHANNEL_PLAYBACK
|
||||
? (m->volume_chan->use_db
|
||||
? m->playback_db_max
|
||||
: m->playback_vol_max)
|
||||
: (m->volume_chan->use_db
|
||||
? m->capture_db_max
|
||||
: m->capture_vol_max)),
|
||||
(m->volume_chan->type == CHANNEL_PLAYBACK ? (m->volume_chan->use_db ? m->playback_db_min : m->playback_vol_min)
|
||||
: (m->volume_chan->use_db ? m->capture_db_min : m->capture_vol_min)),
|
||||
(m->volume_chan->type == CHANNEL_PLAYBACK ? (m->volume_chan->use_db ? m->playback_db_max : m->playback_vol_max)
|
||||
: (m->volume_chan->use_db ? m->capture_db_max : m->capture_vol_max)),
|
||||
m->volume_chan->use_db ? m->volume_chan->db_cur : m->volume_chan->vol_cur,
|
||||
m->muted_chan->muted ? " (muted)" : "",
|
||||
m->volume_chan->name, m->muted_chan->name);
|
||||
m->muted_chan->muted ? " (muted)" : "", m->volume_chan->name, m->muted_chan->name);
|
||||
|
||||
mod->bar->refresh(mod->bar);
|
||||
|
||||
|
@ -595,8 +555,7 @@ run(struct module *mod)
|
|||
bool have_create_event = false;
|
||||
|
||||
while (!have_create_event) {
|
||||
struct pollfd fds[] = {{.fd = mod->abort_fd, .events = POLLIN},
|
||||
{.fd = ifd, .events = POLLIN}};
|
||||
struct pollfd fds[] = {{.fd = mod->abort_fd, .events = POLLIN}, {.fd = ifd, .events = POLLIN}};
|
||||
int r = poll(fds, sizeof(fds) / sizeof(fds[0]), -1);
|
||||
|
||||
if (r < 0) {
|
||||
|
@ -638,7 +597,7 @@ run(struct module *mod)
|
|||
break;
|
||||
|
||||
/* Consume inotify data */
|
||||
for (const char *ptr = buf; ptr < buf + len; ) {
|
||||
for (const char *ptr = buf; ptr < buf + len;) {
|
||||
const struct inotify_event *e = (const struct inotify_event *)ptr;
|
||||
|
||||
if (e->mask & IN_CREATE) {
|
||||
|
@ -656,23 +615,20 @@ out:
|
|||
if (wd >= 0)
|
||||
inotify_rm_watch(ifd, wd);
|
||||
if (ifd >= 0)
|
||||
close (ifd);
|
||||
close(ifd);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static struct module *
|
||||
alsa_new(const char *card, const char *mixer,
|
||||
const char *volume_channel_name, const char *muted_channel_name,
|
||||
alsa_new(const char *card, const char *mixer, const char *volume_channel_name, const char *muted_channel_name,
|
||||
struct particle *label)
|
||||
{
|
||||
struct private *priv = calloc(1, sizeof(*priv));
|
||||
priv->label = label;
|
||||
priv->card = strdup(card);
|
||||
priv->mixer = strdup(mixer);
|
||||
priv->volume_name =
|
||||
volume_channel_name != NULL ? strdup(volume_channel_name) : NULL;
|
||||
priv->muted_name =
|
||||
muted_channel_name != NULL ? strdup(muted_channel_name) : NULL;
|
||||
priv->volume_name = volume_channel_name != NULL ? strdup(volume_channel_name) : NULL;
|
||||
priv->muted_name = muted_channel_name != NULL ? strdup(muted_channel_name) : NULL;
|
||||
|
||||
struct module *mod = module_common_new();
|
||||
mod->private = priv;
|
||||
|
@ -692,12 +648,9 @@ from_conf(const struct yml_node *node, struct conf_inherit inherited)
|
|||
const struct yml_node *muted = yml_get_value(node, "muted");
|
||||
const struct yml_node *content = yml_get_value(node, "content");
|
||||
|
||||
return alsa_new(
|
||||
yml_value_as_string(card),
|
||||
yml_value_as_string(mixer),
|
||||
volume != NULL ? yml_value_as_string(volume) : NULL,
|
||||
muted != NULL ? yml_value_as_string(muted) : NULL,
|
||||
conf_to_particle(content, inherited));
|
||||
return alsa_new(yml_value_as_string(card), yml_value_as_string(mixer),
|
||||
volume != NULL ? yml_value_as_string(volume) : NULL,
|
||||
muted != NULL ? yml_value_as_string(muted) : NULL, conf_to_particle(content, inherited));
|
||||
}
|
||||
|
||||
static bool
|
||||
|
|
|
@ -1,25 +1,26 @@
|
|||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <math.h>
|
||||
#include <poll.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
#include <assert.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <poll.h>
|
||||
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <libudev.h>
|
||||
|
||||
#define LOG_MODULE "backlight"
|
||||
#include "../log.h"
|
||||
#include "../bar/bar.h"
|
||||
#include "../config.h"
|
||||
#include "../config-verify.h"
|
||||
#include "../config.h"
|
||||
#include "../log.h"
|
||||
#include "../plugin.h"
|
||||
|
||||
struct private {
|
||||
struct private
|
||||
{
|
||||
struct particle *label;
|
||||
|
||||
char *device;
|
||||
|
@ -145,8 +146,7 @@ initialize(struct private *m)
|
|||
|
||||
m->current_brightness = readint_from_fd(current_fd);
|
||||
|
||||
LOG_INFO("%s: brightness: %ld (max: %ld)", m->device, m->current_brightness,
|
||||
m->max_brightness);
|
||||
LOG_INFO("%s: brightness: %ld (max: %ld)", m->device, m->current_brightness, m->max_brightness);
|
||||
|
||||
return current_fd;
|
||||
}
|
||||
|
@ -244,8 +244,7 @@ from_conf(const struct yml_node *node, struct conf_inherit inherited)
|
|||
const struct yml_node *name = yml_get_value(node, "name");
|
||||
const struct yml_node *c = yml_get_value(node, "content");
|
||||
|
||||
return backlight_new(
|
||||
yml_value_as_string(name), conf_to_particle(c, inherited));
|
||||
return backlight_new(yml_value_as_string(name), conf_to_particle(c, inherited));
|
||||
}
|
||||
|
||||
static bool
|
||||
|
|
|
@ -1,26 +1,26 @@
|
|||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <math.h>
|
||||
|
||||
#include <poll.h>
|
||||
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <libudev.h>
|
||||
#include <tllist.h>
|
||||
|
||||
#define LOG_MODULE "battery"
|
||||
#define LOG_ENABLE_DBG 0
|
||||
#include "../log.h"
|
||||
#include "../bar/bar.h"
|
||||
#include "../config.h"
|
||||
#include "../config-verify.h"
|
||||
#include "../config.h"
|
||||
#include "../log.h"
|
||||
#include "../plugin.h"
|
||||
|
||||
#define max(x, y) ((x) > (y) ? (x) : (y))
|
||||
|
@ -37,7 +37,8 @@ struct current_state {
|
|||
struct timespec time;
|
||||
};
|
||||
|
||||
struct private {
|
||||
struct private
|
||||
{
|
||||
struct particle *label;
|
||||
|
||||
long poll_interval;
|
||||
|
@ -65,7 +66,7 @@ static int64_t
|
|||
difftimespec_ns(const struct timespec after, const struct timespec before)
|
||||
{
|
||||
return ((int64_t)after.tv_sec - (int64_t)before.tv_sec) * (int64_t)one_sec_in_ns
|
||||
+ ((int64_t)after.tv_nsec - (int64_t)before.tv_nsec);
|
||||
+ ((int64_t)after.tv_nsec - (int64_t)before.tv_nsec);
|
||||
}
|
||||
|
||||
// Linear Exponential Moving Average (unevenly spaced time series)
|
||||
|
@ -88,7 +89,7 @@ ema_linear(struct current_state *state, struct current_state curr, long tau)
|
|||
w2 = (1 - w) / tmp;
|
||||
} else {
|
||||
// Use taylor expansion for numerical stability
|
||||
w2 = 1 - tmp/2 + tmp*tmp/6 - tmp*tmp*tmp/24;
|
||||
w2 = 1 - tmp / 2 + tmp * tmp / 6 - tmp * tmp * tmp / 24;
|
||||
}
|
||||
|
||||
double ema = state->ema * w + curr.current * (1 - w2) + state->current * (w2 - w);
|
||||
|
@ -101,8 +102,7 @@ ema_linear(struct current_state *state, struct current_state curr, long tau)
|
|||
}
|
||||
|
||||
static void
|
||||
timespec_sub(const struct timespec *a, const struct timespec *b,
|
||||
struct timespec *res)
|
||||
timespec_sub(const struct timespec *a, const struct timespec *b, struct timespec *res)
|
||||
{
|
||||
|
||||
res->tv_sec = a->tv_sec - b->tv_sec;
|
||||
|
@ -145,11 +145,8 @@ content(struct module *mod)
|
|||
|
||||
mtx_lock(&mod->lock);
|
||||
|
||||
assert(m->state == STATE_FULL ||
|
||||
m->state == STATE_NOTCHARGING ||
|
||||
m->state == STATE_CHARGING ||
|
||||
m->state == STATE_DISCHARGING ||
|
||||
m->state == STATE_UNKNOWN);
|
||||
assert(m->state == STATE_FULL || m->state == STATE_NOTCHARGING || m->state == STATE_CHARGING
|
||||
|| m->state == STATE_DISCHARGING || m->state == STATE_UNKNOWN);
|
||||
|
||||
unsigned long hours;
|
||||
unsigned long minutes;
|
||||
|
@ -162,9 +159,8 @@ content(struct module *mod)
|
|||
minutes = m->time_to_full / 60;
|
||||
hours = minutes / 60;
|
||||
minutes = minutes % 60;
|
||||
} else if (m->energy_full >= 0 && m->charge && m->power >= 0) {
|
||||
unsigned long energy = m->state == STATE_CHARGING
|
||||
? m->energy_full - m->energy : m->energy;
|
||||
} else if (m->energy_full >= 0 && m->charge && m->power >= 0) {
|
||||
unsigned long energy = m->state == STATE_CHARGING ? m->energy_full - m->energy : m->energy;
|
||||
|
||||
double hours_as_float;
|
||||
if (m->state == STATE_FULL || m->state == STATE_NOTCHARGING)
|
||||
|
@ -177,8 +173,7 @@ content(struct module *mod)
|
|||
hours = hours_as_float;
|
||||
minutes = (hours_as_float - (double)hours) * 60;
|
||||
} else if (m->charge_full >= 0 && m->charge >= 0 && m->ema_current.current >= 0) {
|
||||
unsigned long charge = m->state == STATE_CHARGING
|
||||
? m->charge_full - m->charge : m->charge;
|
||||
unsigned long charge = m->state == STATE_CHARGING ? m->charge_full - m->charge : m->charge;
|
||||
|
||||
double hours_as_float;
|
||||
if (m->state == STATE_FULL || m->state == STATE_NOTCHARGING)
|
||||
|
@ -281,8 +276,7 @@ initialize(struct private *m)
|
|||
{
|
||||
int fd = openat(base_dir_fd, "manufacturer", O_RDONLY);
|
||||
if (fd == -1) {
|
||||
LOG_WARN("/sys/class/power_supply/%s/manufacturer: %s",
|
||||
m->battery, strerror(errno));
|
||||
LOG_WARN("/sys/class/power_supply/%s/manufacturer: %s", m->battery, strerror(errno));
|
||||
m->manufacturer = NULL;
|
||||
} else {
|
||||
m->manufacturer = strdup(readline_from_fd(fd, sizeof(line_buf), line_buf));
|
||||
|
@ -293,8 +287,7 @@ initialize(struct private *m)
|
|||
{
|
||||
int fd = openat(base_dir_fd, "model_name", O_RDONLY);
|
||||
if (fd == -1) {
|
||||
LOG_WARN("/sys/class/power_supply/%s/model_name: %s",
|
||||
m->battery, strerror(errno));
|
||||
LOG_WARN("/sys/class/power_supply/%s/model_name: %s", m->battery, strerror(errno));
|
||||
m->model = NULL;
|
||||
} else {
|
||||
m->model = strdup(readline_from_fd(fd, sizeof(line_buf), line_buf));
|
||||
|
@ -302,9 +295,8 @@ initialize(struct private *m)
|
|||
}
|
||||
}
|
||||
|
||||
if (faccessat(base_dir_fd, "energy_full_design", O_RDONLY, 0) == 0 &&
|
||||
faccessat(base_dir_fd, "energy_full", O_RDONLY, 0) == 0)
|
||||
{
|
||||
if (faccessat(base_dir_fd, "energy_full_design", O_RDONLY, 0) == 0
|
||||
&& faccessat(base_dir_fd, "energy_full", O_RDONLY, 0) == 0) {
|
||||
{
|
||||
int fd = openat(base_dir_fd, "energy_full_design", O_RDONLY);
|
||||
if (fd == -1) {
|
||||
|
@ -330,9 +322,8 @@ initialize(struct private *m)
|
|||
m->energy_full = m->energy_full_design = -1;
|
||||
}
|
||||
|
||||
if (faccessat(base_dir_fd, "charge_full_design", O_RDONLY, 0) == 0 &&
|
||||
faccessat(base_dir_fd, "charge_full", O_RDONLY, 0) == 0)
|
||||
{
|
||||
if (faccessat(base_dir_fd, "charge_full_design", O_RDONLY, 0) == 0
|
||||
&& faccessat(base_dir_fd, "charge_full", O_RDONLY, 0) == 0) {
|
||||
{
|
||||
int fd = openat(base_dir_fd, "charge_full_design", O_RDONLY);
|
||||
if (fd == -1) {
|
||||
|
@ -462,8 +453,8 @@ update_status(struct module *mod)
|
|||
}
|
||||
|
||||
LOG_DBG("capacity: %ld, energy: %ld, power: %ld, charge=%ld, current=%ld, "
|
||||
"time-to-empty: %ld, time-to-full: %ld", capacity,
|
||||
energy, power, charge, current, time_to_empty, time_to_full);
|
||||
"time-to-empty: %ld, time-to-full: %ld",
|
||||
capacity, energy, power, charge, current, time_to_empty, time_to_full);
|
||||
|
||||
mtx_lock(&mod->lock);
|
||||
if (m->state != state) {
|
||||
|
@ -494,13 +485,10 @@ run(struct module *mod)
|
|||
if (!initialize(m))
|
||||
return -1;
|
||||
|
||||
LOG_INFO("%s: %s %s (at %.1f%% of original capacity)",
|
||||
m->battery, m->manufacturer, m->model,
|
||||
(m->energy_full > 0
|
||||
? 100.0 * m->energy_full / m->energy_full_design
|
||||
: m->charge_full > 0
|
||||
? 100.0 * m->charge_full / m->charge_full_design
|
||||
: 0.0));
|
||||
LOG_INFO("%s: %s %s (at %.1f%% of original capacity)", m->battery, m->manufacturer, m->model,
|
||||
(m->energy_full > 0 ? 100.0 * m->energy_full / m->energy_full_design
|
||||
: m->charge_full > 0 ? 100.0 * m->charge_full / m->charge_full_design
|
||||
: 0.0));
|
||||
|
||||
int ret = 1;
|
||||
|
||||
|
@ -555,12 +543,11 @@ run(struct module *mod)
|
|||
struct udev_device *dev = udev_monitor_receive_device(mon);
|
||||
if (dev != NULL) {
|
||||
const char *sysname = udev_device_get_sysname(dev);
|
||||
udev_for_us =
|
||||
sysname != NULL && strcmp(sysname, m->battery) == 0;
|
||||
udev_for_us = sysname != NULL && strcmp(sysname, m->battery) == 0;
|
||||
|
||||
if (!udev_for_us) {
|
||||
LOG_DBG("udev notification not for us (%s != %s)",
|
||||
m->battery, sysname != sysname ? sysname : "NULL");
|
||||
LOG_DBG("udev notification not for us (%s != %s)", m->battery,
|
||||
sysname != sysname ? sysname : "NULL");
|
||||
} else
|
||||
LOG_DBG("triggering update due to udev notification");
|
||||
|
||||
|
@ -586,11 +573,9 @@ run(struct module *mod)
|
|||
struct timespec timeout_consumed;
|
||||
timespec_sub(&time_after_poll, &time_before_poll, &timeout_consumed);
|
||||
|
||||
const int timeout_consumed_ms =
|
||||
timeout_consumed.tv_sec * 1000 + timeout_consumed.tv_nsec / 1000000;
|
||||
const int timeout_consumed_ms = timeout_consumed.tv_sec * 1000 + timeout_consumed.tv_nsec / 1000000;
|
||||
|
||||
LOG_DBG("timeout-left before: %dms, consumed: %dms, updated: %dms",
|
||||
timeout_left_ms, timeout_consumed_ms,
|
||||
LOG_DBG("timeout-left before: %dms, consumed: %dms, updated: %dms", timeout_left_ms, timeout_consumed_ms,
|
||||
max(timeout_left_ms - timeout_consumed_ms, 0));
|
||||
|
||||
timeout_left_ms -= timeout_consumed_ms;
|
||||
|
@ -608,7 +593,8 @@ out:
|
|||
}
|
||||
|
||||
static struct module *
|
||||
battery_new(const char *battery, struct particle *label, long poll_interval_msecs, int battery_scale, long smoothing_secs)
|
||||
battery_new(const char *battery, struct particle *label, long poll_interval_msecs, int battery_scale,
|
||||
long smoothing_secs)
|
||||
{
|
||||
struct private *m = calloc(1, sizeof(*m));
|
||||
m->label = label;
|
||||
|
@ -617,7 +603,7 @@ battery_new(const char *battery, struct particle *label, long poll_interval_msec
|
|||
m->smoothing_scale = smoothing_secs * one_sec_in_ns;
|
||||
m->battery = strdup(battery);
|
||||
m->state = STATE_UNKNOWN;
|
||||
m->ema_current = (struct current_state){ -1, 0, (struct timespec){0, 0} };
|
||||
m->ema_current = (struct current_state){-1, 0, (struct timespec){0, 0}};
|
||||
|
||||
struct module *mod = module_common_new();
|
||||
mod->private = m;
|
||||
|
@ -637,18 +623,10 @@ from_conf(const struct yml_node *node, struct conf_inherit inherited)
|
|||
const struct yml_node *battery_scale = yml_get_value(node, "battery-scale");
|
||||
const struct yml_node *smoothing_secs = yml_get_value(node, "smoothing-secs");
|
||||
|
||||
return battery_new(
|
||||
yml_value_as_string(name),
|
||||
conf_to_particle(c, inherited),
|
||||
(poll_interval != NULL
|
||||
? yml_value_as_int(poll_interval)
|
||||
: default_poll_interval),
|
||||
(battery_scale != NULL
|
||||
? yml_value_as_int(battery_scale)
|
||||
: 1),
|
||||
(smoothing_secs != NULL
|
||||
? yml_value_as_int(smoothing_secs)
|
||||
: 100));
|
||||
return battery_new(yml_value_as_string(name), conf_to_particle(c, inherited),
|
||||
(poll_interval != NULL ? yml_value_as_int(poll_interval) : default_poll_interval),
|
||||
(battery_scale != NULL ? yml_value_as_int(battery_scale) : 1),
|
||||
(smoothing_secs != NULL ? yml_value_as_int(smoothing_secs) : 100));
|
||||
}
|
||||
|
||||
static bool
|
||||
|
@ -660,8 +638,7 @@ conf_verify_poll_interval(keychain_t *chain, const struct yml_node *node)
|
|||
const long value = yml_value_as_int(node);
|
||||
|
||||
if (value != 0 && value < min_poll_interval) {
|
||||
LOG_ERR("%s: interval value cannot be less than %ldms",
|
||||
conf_err_prefix(chain, node), min_poll_interval);
|
||||
LOG_ERR("%s: interval value cannot be less than %ldms", conf_err_prefix(chain, node), min_poll_interval);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,21 +1,22 @@
|
|||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <poll.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#define LOG_MODULE "clock"
|
||||
#define LOG_ENABLE_DBG 0
|
||||
#include "../log.h"
|
||||
#include "../bar/bar.h"
|
||||
#include "../config.h"
|
||||
#include "../config-verify.h"
|
||||
#include "../config.h"
|
||||
#include "../log.h"
|
||||
#include "../plugin.h"
|
||||
|
||||
struct private {
|
||||
struct private
|
||||
{
|
||||
struct particle *label;
|
||||
enum {
|
||||
UPDATE_GRANULARITY_SECONDS,
|
||||
|
@ -57,8 +58,7 @@ content(struct module *mod)
|
|||
strftime(time_str, sizeof(time_str), m->time_format, tm);
|
||||
|
||||
struct tag_set tags = {
|
||||
.tags = (struct tag *[]){tag_new_string(mod, "time", time_str),
|
||||
tag_new_string(mod, "date", date_str)},
|
||||
.tags = (struct tag *[]){tag_new_string(mod, "time", time_str), tag_new_string(mod, "date", date_str)},
|
||||
.count = 2,
|
||||
};
|
||||
|
||||
|
@ -90,15 +90,12 @@ run(struct module *mod)
|
|||
|
||||
switch (m->update_granularity) {
|
||||
case UPDATE_GRANULARITY_SECONDS: {
|
||||
const struct timeval next_second = {
|
||||
.tv_sec = now.tv_sec + 1,
|
||||
.tv_usec = 0};
|
||||
const struct timeval next_second = {.tv_sec = now.tv_sec + 1, .tv_usec = 0};
|
||||
|
||||
struct timeval _timeout;
|
||||
timersub(&next_second, &now, &_timeout);
|
||||
|
||||
assert(_timeout.tv_sec == 0 ||
|
||||
(_timeout.tv_sec == 1 && _timeout.tv_usec == 0));
|
||||
assert(_timeout.tv_sec == 0 || (_timeout.tv_sec == 1 && _timeout.tv_usec == 0));
|
||||
timeout_ms = _timeout.tv_usec / 1000;
|
||||
break;
|
||||
}
|
||||
|
@ -118,8 +115,7 @@ run(struct module *mod)
|
|||
/* Add 1ms to account for rounding errors */
|
||||
timeout_ms++;
|
||||
|
||||
LOG_DBG("now: %lds %ldµs -> timeout: %dms",
|
||||
now.tv_sec, now.tv_usec, timeout_ms);
|
||||
LOG_DBG("now: %lds %ldµs -> timeout: %dms", now.tv_sec, now.tv_usec, timeout_ms);
|
||||
|
||||
struct pollfd fds[] = {{.fd = mod->abort_fd, .events = POLLIN}};
|
||||
if (poll(fds, 1, timeout_ms) < 0) {
|
||||
|
@ -142,8 +138,7 @@ run(struct module *mod)
|
|||
}
|
||||
|
||||
static struct module *
|
||||
clock_new(struct particle *label, const char *date_format,
|
||||
const char *time_format, bool utc)
|
||||
clock_new(struct particle *label, const char *date_format, const char *time_format, bool utc)
|
||||
{
|
||||
struct private *m = calloc(1, sizeof(*m));
|
||||
m->label = label;
|
||||
|
@ -152,20 +147,12 @@ clock_new(struct particle *label, const char *date_format,
|
|||
m->utc = utc;
|
||||
|
||||
static const char *const seconds_formatters[] = {
|
||||
"%c",
|
||||
"%s",
|
||||
"%S",
|
||||
"%T",
|
||||
"%r",
|
||||
"%X",
|
||||
"%c", "%s", "%S", "%T", "%r", "%X",
|
||||
};
|
||||
|
||||
m->update_granularity = UPDATE_GRANULARITY_MINUTES;
|
||||
|
||||
for (size_t i = 0;
|
||||
i < sizeof(seconds_formatters) / sizeof(seconds_formatters[0]);
|
||||
i++)
|
||||
{
|
||||
for (size_t i = 0; i < sizeof(seconds_formatters) / sizeof(seconds_formatters[0]); i++) {
|
||||
if (strstr(time_format, seconds_formatters[i]) != NULL) {
|
||||
m->update_granularity = UPDATE_GRANULARITY_SECONDS;
|
||||
break;
|
||||
|
@ -173,8 +160,7 @@ clock_new(struct particle *label, const char *date_format,
|
|||
}
|
||||
|
||||
LOG_DBG("using %s update granularity",
|
||||
(m->update_granularity == UPDATE_GRANULARITY_MINUTES
|
||||
? "minutes" : "seconds"));
|
||||
(m->update_granularity == UPDATE_GRANULARITY_MINUTES ? "minutes" : "seconds"));
|
||||
|
||||
struct module *mod = module_common_new();
|
||||
mod->private = m;
|
||||
|
@ -193,11 +179,9 @@ from_conf(const struct yml_node *node, struct conf_inherit inherited)
|
|||
const struct yml_node *time_format = yml_get_value(node, "time-format");
|
||||
const struct yml_node *utc = yml_get_value(node, "utc");
|
||||
|
||||
return clock_new(
|
||||
conf_to_particle(c, inherited),
|
||||
date_format != NULL ? yml_value_as_string(date_format) : "%x",
|
||||
time_format != NULL ? yml_value_as_string(time_format) : "%H:%M",
|
||||
utc != NULL ? yml_value_as_bool(utc) : false);
|
||||
return clock_new(conf_to_particle(c, inherited), date_format != NULL ? yml_value_as_string(date_format) : "%x",
|
||||
time_format != NULL ? yml_value_as_string(time_format) : "%H:%M",
|
||||
utc != NULL ? yml_value_as_bool(utc) : false);
|
||||
}
|
||||
|
||||
static bool
|
||||
|
|
|
@ -31,7 +31,8 @@ struct cpu_stats {
|
|||
uint32_t *cur_cores_nidle;
|
||||
};
|
||||
|
||||
struct private {
|
||||
struct private
|
||||
{
|
||||
struct particle *template;
|
||||
uint16_t interval;
|
||||
size_t core_count;
|
||||
|
@ -69,28 +70,22 @@ get_cpu_nb_cores()
|
|||
}
|
||||
|
||||
static bool
|
||||
parse_proc_stat_line(const char *line, uint32_t *user, uint32_t *nice,
|
||||
uint32_t *system, uint32_t *idle, uint32_t *iowait,
|
||||
uint32_t *irq, uint32_t *softirq, uint32_t *steal,
|
||||
uint32_t *guest, uint32_t *guestnice)
|
||||
parse_proc_stat_line(const char *line, uint32_t *user, uint32_t *nice, uint32_t *system, uint32_t *idle,
|
||||
uint32_t *iowait, uint32_t *irq, uint32_t *softirq, uint32_t *steal, uint32_t *guest,
|
||||
uint32_t *guestnice)
|
||||
{
|
||||
int32_t core_id;
|
||||
if (line[sizeof("cpu") - 1] == ' ') {
|
||||
int read = sscanf(
|
||||
line,
|
||||
"cpu %" SCNu32 " %" SCNu32 " %" SCNu32 " %" SCNu32 " %" SCNu32
|
||||
" %" SCNu32 " %" SCNu32 " %" SCNu32 " %" SCNu32 " %" SCNu32,
|
||||
user, nice, system, idle, iowait, irq, softirq, steal, guest,
|
||||
guestnice);
|
||||
int read = sscanf(line,
|
||||
"cpu %" SCNu32 " %" SCNu32 " %" SCNu32 " %" SCNu32 " %" SCNu32 " %" SCNu32 " %" SCNu32
|
||||
" %" SCNu32 " %" SCNu32 " %" SCNu32,
|
||||
user, nice, system, idle, iowait, irq, softirq, steal, guest, guestnice);
|
||||
return read == 10;
|
||||
} else {
|
||||
int read = sscanf(
|
||||
line,
|
||||
"cpu%" SCNu32 " %" SCNu32 " %" SCNu32 " %" SCNu32 " %" SCNu32
|
||||
" %" SCNu32 " %" SCNu32 " %" SCNu32 " %" SCNu32 " %" SCNu32
|
||||
" %" SCNu32,
|
||||
&core_id, user, nice, system, idle, iowait, irq, softirq, steal,
|
||||
guest, guestnice);
|
||||
int read = sscanf(line,
|
||||
"cpu%" SCNu32 " %" SCNu32 " %" SCNu32 " %" SCNu32 " %" SCNu32 " %" SCNu32 " %" SCNu32
|
||||
" %" SCNu32 " %" SCNu32 " %" SCNu32 " %" SCNu32,
|
||||
&core_id, user, nice, system, idle, iowait, irq, softirq, steal, guest, guestnice);
|
||||
return read == 11;
|
||||
}
|
||||
}
|
||||
|
@ -98,18 +93,12 @@ parse_proc_stat_line(const char *line, uint32_t *user, uint32_t *nice,
|
|||
static uint8_t
|
||||
get_cpu_usage_percent(const struct cpu_stats *cpu_stats, int8_t core_idx)
|
||||
{
|
||||
uint32_t prev_total =
|
||||
cpu_stats->prev_cores_idle[core_idx + 1] +
|
||||
cpu_stats->prev_cores_nidle[core_idx + 1];
|
||||
uint32_t prev_total = cpu_stats->prev_cores_idle[core_idx + 1] + cpu_stats->prev_cores_nidle[core_idx + 1];
|
||||
|
||||
uint32_t cur_total =
|
||||
cpu_stats->cur_cores_idle[core_idx + 1] +
|
||||
cpu_stats->cur_cores_nidle[core_idx + 1];
|
||||
uint32_t cur_total = cpu_stats->cur_cores_idle[core_idx + 1] + cpu_stats->cur_cores_nidle[core_idx + 1];
|
||||
|
||||
double totald = cur_total - prev_total;
|
||||
double nidled =
|
||||
cpu_stats->cur_cores_nidle[core_idx + 1] -
|
||||
cpu_stats->prev_cores_nidle[core_idx + 1];
|
||||
double nidled = cpu_stats->cur_cores_nidle[core_idx + 1] - cpu_stats->prev_cores_nidle[core_idx + 1];
|
||||
|
||||
double percent = (nidled * 100) / (totald + 1);
|
||||
return round(percent);
|
||||
|
@ -143,10 +132,8 @@ refresh_cpu_stats(struct cpu_stats *cpu_stats, size_t core_count)
|
|||
|
||||
while ((read = getline(&line, &len, fp)) != -1 && core <= core_count) {
|
||||
if (strncmp(line, "cpu", sizeof("cpu") - 1) == 0) {
|
||||
if (!parse_proc_stat_line(
|
||||
line, &user, &nice, &system, &idle, &iowait, &irq, &softirq,
|
||||
&steal, &guest, &guestnice))
|
||||
{
|
||||
if (!parse_proc_stat_line(line, &user, &nice, &system, &idle, &iowait, &irq, &softirq, &steal, &guest,
|
||||
&guestnice)) {
|
||||
LOG_ERR("unable to parse /proc/stat line");
|
||||
goto exit;
|
||||
}
|
||||
|
@ -251,15 +238,11 @@ cpu_new(uint16_t interval, struct particle *template)
|
|||
p->interval = interval;
|
||||
p->core_count = nb_cores;
|
||||
|
||||
p->cpu_stats.prev_cores_nidle = calloc(
|
||||
nb_cores + 1, sizeof(*p->cpu_stats.prev_cores_nidle));
|
||||
p->cpu_stats.prev_cores_idle = calloc(
|
||||
nb_cores + 1, sizeof(*p->cpu_stats.prev_cores_idle));
|
||||
p->cpu_stats.prev_cores_nidle = calloc(nb_cores + 1, sizeof(*p->cpu_stats.prev_cores_nidle));
|
||||
p->cpu_stats.prev_cores_idle = calloc(nb_cores + 1, sizeof(*p->cpu_stats.prev_cores_idle));
|
||||
|
||||
p->cpu_stats.cur_cores_nidle = calloc(
|
||||
nb_cores + 1, sizeof(*p->cpu_stats.cur_cores_nidle));
|
||||
p->cpu_stats.cur_cores_idle = calloc(
|
||||
nb_cores + 1, sizeof(*p->cpu_stats.cur_cores_idle));
|
||||
p->cpu_stats.cur_cores_nidle = calloc(nb_cores + 1, sizeof(*p->cpu_stats.cur_cores_nidle));
|
||||
p->cpu_stats.cur_cores_idle = calloc(nb_cores + 1, sizeof(*p->cpu_stats.cur_cores_idle));
|
||||
|
||||
struct module *mod = module_common_new();
|
||||
mod->private = p;
|
||||
|
@ -276,9 +259,7 @@ from_conf(const struct yml_node *node, struct conf_inherit inherited)
|
|||
const struct yml_node *interval = yml_get_value(node, "poll-interval");
|
||||
const struct yml_node *c = yml_get_value(node, "content");
|
||||
|
||||
return cpu_new(
|
||||
interval == NULL ? min_poll_interval : yml_value_as_int(interval),
|
||||
conf_to_particle(c, inherited));
|
||||
return cpu_new(interval == NULL ? min_poll_interval : yml_value_as_int(interval), conf_to_particle(c, inherited));
|
||||
}
|
||||
|
||||
static bool
|
||||
|
@ -288,8 +269,7 @@ conf_verify_poll_interval(keychain_t *chain, const struct yml_node *node)
|
|||
return false;
|
||||
|
||||
if (yml_value_as_int(node) < min_poll_interval) {
|
||||
LOG_ERR("%s: interval value cannot be less than %ldms",
|
||||
conf_err_prefix(chain, node), min_poll_interval);
|
||||
LOG_ERR("%s: interval value cannot be less than %ldms", conf_err_prefix(chain, node), min_poll_interval);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
#include <dirent.h>
|
||||
#include <errno.h>
|
||||
#include <inttypes.h>
|
||||
#include <poll.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
#include <dirent.h>
|
||||
|
||||
#include <tllist.h>
|
||||
|
||||
|
@ -34,7 +34,8 @@ struct device_stats {
|
|||
bool exists;
|
||||
};
|
||||
|
||||
struct private {
|
||||
struct private
|
||||
{
|
||||
struct particle *label;
|
||||
uint16_t interval;
|
||||
tll(struct device_stats *) devices;
|
||||
|
@ -63,7 +64,7 @@ is_disk(char const *name)
|
|||
return found;
|
||||
}
|
||||
|
||||
static struct device_stats*
|
||||
static struct device_stats *
|
||||
new_device_stats(char const *name)
|
||||
{
|
||||
struct device_stats *dev = malloc(sizeof(*dev));
|
||||
|
@ -84,9 +85,7 @@ destroy(struct module *mod)
|
|||
{
|
||||
struct private *m = mod->private;
|
||||
m->label->destroy(m->label);
|
||||
tll_foreach(m->devices, it) {
|
||||
free_device_stats(it->item);
|
||||
}
|
||||
tll_foreach(m->devices, it) { free_device_stats(it->item); }
|
||||
tll_free(m->devices);
|
||||
free(m);
|
||||
module_default_destroy(mod);
|
||||
|
@ -126,9 +125,7 @@ refresh_device_stats(struct private *m)
|
|||
* The 'exists' variable is what keep tracks of whether or not /proc/diskstats
|
||||
* is still reporting the device (i.e., it is still connected).
|
||||
*/
|
||||
tll_foreach(m->devices, it) {
|
||||
it->item->exists = false;
|
||||
}
|
||||
tll_foreach(m->devices, it) { it->item->exists = false; }
|
||||
|
||||
while ((read = getline(&line, &len, fp)) != -1) {
|
||||
/*
|
||||
|
@ -156,25 +153,23 @@ refresh_device_stats(struct private *m)
|
|||
uint32_t completed_flushes = 0;
|
||||
uint32_t flushing_time = 0;
|
||||
if (!sscanf(line,
|
||||
" %" SCNu8 " %" SCNu8 " %ms %" SCNu32 " %" SCNu32 " %" SCNu64 " %" SCNu32
|
||||
" %" SCNu32 " %" SCNu32 " %" SCNu64 " %" SCNu32 " %" SCNu32 " %" SCNu32
|
||||
" %" SCNu32 " %" SCNu32 " %" SCNu32 " %" SCNu32 " %" SCNu32 " %" SCNu32
|
||||
" %" SCNu32,
|
||||
&major_number, &minor_number, &device_name, &completed_reads,
|
||||
&merged_reads, §ors_read, &reading_time, &completed_writes,
|
||||
&merged_writes, §ors_written, &writting_time, &ios_in_progress,
|
||||
&io_time, &io_weighted_time, &completed_discards, &merged_discards,
|
||||
§ors_discarded, &discarding_time, &completed_flushes, &flushing_time))
|
||||
{
|
||||
" %" SCNu8 " %" SCNu8 " %ms %" SCNu32 " %" SCNu32 " %" SCNu64 " %" SCNu32 " %" SCNu32 " %" SCNu32
|
||||
" %" SCNu64 " %" SCNu32 " %" SCNu32 " %" SCNu32 " %" SCNu32 " %" SCNu32 " %" SCNu32 " %" SCNu32
|
||||
" %" SCNu32 " %" SCNu32 " %" SCNu32,
|
||||
&major_number, &minor_number, &device_name, &completed_reads, &merged_reads, §ors_read,
|
||||
&reading_time, &completed_writes, &merged_writes, §ors_written, &writting_time,
|
||||
&ios_in_progress, &io_time, &io_weighted_time, &completed_discards, &merged_discards,
|
||||
§ors_discarded, &discarding_time, &completed_flushes, &flushing_time)) {
|
||||
LOG_ERR("unable to parse /proc/diskstats line");
|
||||
free(device_name);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
bool found = false;
|
||||
tll_foreach(m->devices, it) {
|
||||
tll_foreach(m->devices, it)
|
||||
{
|
||||
struct device_stats *dev = it->item;
|
||||
if (strcmp(dev->name, device_name) == 0){
|
||||
if (strcmp(dev->name, device_name) == 0) {
|
||||
dev->prev_sectors_read = dev->cur_sectors_read;
|
||||
dev->prev_sectors_written = dev->cur_sectors_written;
|
||||
dev->ios_in_progress = ios_in_progress;
|
||||
|
@ -200,8 +195,9 @@ refresh_device_stats(struct private *m)
|
|||
free(device_name);
|
||||
}
|
||||
|
||||
tll_foreach(m->devices, it) {
|
||||
if (!it->item->exists){
|
||||
tll_foreach(m->devices, it)
|
||||
{
|
||||
if (!it->item->exists) {
|
||||
free_device_stats(it->item);
|
||||
tll_remove(m->devices, it);
|
||||
}
|
||||
|
@ -221,12 +217,13 @@ content(struct module *mod)
|
|||
mtx_lock(&mod->lock);
|
||||
struct exposable *tag_parts[p->devices.length + 1];
|
||||
int i = 0;
|
||||
tll_foreach(p->devices, it) {
|
||||
tll_foreach(p->devices, it)
|
||||
{
|
||||
struct device_stats *dev = it->item;
|
||||
uint64_t bytes_read = (dev->cur_sectors_read - dev->prev_sectors_read) * 512;
|
||||
uint64_t bytes_written = (dev->cur_sectors_written - dev->prev_sectors_written) * 512;
|
||||
|
||||
if (dev->is_disk){
|
||||
if (dev->is_disk) {
|
||||
total_bytes_read += bytes_read;
|
||||
total_bytes_written += bytes_written;
|
||||
total_ios_in_progress += dev->ios_in_progress;
|
||||
|
@ -314,9 +311,8 @@ from_conf(const struct yml_node *node, struct conf_inherit inherited)
|
|||
const struct yml_node *interval = yml_get_value(node, "poll-interval");
|
||||
const struct yml_node *c = yml_get_value(node, "content");
|
||||
|
||||
return disk_io_new(
|
||||
interval == NULL ? min_poll_interval : yml_value_as_int(interval),
|
||||
conf_to_particle(c, inherited));
|
||||
return disk_io_new(interval == NULL ? min_poll_interval : yml_value_as_int(interval),
|
||||
conf_to_particle(c, inherited));
|
||||
}
|
||||
|
||||
static bool
|
||||
|
@ -326,9 +322,7 @@ conf_verify_poll_interval(keychain_t *chain, const struct yml_node *node)
|
|||
return false;
|
||||
|
||||
if (yml_value_as_int(node) < min_poll_interval) {
|
||||
LOG_ERR(
|
||||
"%s: poll-interval value cannot be less than %ldms",
|
||||
conf_err_prefix(chain, node), min_poll_interval);
|
||||
LOG_ERR("%s: poll-interval value cannot be less than %ldms", conf_err_prefix(chain, node), min_poll_interval);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -249,13 +249,16 @@ process_line(char *line, struct module *module)
|
|||
assert(false); /* unreachable */
|
||||
break;
|
||||
case LINE_MODE_FULLSCREEN:
|
||||
private->fullscreen = (strcmp(string, "0") != 0);
|
||||
private
|
||||
->fullscreen = (strcmp(string, "0") != 0);
|
||||
break;
|
||||
case LINE_MODE_FLOATING:
|
||||
private->floating = (strcmp(string, "0") != 0);
|
||||
private
|
||||
->floating = (strcmp(string, "0") != 0);
|
||||
break;
|
||||
case LINE_MODE_SELMON:
|
||||
private->selmon = (strcmp(string, "0") != 0);
|
||||
private
|
||||
->selmon = (strcmp(string, "0") != 0);
|
||||
break;
|
||||
case LINE_MODE_LAYOUT:
|
||||
free(private->layout);
|
||||
|
@ -438,8 +441,7 @@ run(struct module *module)
|
|||
}
|
||||
|
||||
static struct module *
|
||||
dwl_new(struct particle *label, int number_of_tags,
|
||||
struct yml_node const *name_of_tags, char const *dwl_info_filename)
|
||||
dwl_new(struct particle *label, int number_of_tags, struct yml_node const *name_of_tags, char const *dwl_info_filename)
|
||||
{
|
||||
struct private *private = calloc(1, sizeof(struct private));
|
||||
private->label = label;
|
||||
|
@ -480,8 +482,8 @@ from_conf(struct yml_node const *node, struct conf_inherit inherited)
|
|||
struct yml_node const *name_of_tags = yml_get_value(node, "name-of-tags");
|
||||
struct yml_node const *dwl_info_filename = yml_get_value(node, "dwl-info-filename");
|
||||
|
||||
return dwl_new(conf_to_particle(content, inherited), yml_value_as_int(number_of_tags),
|
||||
name_of_tags, yml_value_as_string(dwl_info_filename));
|
||||
return dwl_new(conf_to_particle(content, inherited), yml_value_as_int(number_of_tags), name_of_tags,
|
||||
yml_value_as_string(dwl_info_filename));
|
||||
}
|
||||
|
||||
static bool
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <poll.h>
|
||||
|
||||
|
@ -11,8 +11,8 @@
|
|||
#define LOG_MODULE "foreign-toplevel"
|
||||
#define LOG_ENABLE_DBG 0
|
||||
#include "../log.h"
|
||||
#include "../plugin.h"
|
||||
#include "../particles/dynlist.h"
|
||||
#include "../plugin.h"
|
||||
|
||||
#include "wlr-foreign-toplevel-management-unstable-v1.h"
|
||||
#include "xdg-output-unstable-v1.h"
|
||||
|
@ -46,7 +46,8 @@ struct toplevel {
|
|||
tll(const struct output *) outputs;
|
||||
};
|
||||
|
||||
struct private {
|
||||
struct private
|
||||
{
|
||||
struct particle *template;
|
||||
uint32_t manager_wl_name;
|
||||
struct zwlr_foreign_toplevel_manager_v1 *manager;
|
||||
|
@ -110,7 +111,8 @@ content(struct module *mod)
|
|||
|
||||
const char *current_output = mod->bar->output_name(mod->bar);
|
||||
|
||||
tll_foreach(m->toplevels, it) {
|
||||
tll_foreach(m->toplevels, it)
|
||||
{
|
||||
const struct toplevel *top = &it->item;
|
||||
|
||||
bool show = false;
|
||||
|
@ -118,11 +120,10 @@ content(struct module *mod)
|
|||
if (m->all_monitors)
|
||||
show = true;
|
||||
else if (current_output != NULL) {
|
||||
tll_foreach(top->outputs, it2) {
|
||||
tll_foreach(top->outputs, it2)
|
||||
{
|
||||
const struct output *output = it2->item;
|
||||
if (output->name != NULL &&
|
||||
strcmp(output->name, current_output) == 0)
|
||||
{
|
||||
if (output->name != NULL && strcmp(output->name, current_output) == 0) {
|
||||
show = true;
|
||||
break;
|
||||
}
|
||||
|
@ -158,22 +159,18 @@ verify_iface_version(const char *iface, uint32_t version, uint32_t wanted)
|
|||
if (version >= wanted)
|
||||
return true;
|
||||
|
||||
LOG_ERR("%s: need interface version %u, but compositor only implements %u",
|
||||
iface, wanted, version);
|
||||
LOG_ERR("%s: need interface version %u, but compositor only implements %u", iface, wanted, version);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static void
|
||||
xdg_output_handle_logical_position(void *data,
|
||||
struct zxdg_output_v1 *xdg_output,
|
||||
int32_t x, int32_t y)
|
||||
xdg_output_handle_logical_position(void *data, struct zxdg_output_v1 *xdg_output, int32_t x, int32_t y)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
xdg_output_handle_logical_size(void *data, struct zxdg_output_v1 *xdg_output,
|
||||
int32_t width, int32_t height)
|
||||
xdg_output_handle_logical_size(void *data, struct zxdg_output_v1 *xdg_output, int32_t width, int32_t height)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -183,8 +180,7 @@ xdg_output_handle_done(void *data, struct zxdg_output_v1 *xdg_output)
|
|||
}
|
||||
|
||||
static void
|
||||
xdg_output_handle_name(void *data, struct zxdg_output_v1 *xdg_output,
|
||||
const char *name)
|
||||
xdg_output_handle_name(void *data, struct zxdg_output_v1 *xdg_output, const char *name)
|
||||
{
|
||||
struct output *output = data;
|
||||
struct module *mod = output->mod;
|
||||
|
@ -198,8 +194,7 @@ xdg_output_handle_name(void *data, struct zxdg_output_v1 *xdg_output,
|
|||
}
|
||||
|
||||
static void
|
||||
xdg_output_handle_description(void *data, struct zxdg_output_v1 *xdg_output,
|
||||
const char *description)
|
||||
xdg_output_handle_description(void *data, struct zxdg_output_v1 *xdg_output, const char *description)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -238,8 +233,7 @@ app_id(void *data, struct zwlr_foreign_toplevel_handle_v1 *handle, const char *a
|
|||
}
|
||||
|
||||
static void
|
||||
output_enter(void *data, struct zwlr_foreign_toplevel_handle_v1 *handle,
|
||||
struct wl_output *wl_output)
|
||||
output_enter(void *data, struct zwlr_foreign_toplevel_handle_v1 *handle, struct wl_output *wl_output)
|
||||
{
|
||||
struct toplevel *top = data;
|
||||
struct module *mod = top->mod;
|
||||
|
@ -248,7 +242,8 @@ output_enter(void *data, struct zwlr_foreign_toplevel_handle_v1 *handle,
|
|||
mtx_lock(&mod->lock);
|
||||
|
||||
const struct output *output = NULL;
|
||||
tll_foreach(m->outputs, it) {
|
||||
tll_foreach(m->outputs, it)
|
||||
{
|
||||
if (it->item.wl_output == wl_output) {
|
||||
output = &it->item;
|
||||
break;
|
||||
|
@ -260,7 +255,8 @@ output_enter(void *data, struct zwlr_foreign_toplevel_handle_v1 *handle,
|
|||
goto out;
|
||||
}
|
||||
|
||||
tll_foreach(top->outputs, it) {
|
||||
tll_foreach(top->outputs, it)
|
||||
{
|
||||
if (it->item == output) {
|
||||
LOG_ERR("output-enter event on output we're already on");
|
||||
goto out;
|
||||
|
@ -275,8 +271,7 @@ out:
|
|||
}
|
||||
|
||||
static void
|
||||
output_leave(void *data, struct zwlr_foreign_toplevel_handle_v1 *handle,
|
||||
struct wl_output *wl_output)
|
||||
output_leave(void *data, struct zwlr_foreign_toplevel_handle_v1 *handle, struct wl_output *wl_output)
|
||||
{
|
||||
struct toplevel *top = data;
|
||||
struct module *mod = top->mod;
|
||||
|
@ -285,7 +280,8 @@ output_leave(void *data, struct zwlr_foreign_toplevel_handle_v1 *handle,
|
|||
mtx_lock(&mod->lock);
|
||||
|
||||
const struct output *output = NULL;
|
||||
tll_foreach(m->outputs, it) {
|
||||
tll_foreach(m->outputs, it)
|
||||
{
|
||||
if (it->item.wl_output == wl_output) {
|
||||
output = &it->item;
|
||||
break;
|
||||
|
@ -298,10 +294,10 @@ output_leave(void *data, struct zwlr_foreign_toplevel_handle_v1 *handle,
|
|||
}
|
||||
|
||||
bool output_removed = false;
|
||||
tll_foreach(top->outputs, it) {
|
||||
tll_foreach(top->outputs, it)
|
||||
{
|
||||
if (it->item == output) {
|
||||
LOG_DBG("unmapped: %s:%s from %s",
|
||||
top->app_id, top->title, output->name);
|
||||
LOG_DBG("unmapped: %s:%s from %s", top->app_id, top->title, output->name);
|
||||
tll_remove(top->outputs, it);
|
||||
output_removed = true;
|
||||
break;
|
||||
|
@ -318,8 +314,7 @@ out:
|
|||
}
|
||||
|
||||
static void
|
||||
state(void *data, struct zwlr_foreign_toplevel_handle_v1 *handle,
|
||||
struct wl_array *states)
|
||||
state(void *data, struct zwlr_foreign_toplevel_handle_v1 *handle, struct wl_array *states)
|
||||
{
|
||||
struct toplevel *top = data;
|
||||
|
||||
|
@ -329,12 +324,21 @@ state(void *data, struct zwlr_foreign_toplevel_handle_v1 *handle,
|
|||
bool fullscreen = false;
|
||||
|
||||
enum zwlr_foreign_toplevel_handle_v1_state *state;
|
||||
wl_array_for_each(state, states) {
|
||||
wl_array_for_each(state, states)
|
||||
{
|
||||
switch (*state) {
|
||||
case ZWLR_FOREIGN_TOPLEVEL_HANDLE_V1_STATE_MAXIMIZED: maximized = true; break;
|
||||
case ZWLR_FOREIGN_TOPLEVEL_HANDLE_V1_STATE_MINIMIZED: minimized = true; break;
|
||||
case ZWLR_FOREIGN_TOPLEVEL_HANDLE_V1_STATE_ACTIVATED: activated = true; break;
|
||||
case ZWLR_FOREIGN_TOPLEVEL_HANDLE_V1_STATE_FULLSCREEN: fullscreen = true; break;
|
||||
case ZWLR_FOREIGN_TOPLEVEL_HANDLE_V1_STATE_MAXIMIZED:
|
||||
maximized = true;
|
||||
break;
|
||||
case ZWLR_FOREIGN_TOPLEVEL_HANDLE_V1_STATE_MINIMIZED:
|
||||
minimized = true;
|
||||
break;
|
||||
case ZWLR_FOREIGN_TOPLEVEL_HANDLE_V1_STATE_ACTIVATED:
|
||||
activated = true;
|
||||
break;
|
||||
case ZWLR_FOREIGN_TOPLEVEL_HANDLE_V1_STATE_FULLSCREEN:
|
||||
fullscreen = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -364,7 +368,8 @@ closed(void *data, struct zwlr_foreign_toplevel_handle_v1 *handle)
|
|||
struct private *m = mod->private;
|
||||
|
||||
mtx_lock(&mod->lock);
|
||||
tll_foreach(m->toplevels, it) {
|
||||
tll_foreach(m->toplevels, it)
|
||||
{
|
||||
if (it->item.handle == handle) {
|
||||
toplevel_free(top);
|
||||
tll_remove(m->toplevels, it);
|
||||
|
@ -378,9 +383,7 @@ closed(void *data, struct zwlr_foreign_toplevel_handle_v1 *handle)
|
|||
}
|
||||
|
||||
static void
|
||||
parent(void *data,
|
||||
struct zwlr_foreign_toplevel_handle_v1 *handle,
|
||||
struct zwlr_foreign_toplevel_handle_v1 *parent)
|
||||
parent(void *data, struct zwlr_foreign_toplevel_handle_v1 *handle, struct zwlr_foreign_toplevel_handle_v1 *parent)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -396,9 +399,7 @@ static const struct zwlr_foreign_toplevel_handle_v1_listener toplevel_listener =
|
|||
};
|
||||
|
||||
static void
|
||||
toplevel(void *data,
|
||||
struct zwlr_foreign_toplevel_manager_v1 *manager,
|
||||
struct zwlr_foreign_toplevel_handle_v1 *handle)
|
||||
toplevel(void *data, struct zwlr_foreign_toplevel_manager_v1 *manager, struct zwlr_foreign_toplevel_handle_v1 *handle)
|
||||
{
|
||||
struct module *mod = data;
|
||||
struct private *m = mod->private;
|
||||
|
@ -412,15 +413,13 @@ toplevel(void *data,
|
|||
{
|
||||
tll_push_back(m->toplevels, toplevel);
|
||||
|
||||
zwlr_foreign_toplevel_handle_v1_add_listener(
|
||||
handle, &toplevel_listener, &tll_back(m->toplevels));
|
||||
zwlr_foreign_toplevel_handle_v1_add_listener(handle, &toplevel_listener, &tll_back(m->toplevels));
|
||||
}
|
||||
mtx_unlock(&mod->lock);
|
||||
}
|
||||
|
||||
static void
|
||||
finished(void *data,
|
||||
struct zwlr_foreign_toplevel_manager_v1 *manager)
|
||||
finished(void *data, struct zwlr_foreign_toplevel_manager_v1 *manager)
|
||||
{
|
||||
struct module *mod = data;
|
||||
struct private *m = mod->private;
|
||||
|
@ -445,15 +444,12 @@ output_xdg_output(struct output *output)
|
|||
if (output->xdg_output != NULL)
|
||||
return;
|
||||
|
||||
output->xdg_output = zxdg_output_manager_v1_get_xdg_output(
|
||||
m->xdg_output_manager, output->wl_output);
|
||||
zxdg_output_v1_add_listener(
|
||||
output->xdg_output, &xdg_output_listener, output);
|
||||
output->xdg_output = zxdg_output_manager_v1_get_xdg_output(m->xdg_output_manager, output->wl_output);
|
||||
zxdg_output_v1_add_listener(output->xdg_output, &xdg_output_listener, output);
|
||||
}
|
||||
|
||||
static void
|
||||
handle_global(void *data, struct wl_registry *registry,
|
||||
uint32_t name, const char *interface, uint32_t version)
|
||||
handle_global(void *data, struct wl_registry *registry, uint32_t name, const char *interface, uint32_t version)
|
||||
{
|
||||
struct module *mod = data;
|
||||
struct private *m = mod->private;
|
||||
|
@ -473,8 +469,7 @@ handle_global(void *data, struct wl_registry *registry,
|
|||
struct output output = {
|
||||
.mod = mod,
|
||||
.wl_name = name,
|
||||
.wl_output = wl_registry_bind(
|
||||
registry, name, &wl_output_interface, required),
|
||||
.wl_output = wl_registry_bind(registry, name, &wl_output_interface, required),
|
||||
};
|
||||
|
||||
mtx_lock(&mod->lock);
|
||||
|
@ -488,12 +483,10 @@ handle_global(void *data, struct wl_registry *registry,
|
|||
if (!verify_iface_version(interface, version, required))
|
||||
return;
|
||||
|
||||
m->xdg_output_manager = wl_registry_bind(
|
||||
registry, name, &zxdg_output_manager_v1_interface, required);
|
||||
m->xdg_output_manager = wl_registry_bind(registry, name, &zxdg_output_manager_v1_interface, required);
|
||||
|
||||
mtx_lock(&mod->lock);
|
||||
tll_foreach(m->outputs, it)
|
||||
output_xdg_output(&it->item);
|
||||
tll_foreach(m->outputs, it) output_xdg_output(&it->item);
|
||||
mtx_unlock(&mod->lock);
|
||||
}
|
||||
}
|
||||
|
@ -506,16 +499,19 @@ handle_global_remove(void *data, struct wl_registry *registry, uint32_t name)
|
|||
|
||||
mtx_lock(&mod->lock);
|
||||
|
||||
tll_foreach(m->outputs, it) {
|
||||
tll_foreach(m->outputs, it)
|
||||
{
|
||||
const struct output *output = &it->item;
|
||||
if (output->wl_name == name) {
|
||||
|
||||
/* Loop all toplevels */
|
||||
tll_foreach(m->toplevels, it2) {
|
||||
tll_foreach(m->toplevels, it2)
|
||||
{
|
||||
|
||||
/* And remove this output from their list of tracked
|
||||
* outputs */
|
||||
tll_foreach(it2->item.outputs, it3) {
|
||||
tll_foreach(it2->item.outputs, it3)
|
||||
{
|
||||
if (it3->item == output) {
|
||||
tll_remove(it2->item.outputs, it3);
|
||||
break;
|
||||
|
@ -551,9 +547,8 @@ run(struct module *mod)
|
|||
goto out;
|
||||
}
|
||||
|
||||
if ((registry = wl_display_get_registry(display)) == NULL ||
|
||||
wl_registry_add_listener(registry, ®istry_listener, mod) != 0)
|
||||
{
|
||||
if ((registry = wl_display_get_registry(display)) == NULL
|
||||
|| wl_registry_add_listener(registry, ®istry_listener, mod) != 0) {
|
||||
LOG_ERR("failed to get Wayland registry");
|
||||
goto out;
|
||||
}
|
||||
|
@ -561,18 +556,14 @@ run(struct module *mod)
|
|||
wl_display_roundtrip(display);
|
||||
|
||||
if (m->manager_wl_name == 0) {
|
||||
LOG_ERR(
|
||||
"compositor does not implement the foreign-toplevel-manager interface");
|
||||
LOG_ERR("compositor does not implement the foreign-toplevel-manager interface");
|
||||
goto out;
|
||||
}
|
||||
|
||||
m->manager = wl_registry_bind(
|
||||
registry, m->manager_wl_name,
|
||||
&zwlr_foreign_toplevel_manager_v1_interface,
|
||||
required_manager_interface_version);
|
||||
m->manager = wl_registry_bind(registry, m->manager_wl_name, &zwlr_foreign_toplevel_manager_v1_interface,
|
||||
required_manager_interface_version);
|
||||
|
||||
zwlr_foreign_toplevel_manager_v1_add_listener(
|
||||
m->manager, &manager_listener, mod);
|
||||
zwlr_foreign_toplevel_manager_v1_add_listener(m->manager, &manager_listener, mod);
|
||||
|
||||
while (true) {
|
||||
wl_display_flush(display);
|
||||
|
@ -606,12 +597,14 @@ run(struct module *mod)
|
|||
}
|
||||
|
||||
out:
|
||||
tll_foreach(m->toplevels, it) {
|
||||
tll_foreach(m->toplevels, it)
|
||||
{
|
||||
toplevel_free(&it->item);
|
||||
tll_remove(m->toplevels, it);
|
||||
}
|
||||
|
||||
tll_foreach(m->outputs, it) {
|
||||
tll_foreach(m->outputs, it)
|
||||
{
|
||||
output_free(&it->item);
|
||||
tll_remove(m->outputs, it);
|
||||
}
|
||||
|
@ -649,9 +642,7 @@ from_conf(const struct yml_node *node, struct conf_inherit inherited)
|
|||
const struct yml_node *c = yml_get_value(node, "content");
|
||||
const struct yml_node *all_monitors = yml_get_value(node, "all-monitors");
|
||||
|
||||
return ftop_new(
|
||||
conf_to_particle(c, inherited),
|
||||
all_monitors != NULL ? yml_value_as_bool(all_monitors) : false);
|
||||
return ftop_new(conf_to_particle(c, inherited), all_monitors != NULL ? yml_value_as_bool(all_monitors) : false);
|
||||
}
|
||||
|
||||
static bool
|
||||
|
|
|
@ -1,15 +1,15 @@
|
|||
#include "i3-common.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include <poll.h>
|
||||
|
||||
#if defined(ENABLE_X11)
|
||||
#include <xcb/xcb.h>
|
||||
#include <xcb/xcb_aux.h>
|
||||
#include <xcb/xcb.h>
|
||||
#include <xcb/xcb_aux.h>
|
||||
#endif
|
||||
|
||||
#include <json-c/json_tokener.h>
|
||||
|
@ -19,7 +19,7 @@
|
|||
#include "../log.h"
|
||||
|
||||
#if defined(ENABLE_X11)
|
||||
#include "../xcb.h"
|
||||
#include "../xcb.h"
|
||||
#endif
|
||||
|
||||
#include "i3-ipc.h"
|
||||
|
@ -41,14 +41,11 @@ get_socket_address_x11(struct sockaddr_un *addr)
|
|||
xcb_atom_t atom = get_atom(conn, "I3_SOCKET_PATH");
|
||||
assert(atom != XCB_ATOM_NONE);
|
||||
|
||||
xcb_get_property_cookie_t cookie
|
||||
= xcb_get_property_unchecked(
|
||||
conn, false, screen->root, atom,
|
||||
XCB_GET_PROPERTY_TYPE_ANY, 0, sizeof(addr->sun_path));
|
||||
xcb_get_property_cookie_t cookie = xcb_get_property_unchecked(conn, false, screen->root, atom,
|
||||
XCB_GET_PROPERTY_TYPE_ANY, 0, sizeof(addr->sun_path));
|
||||
|
||||
xcb_generic_error_t *err = NULL;
|
||||
xcb_get_property_reply_t *reply =
|
||||
xcb_get_property_reply(conn, cookie, &err);
|
||||
xcb_get_property_reply_t *reply = xcb_get_property_reply(conn, cookie, &err);
|
||||
bool ret = false;
|
||||
|
||||
if (err != NULL) {
|
||||
|
@ -102,11 +99,7 @@ bool
|
|||
i3_send_pkg(int sock, int cmd, char *data)
|
||||
{
|
||||
const size_t size = data != NULL ? strlen(data) : 0;
|
||||
const i3_ipc_header_t hdr = {
|
||||
.magic = I3_IPC_MAGIC,
|
||||
.size = size,
|
||||
.type = cmd
|
||||
};
|
||||
const i3_ipc_header_t hdr = {.magic = I3_IPC_MAGIC, .size = size, .type = cmd};
|
||||
|
||||
if (write(sock, &hdr, sizeof(hdr)) != (ssize_t)sizeof(hdr))
|
||||
return false;
|
||||
|
@ -120,8 +113,7 @@ i3_send_pkg(int sock, int cmd, char *data)
|
|||
}
|
||||
|
||||
bool
|
||||
i3_receive_loop(int abort_fd, int sock,
|
||||
const struct i3_ipc_callbacks *cbs, void *data)
|
||||
i3_receive_loop(int abort_fd, int sock, const struct i3_ipc_callbacks *cbs, void *data)
|
||||
{
|
||||
/* Initial reply typically requires a couple of KB. But we often
|
||||
* need more later. For example, switching workspaces can result
|
||||
|
@ -133,10 +125,7 @@ i3_receive_loop(int abort_fd, int sock,
|
|||
bool err = false;
|
||||
|
||||
while (!err) {
|
||||
struct pollfd fds[] = {
|
||||
{.fd = abort_fd, .events = POLLIN},
|
||||
{.fd = sock, .events = POLLIN}
|
||||
};
|
||||
struct pollfd fds[] = {{.fd = abort_fd, .events = POLLIN}, {.fd = sock, .events = POLLIN}};
|
||||
|
||||
int res = poll(fds, 2, -1);
|
||||
if (res <= 0) {
|
||||
|
@ -159,13 +148,11 @@ i3_receive_loop(int abort_fd, int sock,
|
|||
|
||||
/* Grow receive buffer, if necessary */
|
||||
if (buf_idx == reply_buf_size) {
|
||||
LOG_DBG("growing reply buffer: %zu -> %zu",
|
||||
reply_buf_size, reply_buf_size * 2);
|
||||
LOG_DBG("growing reply buffer: %zu -> %zu", reply_buf_size, reply_buf_size * 2);
|
||||
|
||||
char *new_buf = realloc(buf, reply_buf_size * 2);
|
||||
if (new_buf == NULL) {
|
||||
LOG_ERR("failed to grow reply buffer from %zu to %zu bytes",
|
||||
reply_buf_size, reply_buf_size * 2);
|
||||
LOG_ERR("failed to grow reply buffer from %zu to %zu bytes", reply_buf_size, reply_buf_size * 2);
|
||||
err = true;
|
||||
break;
|
||||
}
|
||||
|
@ -188,10 +175,8 @@ i3_receive_loop(int abort_fd, int sock,
|
|||
while (!err && buf_idx >= sizeof(i3_ipc_header_t)) {
|
||||
const i3_ipc_header_t *hdr = (const i3_ipc_header_t *)buf;
|
||||
if (strncmp(hdr->magic, I3_IPC_MAGIC, sizeof(hdr->magic)) != 0) {
|
||||
LOG_ERR(
|
||||
"i3 IPC header magic mismatch: expected \"%.*s\", got \"%.*s\"",
|
||||
(int)sizeof(hdr->magic), I3_IPC_MAGIC,
|
||||
(int)sizeof(hdr->magic), hdr->magic);
|
||||
LOG_ERR("i3 IPC header magic mismatch: expected \"%.*s\", got \"%.*s\"", (int)sizeof(hdr->magic),
|
||||
I3_IPC_MAGIC, (int)sizeof(hdr->magic), hdr->magic);
|
||||
|
||||
err = true;
|
||||
break;
|
||||
|
@ -210,10 +195,10 @@ i3_receive_loop(int abort_fd, int sock,
|
|||
char json_str[hdr->size + 1];
|
||||
memcpy(json_str, &buf[sizeof(*hdr)], hdr->size);
|
||||
json_str[hdr->size] = '\0';
|
||||
//printf("raw: %s\n", json_str);
|
||||
// printf("raw: %s\n", json_str);
|
||||
LOG_DBG("raw: %s\n", json_str);
|
||||
|
||||
//json_tokener *tokener = json_tokener_new();
|
||||
// json_tokener *tokener = json_tokener_new();
|
||||
struct json_object *json = json_tokener_parse(json_str);
|
||||
if (json == NULL) {
|
||||
LOG_ERR("failed to parse json");
|
||||
|
@ -262,13 +247,13 @@ i3_receive_loop(int abort_fd, int sock,
|
|||
break;
|
||||
#endif
|
||||
/* Sway extensions */
|
||||
case 100: /* IPC_GET_INPUTS */
|
||||
case 100: /* IPC_GET_INPUTS */
|
||||
pkt_handler = cbs->reply_inputs;
|
||||
break;
|
||||
|
||||
/*
|
||||
* Events
|
||||
*/
|
||||
/*
|
||||
* Events
|
||||
*/
|
||||
|
||||
case I3_IPC_EVENT_WORKSPACE:
|
||||
pkt_handler = cbs->event_workspace;
|
||||
|
@ -295,7 +280,7 @@ i3_receive_loop(int abort_fd, int sock,
|
|||
pkt_handler = cbs->event_tick;
|
||||
break;
|
||||
|
||||
/* Sway extensions */
|
||||
/* Sway extensions */
|
||||
#define SWAY_IPC_EVENT_INPUT ((1u << 31) | 21)
|
||||
case SWAY_IPC_EVENT_INPUT:
|
||||
pkt_handler = cbs->event_input;
|
||||
|
|
|
@ -2,8 +2,8 @@
|
|||
|
||||
#include <stdbool.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/un.h>
|
||||
|
||||
#include <json-c/json_util.h>
|
||||
|
@ -43,6 +43,4 @@ struct i3_ipc_callbacks {
|
|||
i3_ipc_callback_t event_input;
|
||||
};
|
||||
|
||||
bool i3_receive_loop(
|
||||
int abort_fd, int sock,
|
||||
const struct i3_ipc_callbacks *callbacks, void *data);
|
||||
bool i3_receive_loop(int abort_fd, int sock, const struct i3_ipc_callbacks *callbacks, void *data);
|
||||
|
|
214
modules/i3.c
214
modules/i3.c
|
@ -1,27 +1,27 @@
|
|||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <assert.h>
|
||||
#include <threads.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <tllist.h>
|
||||
|
||||
#define LOG_MODULE "i3"
|
||||
#define LOG_ENABLE_DBG 0
|
||||
#include "../log.h"
|
||||
#include "../bar/bar.h"
|
||||
#include "../config.h"
|
||||
#include "../config-verify.h"
|
||||
#include "../config.h"
|
||||
#include "../log.h"
|
||||
#include "../particles/dynlist.h"
|
||||
#include "../plugin.h"
|
||||
|
||||
#include "i3-ipc.h"
|
||||
#include "i3-common.h"
|
||||
#include "i3-ipc.h"
|
||||
|
||||
enum sort_mode {SORT_NONE, SORT_NATIVE, SORT_ASCENDING, SORT_DESCENDING};
|
||||
enum sort_mode { SORT_NONE, SORT_NATIVE, SORT_ASCENDING, SORT_DESCENDING };
|
||||
|
||||
struct ws_content {
|
||||
char *name;
|
||||
|
@ -48,7 +48,8 @@ struct workspace {
|
|||
} window;
|
||||
};
|
||||
|
||||
struct private {
|
||||
struct private
|
||||
{
|
||||
int left_spacing;
|
||||
int right_spacing;
|
||||
|
||||
|
@ -105,10 +106,8 @@ workspace_from_json(const struct json_object *json, struct workspace *ws)
|
|||
{
|
||||
/* Always present */
|
||||
struct json_object *id, *name, *output;
|
||||
if (!json_object_object_get_ex(json, "id", &id) ||
|
||||
!json_object_object_get_ex(json, "name", &name) ||
|
||||
!json_object_object_get_ex(json, "output", &output))
|
||||
{
|
||||
if (!json_object_object_get_ex(json, "id", &id) || !json_object_object_get_ex(json, "name", &name)
|
||||
|| !json_object_object_get_ex(json, "output", &output)) {
|
||||
LOG_ERR("workspace reply/event without 'name' and/or 'output' "
|
||||
"properties");
|
||||
return false;
|
||||
|
@ -126,14 +125,12 @@ workspace_from_json(const struct json_object *json, struct workspace *ws)
|
|||
|
||||
const char *name_as_string = json_object_get_string(name);
|
||||
|
||||
const size_t node_count = focus != NULL
|
||||
? json_object_array_length(focus)
|
||||
: 0;
|
||||
const size_t node_count = focus != NULL ? json_object_array_length(focus) : 0;
|
||||
|
||||
const bool is_empty = node_count == 0;
|
||||
int name_as_int = workspace_name_as_int(name_as_string);
|
||||
|
||||
*ws = (struct workspace) {
|
||||
*ws = (struct workspace){
|
||||
.id = json_object_get_int(id),
|
||||
.name = strdup(name_as_string),
|
||||
.name_as_int = name_as_int,
|
||||
|
@ -152,9 +149,12 @@ workspace_from_json(const struct json_object *json, struct workspace *ws)
|
|||
static void
|
||||
workspace_free_persistent(struct workspace *ws)
|
||||
{
|
||||
free(ws->output); ws->output = NULL;
|
||||
free(ws->window.title); ws->window.title = NULL;
|
||||
free(ws->window.application); ws->window.application = NULL;
|
||||
free(ws->output);
|
||||
ws->output = NULL;
|
||||
free(ws->window.title);
|
||||
ws->window.title = NULL;
|
||||
free(ws->window.application);
|
||||
ws->window.application = NULL;
|
||||
ws->id = -1;
|
||||
}
|
||||
|
||||
|
@ -162,13 +162,15 @@ static void
|
|||
workspace_free(struct workspace *ws)
|
||||
{
|
||||
workspace_free_persistent(ws);
|
||||
free(ws->name); ws->name = NULL;
|
||||
free(ws->name);
|
||||
ws->name = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
workspaces_free(struct private *m, bool free_persistent)
|
||||
{
|
||||
tll_foreach(m->workspaces, it) {
|
||||
tll_foreach(m->workspaces, it)
|
||||
{
|
||||
if (free_persistent || !it->item.persistent) {
|
||||
workspace_free(&it->item);
|
||||
tll_remove(m->workspaces, it);
|
||||
|
@ -176,7 +178,6 @@ workspaces_free(struct private *m, bool free_persistent)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
workspace_add(struct private *m, struct workspace ws)
|
||||
{
|
||||
|
@ -187,7 +188,8 @@ workspace_add(struct private *m, struct workspace ws)
|
|||
|
||||
case SORT_NATIVE:
|
||||
if (ws.name_as_int >= 0) {
|
||||
tll_foreach(m->workspaces, it) {
|
||||
tll_foreach(m->workspaces, it)
|
||||
{
|
||||
if (it->item.name_as_int < 0)
|
||||
continue;
|
||||
if (it->item.name_as_int > ws.name_as_int) {
|
||||
|
@ -202,7 +204,8 @@ workspace_add(struct private *m, struct workspace ws)
|
|||
|
||||
case SORT_ASCENDING:
|
||||
if (ws.name_as_int >= 0) {
|
||||
tll_foreach(m->workspaces, it) {
|
||||
tll_foreach(m->workspaces, it)
|
||||
{
|
||||
if (it->item.name_as_int < 0)
|
||||
continue;
|
||||
if (it->item.name_as_int > ws.name_as_int) {
|
||||
|
@ -211,10 +214,9 @@ workspace_add(struct private *m, struct workspace ws)
|
|||
}
|
||||
}
|
||||
} else {
|
||||
tll_foreach(m->workspaces, it) {
|
||||
if (strcoll(it->item.name, ws.name) > 0 ||
|
||||
it->item.name_as_int >= 0)
|
||||
{
|
||||
tll_foreach(m->workspaces, it)
|
||||
{
|
||||
if (strcoll(it->item.name, ws.name) > 0 || it->item.name_as_int >= 0) {
|
||||
tll_insert_before(m->workspaces, it, ws);
|
||||
return;
|
||||
}
|
||||
|
@ -225,14 +227,16 @@ workspace_add(struct private *m, struct workspace ws)
|
|||
|
||||
case SORT_DESCENDING:
|
||||
if (ws.name_as_int >= 0) {
|
||||
tll_foreach(m->workspaces, it) {
|
||||
tll_foreach(m->workspaces, it)
|
||||
{
|
||||
if (it->item.name_as_int < ws.name_as_int) {
|
||||
tll_insert_before(m->workspaces, it, ws);
|
||||
return;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
tll_foreach(m->workspaces, it) {
|
||||
tll_foreach(m->workspaces, it)
|
||||
{
|
||||
if (it->item.name_as_int >= 0)
|
||||
continue;
|
||||
if (strcoll(it->item.name, ws.name) < 0) {
|
||||
|
@ -249,7 +253,8 @@ workspace_add(struct private *m, struct workspace ws)
|
|||
static void
|
||||
workspace_del(struct private *m, int id)
|
||||
{
|
||||
tll_foreach(m->workspaces, it) {
|
||||
tll_foreach(m->workspaces, it)
|
||||
{
|
||||
struct workspace *ws = &it->item;
|
||||
|
||||
if (ws->id != id)
|
||||
|
@ -264,7 +269,8 @@ workspace_del(struct private *m, int id)
|
|||
static struct workspace *
|
||||
workspace_lookup(struct private *m, int id)
|
||||
{
|
||||
tll_foreach(m->workspaces, it) {
|
||||
tll_foreach(m->workspaces, it)
|
||||
{
|
||||
struct workspace *ws = &it->item;
|
||||
if (ws->id == id)
|
||||
return ws;
|
||||
|
@ -275,7 +281,8 @@ workspace_lookup(struct private *m, int id)
|
|||
static struct workspace *
|
||||
workspace_lookup_by_name(struct private *m, const char *name)
|
||||
{
|
||||
tll_foreach(m->workspaces, it) {
|
||||
tll_foreach(m->workspaces, it)
|
||||
{
|
||||
struct workspace *ws = &it->item;
|
||||
if (strcmp(ws->name, name) == 0)
|
||||
return ws;
|
||||
|
@ -339,13 +346,9 @@ workspace_update_or_add(struct private *m, const struct json_object *ws_json)
|
|||
if (json_object_object_get_ex(ws_json, "name", &_name)) {
|
||||
const char *name = json_object_get_string(_name);
|
||||
if (name != NULL) {
|
||||
struct workspace *maybe_persistent =
|
||||
workspace_lookup_by_name(m, name);
|
||||
struct workspace *maybe_persistent = workspace_lookup_by_name(m, name);
|
||||
|
||||
if (maybe_persistent != NULL &&
|
||||
maybe_persistent->persistent &&
|
||||
maybe_persistent->id < 0)
|
||||
{
|
||||
if (maybe_persistent != NULL && maybe_persistent->persistent && maybe_persistent->id < 0) {
|
||||
already_exists = maybe_persistent;
|
||||
}
|
||||
}
|
||||
|
@ -421,10 +424,9 @@ handle_workspace_event(int sock, int type, const struct json_object *json, void
|
|||
bool is_reload = strcmp(change_str, "reload") == 0;
|
||||
|
||||
struct json_object *current, *_current_id;
|
||||
if ((!json_object_object_get_ex(json, "current", ¤t) ||
|
||||
!json_object_object_get_ex(current, "id", &_current_id)) &&
|
||||
!is_reload)
|
||||
{
|
||||
if ((!json_object_object_get_ex(json, "current", ¤t)
|
||||
|| !json_object_object_get_ex(current, "id", &_current_id))
|
||||
&& !is_reload) {
|
||||
LOG_ERR("workspace event without 'current' and/or 'id' properties");
|
||||
return false;
|
||||
}
|
||||
|
@ -452,10 +454,8 @@ handle_workspace_event(int sock, int type, const struct json_object *json, void
|
|||
|
||||
else if (is_focused) {
|
||||
struct json_object *old, *_old_id, *urgent;
|
||||
if (!json_object_object_get_ex(json, "old", &old) ||
|
||||
!json_object_object_get_ex(old, "id", &_old_id) ||
|
||||
!json_object_object_get_ex(current, "urgent", &urgent))
|
||||
{
|
||||
if (!json_object_object_get_ex(json, "old", &old) || !json_object_object_get_ex(old, "id", &_old_id)
|
||||
|| !json_object_object_get_ex(current, "urgent", &urgent)) {
|
||||
LOG_ERR("workspace 'focused' event without 'old', 'name' and/or 'urgent' property");
|
||||
mtx_unlock(&mod->lock);
|
||||
return false;
|
||||
|
@ -467,7 +467,8 @@ handle_workspace_event(int sock, int type, const struct json_object *json, void
|
|||
LOG_DBG("w: %s", w->name);
|
||||
|
||||
/* Mark all workspaces on current's output invisible */
|
||||
tll_foreach(m->workspaces, it) {
|
||||
tll_foreach(m->workspaces, it)
|
||||
{
|
||||
struct workspace *ws = &it->item;
|
||||
if (ws->output != NULL && strcmp(ws->output, w->output) == 0)
|
||||
ws->visible = false;
|
||||
|
@ -501,7 +502,8 @@ handle_workspace_event(int sock, int type, const struct json_object *json, void
|
|||
|
||||
/* Re-add the workspace to ensure correct sorting */
|
||||
struct workspace ws = *w;
|
||||
tll_foreach(m->workspaces, it) {
|
||||
tll_foreach(m->workspaces, it)
|
||||
{
|
||||
if (it->item.id == current_id) {
|
||||
tll_remove(m->workspaces, it);
|
||||
break;
|
||||
|
@ -588,7 +590,8 @@ handle_window_event(int sock, int type, const struct json_object *json, void *_m
|
|||
|
||||
struct workspace *ws = NULL;
|
||||
size_t focused = 0;
|
||||
tll_foreach(m->workspaces, it) {
|
||||
tll_foreach(m->workspaces, it)
|
||||
{
|
||||
if (it->item.focused) {
|
||||
ws = &it->item;
|
||||
focused++;
|
||||
|
@ -599,10 +602,8 @@ handle_window_event(int sock, int type, const struct json_object *json, void *_m
|
|||
assert(ws != NULL);
|
||||
|
||||
struct json_object *container, *id, *name;
|
||||
if (!json_object_object_get_ex(json, "container", &container) ||
|
||||
!json_object_object_get_ex(container, "id", &id) ||
|
||||
!json_object_object_get_ex(container, "name", &name))
|
||||
{
|
||||
if (!json_object_object_get_ex(json, "container", &container) || !json_object_object_get_ex(container, "id", &id)
|
||||
|| !json_object_object_get_ex(container, "name", &name)) {
|
||||
mtx_unlock(&mod->lock);
|
||||
LOG_ERR("window event without 'container' with 'id' and 'name'");
|
||||
return false;
|
||||
|
@ -645,18 +646,14 @@ handle_window_event(int sock, int type, const struct json_object *json, void *_m
|
|||
struct json_object *app_id;
|
||||
struct json_object *pid;
|
||||
|
||||
if (json_object_object_get_ex(container, "app_id", &app_id) &&
|
||||
json_object_get_string(app_id) != NULL)
|
||||
{
|
||||
if (json_object_object_get_ex(container, "app_id", &app_id) && json_object_get_string(app_id) != NULL) {
|
||||
free(ws->window.application);
|
||||
ws->window.application = strdup(json_object_get_string(app_id));
|
||||
LOG_DBG("application: \"%s\", via 'app_id'", ws->window.application);
|
||||
}
|
||||
|
||||
/* If PID has changed, update application name from /proc/<pid>/comm */
|
||||
else if (json_object_object_get_ex(container, "pid", &pid) &&
|
||||
ws->window.pid != json_object_get_int(pid))
|
||||
{
|
||||
else if (json_object_object_get_ex(container, "pid", &pid) && ws->window.pid != json_object_get_int(pid)) {
|
||||
ws->window.pid = json_object_get_int(pid);
|
||||
|
||||
char path[64];
|
||||
|
@ -665,7 +662,8 @@ handle_window_event(int sock, int type, const struct json_object *json, void *_m
|
|||
int fd = open(path, O_RDONLY);
|
||||
if (fd == -1) {
|
||||
/* Application may simply have terminated */
|
||||
free(ws->window.application); ws->window.application = NULL;
|
||||
free(ws->window.application);
|
||||
ws->window.application = NULL;
|
||||
ws->window.pid = -1;
|
||||
|
||||
m->dirty = true;
|
||||
|
@ -837,7 +835,8 @@ content(struct module *mod)
|
|||
struct exposable *particles[tll_length(m->workspaces) + 1];
|
||||
struct exposable *current = NULL;
|
||||
|
||||
tll_foreach(m->workspaces, it) {
|
||||
tll_foreach(m->workspaces, it)
|
||||
{
|
||||
struct workspace *ws = &it->item;
|
||||
const struct ws_content *template = NULL;
|
||||
|
||||
|
@ -853,21 +852,12 @@ content(struct module *mod)
|
|||
template = ws_content_for_name(m, "");
|
||||
}
|
||||
|
||||
const char *state =
|
||||
ws->urgent ? "urgent" :
|
||||
ws->visible ? ws->focused ? "focused" : "unfocused" :
|
||||
"invisible";
|
||||
const char *state = ws->urgent ? "urgent" : ws->visible ? ws->focused ? "focused" : "unfocused" : "invisible";
|
||||
|
||||
LOG_DBG("name=%s (name-as-int=%d): visible=%s, focused=%s, urgent=%s, empty=%s, state=%s, "
|
||||
"application=%s, title=%s, mode=%s",
|
||||
ws->name, ws->name_as_int,
|
||||
ws->visible ? "yes" : "no",
|
||||
ws->focused ? "yes" : "no",
|
||||
ws->urgent ? "yes" : "no",
|
||||
ws->empty ? "yes" : "no",
|
||||
state,
|
||||
ws->window.application,
|
||||
ws->window.title,
|
||||
ws->name, ws->name_as_int, ws->visible ? "yes" : "no", ws->focused ? "yes" : "no",
|
||||
ws->urgent ? "yes" : "no", ws->empty ? "yes" : "no", state, ws->window.application, ws->window.title,
|
||||
m->mode);
|
||||
|
||||
const char *name = ws->name;
|
||||
|
@ -902,12 +892,9 @@ content(struct module *mod)
|
|||
}
|
||||
|
||||
if (template == NULL) {
|
||||
LOG_WARN(
|
||||
"no ws template for %s, and no default template available",
|
||||
ws->name);
|
||||
LOG_WARN("no ws template for %s, and no default template available", ws->name);
|
||||
} else {
|
||||
particles[particle_count++] = template->content->instantiate(
|
||||
template->content, &tags);
|
||||
particles[particle_count++] = template->content->instantiate(template->content, &tags);
|
||||
}
|
||||
|
||||
tag_set_destroy(&tags);
|
||||
|
@ -917,8 +904,7 @@ content(struct module *mod)
|
|||
particles[particle_count++] = current;
|
||||
|
||||
mtx_unlock(&mod->lock);
|
||||
return dynlist_exposable_new(
|
||||
particles, particle_count, m->left_spacing, m->right_spacing);
|
||||
return dynlist_exposable_new(particles, particle_count, m->left_spacing, m->right_spacing);
|
||||
}
|
||||
|
||||
/* Maps workspace name to a content particle. */
|
||||
|
@ -928,10 +914,8 @@ struct i3_workspaces {
|
|||
};
|
||||
|
||||
static struct module *
|
||||
i3_new(struct i3_workspaces workspaces[], size_t workspace_count,
|
||||
int left_spacing, int right_spacing, enum sort_mode sort_mode,
|
||||
size_t persistent_count,
|
||||
const char *persistent_workspaces[static persistent_count],
|
||||
i3_new(struct i3_workspaces workspaces[], size_t workspace_count, int left_spacing, int right_spacing,
|
||||
enum sort_mode sort_mode, size_t persistent_count, const char *persistent_workspaces[static persistent_count],
|
||||
bool strip_workspace_numbers)
|
||||
{
|
||||
struct private *m = calloc(1, sizeof(*m));
|
||||
|
@ -952,8 +936,7 @@ i3_new(struct i3_workspaces workspaces[], size_t workspace_count,
|
|||
m->sort_mode = sort_mode;
|
||||
|
||||
m->persistent_count = persistent_count;
|
||||
m->persistent_workspaces = calloc(
|
||||
persistent_count, sizeof(m->persistent_workspaces[0]));
|
||||
m->persistent_workspaces = calloc(persistent_count, sizeof(m->persistent_workspaces[0]));
|
||||
|
||||
for (size_t i = 0; i < persistent_count; i++)
|
||||
m->persistent_workspaces[i] = strdup(persistent_workspaces[i]);
|
||||
|
@ -976,31 +959,26 @@ from_conf(const struct yml_node *node, struct conf_inherit inherited)
|
|||
const struct yml_node *right_spacing = yml_get_value(node, "right-spacing");
|
||||
const struct yml_node *sort = yml_get_value(node, "sort");
|
||||
const struct yml_node *persistent = yml_get_value(node, "persistent");
|
||||
const struct yml_node *strip_workspace_number = yml_get_value(
|
||||
node, "strip-workspace-numbers");
|
||||
const struct yml_node *strip_workspace_number = yml_get_value(node, "strip-workspace-numbers");
|
||||
|
||||
int left = spacing != NULL ? yml_value_as_int(spacing) :
|
||||
left_spacing != NULL ? yml_value_as_int(left_spacing) : 0;
|
||||
int right = spacing != NULL ? yml_value_as_int(spacing) :
|
||||
right_spacing != NULL ? yml_value_as_int(right_spacing) : 0;
|
||||
int left = spacing != NULL ? yml_value_as_int(spacing) : left_spacing != NULL ? yml_value_as_int(left_spacing) : 0;
|
||||
int right = spacing != NULL ? yml_value_as_int(spacing)
|
||||
: right_spacing != NULL ? yml_value_as_int(right_spacing)
|
||||
: 0;
|
||||
|
||||
const char *sort_value = sort != NULL ? yml_value_as_string(sort) : NULL;
|
||||
enum sort_mode sort_mode =
|
||||
sort_value == NULL ? SORT_NONE :
|
||||
strcmp(sort_value, "none") == 0 ? SORT_NONE :
|
||||
strcmp(sort_value, "native") == 0 ? SORT_NATIVE :
|
||||
strcmp(sort_value, "ascending") == 0 ? SORT_ASCENDING : SORT_DESCENDING;
|
||||
enum sort_mode sort_mode = sort_value == NULL ? SORT_NONE
|
||||
: strcmp(sort_value, "none") == 0 ? SORT_NONE
|
||||
: strcmp(sort_value, "native") == 0 ? SORT_NATIVE
|
||||
: strcmp(sort_value, "ascending") == 0 ? SORT_ASCENDING
|
||||
: SORT_DESCENDING;
|
||||
|
||||
const size_t persistent_count =
|
||||
persistent != NULL ? yml_list_length(persistent) : 0;
|
||||
const size_t persistent_count = persistent != NULL ? yml_list_length(persistent) : 0;
|
||||
const char *persistent_workspaces[persistent_count];
|
||||
|
||||
if (persistent != NULL) {
|
||||
size_t idx = 0;
|
||||
for (struct yml_list_iter it = yml_list_iter(persistent);
|
||||
it.node != NULL;
|
||||
yml_list_next(&it), idx++)
|
||||
{
|
||||
for (struct yml_list_iter it = yml_list_iter(persistent); it.node != NULL; yml_list_next(&it), idx++) {
|
||||
persistent_workspaces[idx] = yml_value_as_string(it.node);
|
||||
}
|
||||
}
|
||||
|
@ -1008,38 +986,27 @@ from_conf(const struct yml_node *node, struct conf_inherit inherited)
|
|||
struct i3_workspaces workspaces[yml_dict_length(c)];
|
||||
|
||||
size_t idx = 0;
|
||||
for (struct yml_dict_iter it = yml_dict_iter(c);
|
||||
it.key != NULL;
|
||||
yml_dict_next(&it), idx++)
|
||||
{
|
||||
for (struct yml_dict_iter it = yml_dict_iter(c); it.key != NULL; yml_dict_next(&it), idx++) {
|
||||
workspaces[idx].name = yml_value_as_string(it.key);
|
||||
workspaces[idx].content = conf_to_particle(it.value, inherited);
|
||||
}
|
||||
|
||||
return i3_new(workspaces, yml_dict_length(c), left, right, sort_mode,
|
||||
persistent_count, persistent_workspaces,
|
||||
(strip_workspace_number != NULL
|
||||
? yml_value_as_bool(strip_workspace_number) : false));
|
||||
return i3_new(workspaces, yml_dict_length(c), left, right, sort_mode, persistent_count, persistent_workspaces,
|
||||
(strip_workspace_number != NULL ? yml_value_as_bool(strip_workspace_number) : false));
|
||||
}
|
||||
|
||||
static bool
|
||||
verify_content(keychain_t *chain, const struct yml_node *node)
|
||||
{
|
||||
if (!yml_is_dict(node)) {
|
||||
LOG_ERR(
|
||||
"%s: must be a dictionary of workspace-name: particle mappings",
|
||||
conf_err_prefix(chain, node));
|
||||
LOG_ERR("%s: must be a dictionary of workspace-name: particle mappings", conf_err_prefix(chain, node));
|
||||
return false;
|
||||
}
|
||||
|
||||
for (struct yml_dict_iter it = yml_dict_iter(node);
|
||||
it.key != NULL;
|
||||
yml_dict_next(&it))
|
||||
{
|
||||
for (struct yml_dict_iter it = yml_dict_iter(node); it.key != NULL; yml_dict_next(&it)) {
|
||||
const char *key = yml_value_as_string(it.key);
|
||||
if (key == NULL) {
|
||||
LOG_ERR("%s: key must be a string (a i3 workspace name)",
|
||||
conf_err_prefix(chain, it.key));
|
||||
LOG_ERR("%s: key must be a string (a i3 workspace name)", conf_err_prefix(chain, it.key));
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -1055,8 +1022,7 @@ verify_content(keychain_t *chain, const struct yml_node *node)
|
|||
static bool
|
||||
verify_sort(keychain_t *chain, const struct yml_node *node)
|
||||
{
|
||||
return conf_verify_enum(
|
||||
chain, node, (const char *[]){"none", "native", "ascending", "descending"}, 4);
|
||||
return conf_verify_enum(chain, node, (const char *[]){"none", "native", "ascending", "descending"}, 4);
|
||||
}
|
||||
|
||||
static bool
|
||||
|
@ -1089,5 +1055,5 @@ const struct module_iface module_i3_iface = {
|
|||
};
|
||||
|
||||
#if defined(CORE_PLUGINS_AS_SHARED_LIBRARIES)
|
||||
extern const struct module_iface iface __attribute__((weak, alias("module_i3_iface"))) ;
|
||||
extern const struct module_iface iface __attribute__((weak, alias("module_i3_iface")));
|
||||
#endif
|
||||
|
|
|
@ -1,16 +1,14 @@
|
|||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <poll.h>
|
||||
|
||||
#include "../config.h"
|
||||
#include "../config-verify.h"
|
||||
#include "../config.h"
|
||||
#include "../module.h"
|
||||
#include "../plugin.h"
|
||||
|
||||
struct private {
|
||||
struct particle *label;
|
||||
};
|
||||
struct private { struct particle *label; };
|
||||
|
||||
static void
|
||||
destroy(struct module *mod)
|
||||
|
|
|
@ -162,9 +162,7 @@ from_conf(const struct yml_node *node, struct conf_inherit inherited)
|
|||
const struct yml_node *interval = yml_get_value(node, "poll-interval");
|
||||
const struct yml_node *c = yml_get_value(node, "content");
|
||||
|
||||
return mem_new(
|
||||
interval == NULL ? min_poll_interval : yml_value_as_int(interval),
|
||||
conf_to_particle(c, inherited));
|
||||
return mem_new(interval == NULL ? min_poll_interval : yml_value_as_int(interval), conf_to_particle(c, inherited));
|
||||
}
|
||||
|
||||
static bool
|
||||
|
@ -174,8 +172,7 @@ conf_verify_poll_interval(keychain_t *chain, const struct yml_node *node)
|
|||
return false;
|
||||
|
||||
if (yml_value_as_int(node) < min_poll_interval) {
|
||||
LOG_ERR("%s: interval value cannot be less than %ldms",
|
||||
conf_err_prefix(chain, node), min_poll_interval);
|
||||
LOG_ERR("%s: interval value cannot be less than %ldms", conf_err_prefix(chain, node), min_poll_interval);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
126
modules/mpd.c
126
modules/mpd.c
|
@ -1,33 +1,34 @@
|
|||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <inttypes.h>
|
||||
#include <time.h>
|
||||
#include <threads.h>
|
||||
#include <unistd.h>
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <inttypes.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <threads.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <poll.h>
|
||||
#include <libgen.h>
|
||||
#include <poll.h>
|
||||
|
||||
#include <sys/stat.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/un.h>
|
||||
#include <sys/eventfd.h>
|
||||
#include <sys/inotify.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/un.h>
|
||||
|
||||
#include <mpd/client.h>
|
||||
|
||||
#define LOG_MODULE "mpd"
|
||||
#define LOG_ENABLE_DBG 0
|
||||
#include "../log.h"
|
||||
#include "../bar/bar.h"
|
||||
#include "../config.h"
|
||||
#include "../config-verify.h"
|
||||
#include "../config.h"
|
||||
#include "../log.h"
|
||||
#include "../plugin.h"
|
||||
|
||||
struct private {
|
||||
struct private
|
||||
{
|
||||
char *host;
|
||||
uint16_t port;
|
||||
struct particle *label;
|
||||
|
@ -38,7 +39,7 @@ struct private {
|
|||
bool repeat;
|
||||
bool random;
|
||||
bool consume;
|
||||
int volume;
|
||||
int volume;
|
||||
char *album;
|
||||
char *artist;
|
||||
char *title;
|
||||
|
@ -60,11 +61,9 @@ destroy(struct module *mod)
|
|||
struct private *m = mod->private;
|
||||
if (m->refresh_thread_id != 0) {
|
||||
assert(m->refresh_abort_fd != -1);
|
||||
if (write(m->refresh_abort_fd, &(uint64_t){1}, sizeof(uint64_t))
|
||||
!= sizeof(uint64_t))
|
||||
{
|
||||
if (write(m->refresh_abort_fd, &(uint64_t){1}, sizeof(uint64_t)) != sizeof(uint64_t)) {
|
||||
LOG_ERRNO("failed to signal abort to refresher thread");
|
||||
} else{
|
||||
} else {
|
||||
int res;
|
||||
thrd_join(m->refresh_thread_id, &res);
|
||||
}
|
||||
|
@ -132,12 +131,11 @@ content(struct module *mod)
|
|||
if (m->state == MPD_STATE_PLAY) {
|
||||
elapsed += timespec_diff_milli_seconds(&now, &m->elapsed.when);
|
||||
if (elapsed > m->duration) {
|
||||
LOG_DBG(
|
||||
"dynamic update of elapsed overflowed: "
|
||||
"elapsed=%"PRIu64", duration=%"PRIu64, elapsed, m->duration);
|
||||
LOG_DBG("dynamic update of elapsed overflowed: "
|
||||
"elapsed=%" PRIu64 ", duration=%" PRIu64,
|
||||
elapsed, m->duration);
|
||||
elapsed = m->duration;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
unsigned elapsed_secs = elapsed / 1000;
|
||||
|
@ -154,16 +152,23 @@ content(struct module *mod)
|
|||
state_str = "offline";
|
||||
else {
|
||||
switch (m->state) {
|
||||
case MPD_STATE_UNKNOWN: state_str = "unknown"; break;
|
||||
case MPD_STATE_STOP: state_str = "stopped"; break;
|
||||
case MPD_STATE_PAUSE: state_str = "paused"; break;
|
||||
case MPD_STATE_PLAY: state_str = "playing"; break;
|
||||
case MPD_STATE_UNKNOWN:
|
||||
state_str = "unknown";
|
||||
break;
|
||||
case MPD_STATE_STOP:
|
||||
state_str = "stopped";
|
||||
break;
|
||||
case MPD_STATE_PAUSE:
|
||||
state_str = "paused";
|
||||
break;
|
||||
case MPD_STATE_PLAY:
|
||||
state_str = "playing";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Tell particle to real-time track? */
|
||||
enum tag_realtime_unit realtime = m->state == MPD_STATE_PLAY
|
||||
? TAG_REALTIME_MSECS : TAG_REALTIME_NONE;
|
||||
enum tag_realtime_unit realtime = m->state == MPD_STATE_PLAY ? TAG_REALTIME_MSECS : TAG_REALTIME_NONE;
|
||||
|
||||
struct tag_set tags = {
|
||||
.tags = (struct tag *[]){
|
||||
|
@ -237,8 +242,7 @@ wait_for_socket_create(const struct module *mod)
|
|||
LOG_DBG("%s: already exists, and is connectable", m->host);
|
||||
have_mpd_socket = true;
|
||||
} else {
|
||||
LOG_DBG("%s: already exists, but isn't connectable: %s",
|
||||
m->host, strerror(errno));
|
||||
LOG_DBG("%s: already exists, but isn't connectable: %s", m->host, strerror(errno));
|
||||
}
|
||||
|
||||
close(s);
|
||||
|
@ -249,10 +253,7 @@ wait_for_socket_create(const struct module *mod)
|
|||
|
||||
bool ret = false;
|
||||
while (!have_mpd_socket) {
|
||||
struct pollfd fds[] = {
|
||||
{.fd = mod->abort_fd, .events = POLLIN},
|
||||
{.fd = fd, .events = POLLIN}
|
||||
};
|
||||
struct pollfd fds[] = {{.fd = mod->abort_fd, .events = POLLIN}, {.fd = fd, .events = POLLIN}};
|
||||
|
||||
if (poll(fds, sizeof(fds) / sizeof(fds[0]), -1) < 0) {
|
||||
if (errno == EINTR)
|
||||
|
@ -272,7 +273,7 @@ wait_for_socket_create(const struct module *mod)
|
|||
char buf[1024];
|
||||
ssize_t len = read(fd, buf, sizeof(buf));
|
||||
|
||||
for (const char *ptr = buf; ptr < buf + len; ) {
|
||||
for (const char *ptr = buf; ptr < buf + len;) {
|
||||
const struct inotify_event *e = (const struct inotify_event *)ptr;
|
||||
LOG_DBG("inotify: CREATED: %s/%.*s", directory, e->len, e->name);
|
||||
|
||||
|
@ -282,7 +283,7 @@ wait_for_socket_create(const struct module *mod)
|
|||
break;
|
||||
}
|
||||
|
||||
ptr += sizeof(*e) + e->len;
|
||||
ptr += sizeof(*e) + e->len;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -305,8 +306,7 @@ connect_to_mpd(const struct module *mod)
|
|||
|
||||
enum mpd_error merr = mpd_connection_get_error(conn);
|
||||
if (merr != MPD_ERROR_SUCCESS) {
|
||||
LOG_WARN("failed to connect to MPD: %s",
|
||||
mpd_connection_get_error_message(conn));
|
||||
LOG_WARN("failed to connect to MPD: %s", mpd_connection_get_error_message(conn));
|
||||
mpd_connection_free(conn);
|
||||
return NULL;
|
||||
}
|
||||
|
@ -324,8 +324,7 @@ update_status(struct module *mod)
|
|||
|
||||
struct mpd_status *status = mpd_run_status(m->conn);
|
||||
if (status == NULL) {
|
||||
LOG_ERR("failed to get status: %s",
|
||||
mpd_connection_get_error_message(m->conn));
|
||||
LOG_ERR("failed to get status: %s", mpd_connection_get_error_message(m->conn));
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -347,17 +346,20 @@ update_status(struct module *mod)
|
|||
|
||||
struct mpd_song *song = mpd_run_current_song(m->conn);
|
||||
if (song == NULL && mpd_connection_get_error(m->conn) != MPD_ERROR_SUCCESS) {
|
||||
LOG_ERR("failed to get current song: %s",
|
||||
mpd_connection_get_error_message(m->conn));
|
||||
LOG_ERR("failed to get current song: %s", mpd_connection_get_error_message(m->conn));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (song == NULL) {
|
||||
mtx_lock(&mod->lock);
|
||||
free(m->album); m->album = NULL;
|
||||
free(m->artist); m->artist = NULL;
|
||||
free(m->title); m->title = NULL;
|
||||
free(m->file); m->file = NULL;
|
||||
free(m->album);
|
||||
m->album = NULL;
|
||||
free(m->artist);
|
||||
m->artist = NULL;
|
||||
free(m->title);
|
||||
m->title = NULL;
|
||||
free(m->file);
|
||||
m->file = NULL;
|
||||
mtx_unlock(&mod->lock);
|
||||
} else {
|
||||
const char *album = mpd_song_get_tag(song, MPD_TAG_ALBUM, 0);
|
||||
|
@ -401,10 +403,14 @@ run(struct module *mod)
|
|||
|
||||
/* Reset state */
|
||||
mtx_lock(&mod->lock);
|
||||
free(m->album); m->album = NULL;
|
||||
free(m->artist); m->artist = NULL;
|
||||
free(m->title); m->title = NULL;
|
||||
free(m->file); m->file = NULL;
|
||||
free(m->album);
|
||||
m->album = NULL;
|
||||
free(m->artist);
|
||||
m->artist = NULL;
|
||||
free(m->title);
|
||||
m->title = NULL;
|
||||
free(m->file);
|
||||
m->file = NULL;
|
||||
m->state = MPD_STATE_UNKNOWN;
|
||||
m->elapsed.value = m->duration = 0;
|
||||
m->elapsed.when.tv_sec = m->elapsed.when.tv_nsec = 0;
|
||||
|
@ -467,8 +473,7 @@ run(struct module *mod)
|
|||
};
|
||||
|
||||
if (!mpd_send_idle(m->conn)) {
|
||||
LOG_ERR("failed to send IDLE command: %s",
|
||||
mpd_connection_get_error_message(m->conn));
|
||||
LOG_ERR("failed to send IDLE command: %s", mpd_connection_get_error_message(m->conn));
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -492,8 +497,7 @@ run(struct module *mod)
|
|||
}
|
||||
|
||||
if (fds[1].revents & POLLIN) {
|
||||
enum mpd_idle idle __attribute__ ((unused)) =
|
||||
mpd_recv_idle(m->conn, true);
|
||||
enum mpd_idle idle __attribute__((unused)) = mpd_recv_idle(m->conn, true);
|
||||
|
||||
LOG_DBG("IDLE mask: %d", idle);
|
||||
|
||||
|
@ -565,9 +569,7 @@ refresh_in(struct module *mod, long milli_seconds)
|
|||
|
||||
/* Signal abort to thread */
|
||||
assert(m->refresh_abort_fd != -1);
|
||||
if (write(m->refresh_abort_fd, &(uint64_t){1}, sizeof(uint64_t))
|
||||
!= sizeof(uint64_t))
|
||||
{
|
||||
if (write(m->refresh_abort_fd, &(uint64_t){1}, sizeof(uint64_t)) != sizeof(uint64_t)) {
|
||||
LOG_ERRNO("failed to signal abort to refresher thread");
|
||||
return false;
|
||||
}
|
||||
|
@ -607,7 +609,7 @@ refresh_in(struct module *mod, long milli_seconds)
|
|||
}
|
||||
|
||||
/* Detach - we don't want to have to thrd_join() it */
|
||||
//thrd_detach(tid);
|
||||
// thrd_detach(tid);
|
||||
return r == 0;
|
||||
}
|
||||
|
||||
|
@ -638,10 +640,8 @@ from_conf(const struct yml_node *node, struct conf_inherit inherited)
|
|||
const struct yml_node *port = yml_get_value(node, "port");
|
||||
const struct yml_node *c = yml_get_value(node, "content");
|
||||
|
||||
return mpd_new(
|
||||
yml_value_as_string(host),
|
||||
port != NULL ? yml_value_as_int(port) : 0,
|
||||
conf_to_particle(c, inherited));
|
||||
return mpd_new(yml_value_as_string(host), port != NULL ? yml_value_as_int(port) : 0,
|
||||
conf_to_particle(c, inherited));
|
||||
}
|
||||
|
||||
static bool
|
||||
|
|
|
@ -1,34 +1,34 @@
|
|||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <assert.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <threads.h>
|
||||
#include <poll.h>
|
||||
#include <sys/timerfd.h>
|
||||
#include <threads.h>
|
||||
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <arpa/inet.h>
|
||||
#include <linux/genetlink.h>
|
||||
#include <linux/if.h>
|
||||
#include <linux/netlink.h>
|
||||
#include <linux/genetlink.h>
|
||||
#include <linux/rtnetlink.h>
|
||||
#include <linux/nl80211.h>
|
||||
#include <linux/rtnetlink.h>
|
||||
|
||||
#include <tllist.h>
|
||||
|
||||
#define LOG_MODULE "network"
|
||||
#define LOG_ENABLE_DBG 0
|
||||
#include "../log.h"
|
||||
#include "../bar/bar.h"
|
||||
#include "../config.h"
|
||||
#include "../config-verify.h"
|
||||
#include "../config.h"
|
||||
#include "../log.h"
|
||||
#include "../module.h"
|
||||
#include "../particles/dynlist.h"
|
||||
#include "../plugin.h"
|
||||
|
@ -58,7 +58,7 @@ struct iface {
|
|||
int index;
|
||||
uint8_t mac[6];
|
||||
bool carrier;
|
||||
uint8_t state; /* IFLA_OPERSTATE */
|
||||
uint8_t state; /* IFLA_OPERSTATE */
|
||||
|
||||
/* IPv4 and IPv6 addresses */
|
||||
tll(struct af_addr) addrs;
|
||||
|
@ -76,7 +76,8 @@ struct iface {
|
|||
uint64_t dl_bits;
|
||||
};
|
||||
|
||||
struct private {
|
||||
struct private
|
||||
{
|
||||
struct particle *label;
|
||||
int poll_interval;
|
||||
|
||||
|
@ -118,8 +119,7 @@ destroy(struct module *mod)
|
|||
if (m->urandom_fd >= 0)
|
||||
close(m->urandom_fd);
|
||||
|
||||
tll_foreach(m->ifaces, it)
|
||||
free_iface(it->item);
|
||||
tll_foreach(m->ifaces, it) free_iface(it->item);
|
||||
|
||||
free(m);
|
||||
module_default_destroy(mod);
|
||||
|
@ -141,35 +141,53 @@ content(struct module *mod)
|
|||
struct exposable *exposables[max(tll_length(m->ifaces), 1)];
|
||||
size_t idx = 0;
|
||||
|
||||
tll_foreach(m->ifaces, it) {
|
||||
tll_foreach(m->ifaces, it)
|
||||
{
|
||||
struct iface *iface = &it->item;
|
||||
|
||||
const char *state = NULL;
|
||||
switch (iface->state) {
|
||||
case IF_OPER_UNKNOWN: state = "unknown"; break;
|
||||
case IF_OPER_NOTPRESENT: state = "not present"; break;
|
||||
case IF_OPER_DOWN: state = "down"; break;
|
||||
case IF_OPER_LOWERLAYERDOWN: state = "lower layers down"; break;
|
||||
case IF_OPER_TESTING: state = "testing"; break;
|
||||
case IF_OPER_DORMANT: state = "dormant"; break;
|
||||
case IF_OPER_UP: state = "up"; break;
|
||||
default: state = "unknown"; break;
|
||||
case IF_OPER_UNKNOWN:
|
||||
state = "unknown";
|
||||
break;
|
||||
case IF_OPER_NOTPRESENT:
|
||||
state = "not present";
|
||||
break;
|
||||
case IF_OPER_DOWN:
|
||||
state = "down";
|
||||
break;
|
||||
case IF_OPER_LOWERLAYERDOWN:
|
||||
state = "lower layers down";
|
||||
break;
|
||||
case IF_OPER_TESTING:
|
||||
state = "testing";
|
||||
break;
|
||||
case IF_OPER_DORMANT:
|
||||
state = "dormant";
|
||||
break;
|
||||
case IF_OPER_UP:
|
||||
state = "up";
|
||||
break;
|
||||
default:
|
||||
state = "unknown";
|
||||
break;
|
||||
}
|
||||
|
||||
char mac_str[6 * 2 + 5 + 1];
|
||||
char ipv4_str[INET_ADDRSTRLEN] = {0};
|
||||
char ipv6_str[INET6_ADDRSTRLEN] = {0};
|
||||
|
||||
snprintf(mac_str, sizeof(mac_str), "%02x:%02x:%02x:%02x:%02x:%02x",
|
||||
iface->mac[0], iface->mac[1], iface->mac[2], iface->mac[3], iface->mac[4], iface->mac[5]);
|
||||
snprintf(mac_str, sizeof(mac_str), "%02x:%02x:%02x:%02x:%02x:%02x", iface->mac[0], iface->mac[1], iface->mac[2],
|
||||
iface->mac[3], iface->mac[4], iface->mac[5]);
|
||||
|
||||
/* TODO: this exposes the *last* added address of each kind. Can
|
||||
* we expose all in some way? */
|
||||
tll_foreach(iface->addrs, it) {
|
||||
tll_foreach(iface->addrs, it)
|
||||
{
|
||||
if (it->item.family == AF_INET)
|
||||
inet_ntop(AF_INET, &it->item.addr.ipv4, ipv4_str, sizeof(ipv4_str));
|
||||
else if (it->item.family == AF_INET6)
|
||||
if(!IN6_IS_ADDR_LINKLOCAL(&it->item.addr.ipv6))
|
||||
if (!IN6_IS_ADDR_LINKLOCAL(&it->item.addr.ipv6))
|
||||
inet_ntop(AF_INET6, &it->item.addr.ipv6, ipv6_str, sizeof(ipv6_str));
|
||||
}
|
||||
|
||||
|
@ -208,8 +226,7 @@ content(struct module *mod)
|
|||
|
||||
mtx_unlock(&mod->lock);
|
||||
|
||||
return dynlist_exposable_new(
|
||||
exposables, idx, m->left_spacing, m->right_spacing);
|
||||
return dynlist_exposable_new(exposables, idx, m->left_spacing, m->right_spacing);
|
||||
}
|
||||
|
||||
/* Returns a value suitable for nl_pid/nlmsg_pid */
|
||||
|
@ -254,8 +271,7 @@ netlink_connect_genl(void)
|
|||
}
|
||||
|
||||
const struct sockaddr_nl addr = {
|
||||
.nl_family = AF_NETLINK,
|
||||
.nl_pid = nl_pid_value(),
|
||||
.nl_family = AF_NETLINK, .nl_pid = nl_pid_value(),
|
||||
/* no multicast notifications by default, will be added later */
|
||||
};
|
||||
|
||||
|
@ -271,10 +287,8 @@ netlink_connect_genl(void)
|
|||
static bool
|
||||
send_nlmsg(int sock, const void *nlmsg, size_t len)
|
||||
{
|
||||
int r = sendto(
|
||||
sock, nlmsg, len, 0,
|
||||
(struct sockaddr *)&(struct sockaddr_nl){.nl_family = AF_NETLINK},
|
||||
sizeof(struct sockaddr_nl));
|
||||
int r = sendto(sock, nlmsg, len, 0, (struct sockaddr *)&(struct sockaddr_nl){.nl_family = AF_NETLINK},
|
||||
sizeof(struct sockaddr_nl));
|
||||
|
||||
return r == len;
|
||||
}
|
||||
|
@ -300,8 +314,7 @@ send_rt_request(struct private *m, int request)
|
|||
};
|
||||
|
||||
if (!send_nlmsg(m->rt_sock, &req, req.hdr.nlmsg_len)) {
|
||||
LOG_ERRNO("failed to send netlink RT request (%d)",
|
||||
request);
|
||||
LOG_ERRNO("failed to send netlink RT request (%d)", request);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -312,8 +325,7 @@ static bool
|
|||
send_rt_getstats_request(struct private *m, struct iface *iface)
|
||||
{
|
||||
if (iface->get_stats_seq_nr > 0) {
|
||||
LOG_DBG(
|
||||
"%s: RT get-stats request already in progress", iface->name);
|
||||
LOG_DBG("%s: RT get-stats request already in progress", iface->name);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -345,8 +357,7 @@ send_rt_getstats_request(struct private *m, struct iface *iface)
|
|||
};
|
||||
|
||||
if (!send_nlmsg(m->rt_sock, &req, req.hdr.nlmsg_len)) {
|
||||
LOG_ERRNO("%s: failed to send netlink RT getstats request (%d)",
|
||||
iface->name, RTM_GETSTATS);
|
||||
LOG_ERRNO("%s: failed to send netlink RT getstats request (%d)", iface->name, RTM_GETSTATS);
|
||||
return false;
|
||||
}
|
||||
iface->get_stats_seq_nr = seq;
|
||||
|
@ -391,10 +402,8 @@ send_ctrl_get_family_request(struct private *m)
|
|||
},
|
||||
};
|
||||
|
||||
_Static_assert(
|
||||
sizeof(req.msg.family_name_attr) ==
|
||||
NLA_HDRLEN + NLA_ALIGN(sizeof(req.msg.family_name_attr.data)),
|
||||
"");
|
||||
_Static_assert(sizeof(req.msg.family_name_attr) == NLA_HDRLEN + NLA_ALIGN(sizeof(req.msg.family_name_attr.data)),
|
||||
"");
|
||||
|
||||
if (!send_nlmsg(m->genl_sock, &req, req.hdr.nlmsg_len)) {
|
||||
LOG_ERRNO("failed to send netlink ctrl-get-family request");
|
||||
|
@ -538,15 +547,15 @@ send_nl80211_get_scan(struct private *m)
|
|||
}
|
||||
|
||||
static void
|
||||
handle_link(struct module *mod, uint16_t type,
|
||||
const struct ifinfomsg *msg, size_t len)
|
||||
handle_link(struct module *mod, uint16_t type, const struct ifinfomsg *msg, size_t len)
|
||||
{
|
||||
assert(type == RTM_NEWLINK || type == RTM_DELLINK);
|
||||
|
||||
struct private *m = mod->private;
|
||||
|
||||
if (type == RTM_DELLINK) {
|
||||
tll_foreach(m->ifaces, it) {
|
||||
tll_foreach(m->ifaces, it)
|
||||
{
|
||||
if (msg->ifi_index != it->item.index)
|
||||
continue;
|
||||
mtx_lock(&mod->lock);
|
||||
|
@ -560,7 +569,8 @@ handle_link(struct module *mod, uint16_t type,
|
|||
}
|
||||
|
||||
struct iface *iface = NULL;
|
||||
tll_foreach(m->ifaces, it) {
|
||||
tll_foreach(m->ifaces, it)
|
||||
{
|
||||
if (msg->ifi_index != it->item.index)
|
||||
continue;
|
||||
iface = &it->item;
|
||||
|
@ -568,21 +578,17 @@ handle_link(struct module *mod, uint16_t type,
|
|||
}
|
||||
|
||||
if (iface == NULL) {
|
||||
mtx_lock(&mod->lock);
|
||||
tll_push_back(m->ifaces,
|
||||
((struct iface){
|
||||
.index = msg->ifi_index,
|
||||
.state = IF_OPER_DOWN,
|
||||
.addrs = tll_init(),
|
||||
}));
|
||||
mtx_unlock(&mod->lock);
|
||||
iface = &tll_back(m->ifaces);
|
||||
mtx_lock(&mod->lock);
|
||||
tll_push_back(m->ifaces, ((struct iface){
|
||||
.index = msg->ifi_index,
|
||||
.state = IF_OPER_DOWN,
|
||||
.addrs = tll_init(),
|
||||
}));
|
||||
mtx_unlock(&mod->lock);
|
||||
iface = &tll_back(m->ifaces);
|
||||
}
|
||||
|
||||
for (const struct rtattr *attr = IFLA_RTA(msg);
|
||||
RTA_OK(attr, len);
|
||||
attr = RTA_NEXT(attr, len))
|
||||
{
|
||||
for (const struct rtattr *attr = IFLA_RTA(msg); RTA_OK(attr, len); attr = RTA_NEXT(attr, len)) {
|
||||
switch (attr->rta_type) {
|
||||
case IFLA_IFNAME:
|
||||
mtx_lock(&mod->lock);
|
||||
|
@ -623,9 +629,8 @@ handle_link(struct module *mod, uint16_t type,
|
|||
if (memcmp(iface->mac, mac, sizeof(iface->mac)) == 0)
|
||||
break;
|
||||
|
||||
LOG_DBG("%s: IFLA_ADDRESS: %02x:%02x:%02x:%02x:%02x:%02x",
|
||||
iface->name,
|
||||
mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
|
||||
LOG_DBG("%s: IFLA_ADDRESS: %02x:%02x:%02x:%02x:%02x:%02x", iface->name, mac[0], mac[1], mac[2], mac[3],
|
||||
mac[4], mac[5]);
|
||||
|
||||
mtx_lock(&mod->lock);
|
||||
memcpy(iface->mac, mac, sizeof(iface->mac));
|
||||
|
@ -645,8 +650,7 @@ handle_link(struct module *mod, uint16_t type,
|
|||
}
|
||||
|
||||
static void
|
||||
handle_address(struct module *mod, uint16_t type,
|
||||
const struct ifaddrmsg *msg, size_t len)
|
||||
handle_address(struct module *mod, uint16_t type, const struct ifaddrmsg *msg, size_t len)
|
||||
{
|
||||
assert(type == RTM_NEWADDR || type == RTM_DELADDR);
|
||||
|
||||
|
@ -656,7 +660,8 @@ handle_address(struct module *mod, uint16_t type,
|
|||
|
||||
struct iface *iface = NULL;
|
||||
|
||||
tll_foreach(m->ifaces, it) {
|
||||
tll_foreach(m->ifaces, it)
|
||||
{
|
||||
if (msg->ifa_index != it->item.index)
|
||||
continue;
|
||||
iface = &it->item;
|
||||
|
@ -668,10 +673,7 @@ handle_address(struct module *mod, uint16_t type,
|
|||
return;
|
||||
}
|
||||
|
||||
for (const struct rtattr *attr = IFA_RTA(msg);
|
||||
RTA_OK(attr, len);
|
||||
attr = RTA_NEXT(attr, len))
|
||||
{
|
||||
for (const struct rtattr *attr = IFA_RTA(msg); RTA_OK(attr, len); attr = RTA_NEXT(attr, len)) {
|
||||
switch (attr->rta_type) {
|
||||
case IFA_ADDRESS: {
|
||||
const void *raw_addr = RTA_DATA(attr);
|
||||
|
@ -681,14 +683,14 @@ handle_address(struct module *mod, uint16_t type,
|
|||
char s[INET6_ADDRSTRLEN];
|
||||
inet_ntop(msg->ifa_family, raw_addr, s, sizeof(s));
|
||||
#endif
|
||||
LOG_DBG("%s: IFA_ADDRESS (%s): %s", iface->name,
|
||||
type == RTM_NEWADDR ? "add" : "del", s);
|
||||
LOG_DBG("%s: IFA_ADDRESS (%s): %s", iface->name, type == RTM_NEWADDR ? "add" : "del", s);
|
||||
|
||||
mtx_lock(&mod->lock);
|
||||
|
||||
if (type == RTM_DELADDR) {
|
||||
/* Find address in our list and remove it */
|
||||
tll_foreach(iface->addrs, it) {
|
||||
tll_foreach(iface->addrs, it)
|
||||
{
|
||||
if (it->item.family != msg->ifa_family)
|
||||
continue;
|
||||
|
||||
|
@ -719,19 +721,18 @@ handle_address(struct module *mod, uint16_t type,
|
|||
|
||||
static bool
|
||||
foreach_nlattr(struct module *mod, struct iface *iface, const struct genlmsghdr *genl, size_t len,
|
||||
bool (*cb)(struct module *mod, struct iface *iface, uint16_t type, bool nested,
|
||||
const void *payload, size_t len, void *ctx),
|
||||
bool (*cb)(struct module *mod, struct iface *iface, uint16_t type, bool nested, const void *payload,
|
||||
size_t len, void *ctx),
|
||||
void *ctx)
|
||||
{
|
||||
const uint8_t *raw = (const uint8_t *)genl + GENL_HDRLEN;
|
||||
const uint8_t *end = (const uint8_t *)genl + len;
|
||||
|
||||
for (const struct nlattr *attr = (const struct nlattr *)raw;
|
||||
raw < end;
|
||||
raw += NLA_ALIGN(attr->nla_len), attr = (const struct nlattr *)raw)
|
||||
{
|
||||
for (const struct nlattr *attr = (const struct nlattr *)raw; raw < end;
|
||||
raw += NLA_ALIGN(attr->nla_len), attr = (const struct nlattr *)raw) {
|
||||
uint16_t type = attr->nla_type & NLA_TYPE_MASK;
|
||||
bool nested = (attr->nla_type & NLA_F_NESTED) != 0;;
|
||||
bool nested = (attr->nla_type & NLA_F_NESTED) != 0;
|
||||
;
|
||||
const void *payload = raw + NLA_HDRLEN;
|
||||
|
||||
if (!cb(mod, iface, type, nested, payload, attr->nla_len - NLA_HDRLEN, ctx))
|
||||
|
@ -743,18 +744,15 @@ foreach_nlattr(struct module *mod, struct iface *iface, const struct genlmsghdr
|
|||
|
||||
static bool
|
||||
foreach_nlattr_nested(struct module *mod, struct iface *iface, const void *parent_payload, size_t len,
|
||||
bool (*cb)(struct module *mod, struct iface *iface, uint16_t type,
|
||||
bool nested, const void *payload, size_t len,
|
||||
void *ctx),
|
||||
bool (*cb)(struct module *mod, struct iface *iface, uint16_t type, bool nested,
|
||||
const void *payload, size_t len, void *ctx),
|
||||
void *ctx)
|
||||
{
|
||||
const uint8_t *raw = parent_payload;
|
||||
const uint8_t *end = parent_payload + len;
|
||||
|
||||
for (const struct nlattr *attr = (const struct nlattr *)raw;
|
||||
raw < end;
|
||||
raw += NLA_ALIGN(attr->nla_len), attr = (const struct nlattr *)raw)
|
||||
{
|
||||
for (const struct nlattr *attr = (const struct nlattr *)raw; raw < end;
|
||||
raw += NLA_ALIGN(attr->nla_len), attr = (const struct nlattr *)raw) {
|
||||
uint16_t type = attr->nla_type & NLA_TYPE_MASK;
|
||||
bool nested = (attr->nla_type & NLA_F_NESTED) != 0;
|
||||
const void *payload = raw + NLA_HDRLEN;
|
||||
|
@ -772,8 +770,8 @@ struct mcast_group {
|
|||
};
|
||||
|
||||
static bool
|
||||
parse_mcast_group(struct module *mod, struct iface *iface, uint16_t type, bool nested,
|
||||
const void *payload, size_t len, void *_ctx)
|
||||
parse_mcast_group(struct module *mod, struct iface *iface, uint16_t type, bool nested, const void *payload, size_t len,
|
||||
void *_ctx)
|
||||
{
|
||||
struct mcast_group *ctx = _ctx;
|
||||
|
||||
|
@ -790,7 +788,8 @@ parse_mcast_group(struct module *mod, struct iface *iface, uint16_t type, bool n
|
|||
|
||||
default:
|
||||
LOG_WARN("unrecognized GENL MCAST GRP attribute: "
|
||||
"type=%hu, nested=%d, len=%zu", type, nested, len);
|
||||
"type=%hu, nested=%d, len=%zu",
|
||||
type, nested, len);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -798,8 +797,8 @@ parse_mcast_group(struct module *mod, struct iface *iface, uint16_t type, bool n
|
|||
}
|
||||
|
||||
static bool
|
||||
parse_mcast_groups(struct module *mod, struct iface *iface, uint16_t type, bool nested,
|
||||
const void *payload, size_t len, void *_ctx)
|
||||
parse_mcast_groups(struct module *mod, struct iface *iface, uint16_t type, bool nested, const void *payload, size_t len,
|
||||
void *_ctx)
|
||||
{
|
||||
struct private *m = mod->private;
|
||||
|
||||
|
@ -814,9 +813,7 @@ parse_mcast_groups(struct module *mod, struct iface *iface, uint16_t type, bool
|
|||
* CONNECT/DISCONNECT events.
|
||||
*/
|
||||
|
||||
int r = setsockopt(
|
||||
m->genl_sock, SOL_NETLINK, NETLINK_ADD_MEMBERSHIP,
|
||||
&group.id, sizeof(int));
|
||||
int r = setsockopt(m->genl_sock, SOL_NETLINK, NETLINK_ADD_MEMBERSHIP, &group.id, sizeof(int));
|
||||
|
||||
if (r < 0)
|
||||
LOG_ERRNO("failed to joint the nl80211 MLME mcast group");
|
||||
|
@ -826,8 +823,8 @@ parse_mcast_groups(struct module *mod, struct iface *iface, uint16_t type, bool
|
|||
}
|
||||
|
||||
static bool
|
||||
handle_genl_ctrl(struct module *mod, struct iface *iface, uint16_t type, bool nested,
|
||||
const void *payload, size_t len, void *_ctx)
|
||||
handle_genl_ctrl(struct module *mod, struct iface *iface, uint16_t type, bool nested, const void *payload, size_t len,
|
||||
void *_ctx)
|
||||
{
|
||||
struct private *m = mod->private;
|
||||
|
||||
|
@ -839,7 +836,7 @@ handle_genl_ctrl(struct module *mod, struct iface *iface, uint16_t type, bool ne
|
|||
}
|
||||
|
||||
case CTRL_ATTR_FAMILY_NAME:
|
||||
//LOG_INFO("NAME: %.*s (%zu bytes)", (int)len, (const char *)payload, len);
|
||||
// LOG_INFO("NAME: %.*s (%zu bytes)", (int)len, (const char *)payload, len);
|
||||
break;
|
||||
|
||||
case CTRL_ATTR_MCAST_GROUPS:
|
||||
|
@ -848,17 +845,17 @@ handle_genl_ctrl(struct module *mod, struct iface *iface, uint16_t type, bool ne
|
|||
|
||||
default:
|
||||
LOG_DBG("unrecognized GENL CTRL attribute: "
|
||||
"type=%hu, nested=%d, len=%zu", type, nested, len);
|
||||
"type=%hu, nested=%d, len=%zu",
|
||||
type, nested, len);
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
static bool
|
||||
find_nl80211_iface(struct module *mod, struct iface *_iface, uint16_t type, bool nested,
|
||||
const void *payload, size_t len, void *ctx)
|
||||
find_nl80211_iface(struct module *mod, struct iface *_iface, uint16_t type, bool nested, const void *payload,
|
||||
size_t len, void *ctx)
|
||||
{
|
||||
struct private *m = mod->private;
|
||||
struct iface **iface = ctx;
|
||||
|
@ -868,7 +865,8 @@ find_nl80211_iface(struct module *mod, struct iface *_iface, uint16_t type, bool
|
|||
if (*iface != NULL)
|
||||
if (*(uint32_t *)payload == (*iface)->index)
|
||||
return false;
|
||||
tll_foreach(m->ifaces, it) {
|
||||
tll_foreach(m->ifaces, it)
|
||||
{
|
||||
if (*(uint32_t *)payload != it->item.index)
|
||||
continue;
|
||||
*iface = &it->item;
|
||||
|
@ -882,8 +880,8 @@ find_nl80211_iface(struct module *mod, struct iface *_iface, uint16_t type, bool
|
|||
}
|
||||
|
||||
static bool
|
||||
handle_nl80211_new_interface(struct module *mod, struct iface *iface, uint16_t type, bool nested,
|
||||
const void *payload, size_t len, void *_ctx)
|
||||
handle_nl80211_new_interface(struct module *mod, struct iface *iface, uint16_t type, bool nested, const void *payload,
|
||||
size_t len, void *_ctx)
|
||||
{
|
||||
switch (type) {
|
||||
case NL80211_ATTR_IFINDEX:
|
||||
|
@ -907,7 +905,8 @@ handle_nl80211_new_interface(struct module *mod, struct iface *iface, uint16_t t
|
|||
|
||||
default:
|
||||
LOG_DBG("%s: unrecognized nl80211 attribute: "
|
||||
"type=%hu, nested=%d, len=%zu", iface->name, type, nested, len);
|
||||
"type=%hu, nested=%d, len=%zu",
|
||||
iface->name, type, nested, len);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -919,8 +918,8 @@ struct rate_info_ctx {
|
|||
};
|
||||
|
||||
static bool
|
||||
handle_nl80211_rate_info(struct module *mod, struct iface *iface, uint16_t type, bool nested,
|
||||
const void *payload, size_t len, void *_ctx)
|
||||
handle_nl80211_rate_info(struct module *mod, struct iface *iface, uint16_t type, bool nested, const void *payload,
|
||||
size_t len, void *_ctx)
|
||||
{
|
||||
struct rate_info_ctx *ctx = _ctx;
|
||||
|
||||
|
@ -942,7 +941,8 @@ handle_nl80211_rate_info(struct module *mod, struct iface *iface, uint16_t type,
|
|||
|
||||
default:
|
||||
LOG_DBG("%s: unrecognized nl80211 rate info attribute: "
|
||||
"type=%hu, nested=%d, len=%zu", iface->name, type, nested, len);
|
||||
"type=%hu, nested=%d, len=%zu",
|
||||
iface->name, type, nested, len);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -954,8 +954,8 @@ struct station_info_ctx {
|
|||
};
|
||||
|
||||
static bool
|
||||
handle_nl80211_station_info(struct module *mod, struct iface *iface, uint16_t type, bool nested,
|
||||
const void *payload, size_t len, void *_ctx)
|
||||
handle_nl80211_station_info(struct module *mod, struct iface *iface, uint16_t type, bool nested, const void *payload,
|
||||
size_t len, void *_ctx)
|
||||
{
|
||||
struct station_info_ctx *ctx = _ctx;
|
||||
|
||||
|
@ -974,8 +974,7 @@ handle_nl80211_station_info(struct module *mod, struct iface *iface, uint16_t ty
|
|||
|
||||
case NL80211_STA_INFO_TX_BITRATE: {
|
||||
struct rate_info_ctx rctx = {0};
|
||||
foreach_nlattr_nested(
|
||||
mod, iface, payload, len, &handle_nl80211_rate_info, &rctx);
|
||||
foreach_nlattr_nested(mod, iface, payload, len, &handle_nl80211_rate_info, &rctx);
|
||||
|
||||
LOG_DBG("TX bitrate: %.1f Mbit/s", rctx.bitrate / 1000. / 1000.);
|
||||
mtx_lock(&mod->lock);
|
||||
|
@ -987,8 +986,7 @@ handle_nl80211_station_info(struct module *mod, struct iface *iface, uint16_t ty
|
|||
|
||||
case NL80211_STA_INFO_RX_BITRATE: {
|
||||
struct rate_info_ctx rctx = {0};
|
||||
foreach_nlattr_nested(
|
||||
mod, iface, payload, len, &handle_nl80211_rate_info, &rctx);
|
||||
foreach_nlattr_nested(mod, iface, payload, len, &handle_nl80211_rate_info, &rctx);
|
||||
|
||||
LOG_DBG("RX bitrate: %.1f Mbit/s", rctx.bitrate / 1000. / 1000.);
|
||||
mtx_lock(&mod->lock);
|
||||
|
@ -1000,7 +998,8 @@ handle_nl80211_station_info(struct module *mod, struct iface *iface, uint16_t ty
|
|||
|
||||
default:
|
||||
LOG_DBG("%s: unrecognized nl80211 station info attribute: "
|
||||
"type=%hu, nested=%d, len=%zu", iface->name, type, nested, len);
|
||||
"type=%hu, nested=%d, len=%zu",
|
||||
iface->name, type, nested, len);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -1008,8 +1007,8 @@ handle_nl80211_station_info(struct module *mod, struct iface *iface, uint16_t ty
|
|||
}
|
||||
|
||||
static bool
|
||||
handle_nl80211_new_station(struct module *mod, struct iface *iface, uint16_t type, bool nested,
|
||||
const void *payload, size_t len, void *_ctx)
|
||||
handle_nl80211_new_station(struct module *mod, struct iface *iface, uint16_t type, bool nested, const void *payload,
|
||||
size_t len, void *_ctx)
|
||||
{
|
||||
switch (type) {
|
||||
case NL80211_ATTR_IFINDEX:
|
||||
|
@ -1017,8 +1016,7 @@ handle_nl80211_new_station(struct module *mod, struct iface *iface, uint16_t typ
|
|||
|
||||
case NL80211_ATTR_STA_INFO: {
|
||||
struct station_info_ctx ctx = {0};
|
||||
foreach_nlattr_nested(
|
||||
mod, iface, payload, len, &handle_nl80211_station_info, &ctx);
|
||||
foreach_nlattr_nested(mod, iface, payload, len, &handle_nl80211_station_info, &ctx);
|
||||
|
||||
if (ctx.update_bar)
|
||||
mod->bar->refresh(mod->bar);
|
||||
|
@ -1027,7 +1025,8 @@ handle_nl80211_new_station(struct module *mod, struct iface *iface, uint16_t typ
|
|||
|
||||
default:
|
||||
LOG_DBG("%s: unrecognized nl80211 attribute: "
|
||||
"type=%hu, nested=%d, len=%zu", iface->name, type, nested, len);
|
||||
"type=%hu, nested=%d, len=%zu",
|
||||
iface->name, type, nested, len);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -1041,7 +1040,7 @@ handle_ies(struct module *mod, struct iface *iface, const void *_ies, size_t len
|
|||
|
||||
while (len >= 2 && len - 2 >= ies[1]) {
|
||||
switch (ies[0]) {
|
||||
case 0: { /* SSID */
|
||||
case 0: { /* SSID */
|
||||
const char *ssid = (const char *)&ies[2];
|
||||
const size_t ssid_len = ies[1];
|
||||
|
||||
|
@ -1072,8 +1071,8 @@ struct scan_results_context {
|
|||
};
|
||||
|
||||
static bool
|
||||
handle_nl80211_bss(struct module *mod, struct iface *iface, uint16_t type, bool nested,
|
||||
const void *payload, size_t len, void *_ctx)
|
||||
handle_nl80211_bss(struct module *mod, struct iface *iface, uint16_t type, bool nested, const void *payload, size_t len,
|
||||
void *_ctx)
|
||||
{
|
||||
struct scan_results_context *ctx = _ctx;
|
||||
|
||||
|
@ -1113,8 +1112,8 @@ handle_nl80211_bss(struct module *mod, struct iface *iface, uint16_t type, bool
|
|||
}
|
||||
|
||||
static bool
|
||||
handle_nl80211_scan_results(struct module *mod, struct iface *iface, uint16_t type, bool nested,
|
||||
const void *payload, size_t len, void *_ctx)
|
||||
handle_nl80211_scan_results(struct module *mod, struct iface *iface, uint16_t type, bool nested, const void *payload,
|
||||
size_t len, void *_ctx)
|
||||
{
|
||||
struct scan_results_context ctx = {0};
|
||||
|
||||
|
@ -1172,7 +1171,8 @@ handle_stats(struct module *mod, uint32_t seq, struct rt_stats_msg *msg)
|
|||
|
||||
struct iface *iface = NULL;
|
||||
|
||||
tll_foreach(m->ifaces, it) {
|
||||
tll_foreach(m->ifaces, it)
|
||||
{
|
||||
if (seq != it->item.get_stats_seq_nr)
|
||||
continue;
|
||||
iface = &it->item;
|
||||
|
@ -1241,16 +1241,14 @@ parse_rt_reply(struct module *mod, const struct nlmsghdr *hdr, size_t len)
|
|||
break;
|
||||
}
|
||||
|
||||
case NLMSG_ERROR:{
|
||||
case NLMSG_ERROR: {
|
||||
const struct nlmsgerr *err = NLMSG_DATA(hdr);
|
||||
LOG_ERRNO_P(-err->error, "netlink RT reply");
|
||||
return false;
|
||||
}
|
||||
|
||||
default:
|
||||
LOG_WARN(
|
||||
"unrecognized netlink message type: 0x%x",
|
||||
hdr->nlmsg_type);
|
||||
LOG_WARN("unrecognized netlink message type: 0x%x", hdr->nlmsg_type);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -1288,8 +1286,7 @@ parse_genl_reply(struct module *mod, const struct nlmsghdr *hdr, size_t len)
|
|||
/* Current request is now considered complete */
|
||||
m->nl80211.get_scan_seq_nr = 0;
|
||||
|
||||
tll_foreach(m->ifaces, it)
|
||||
send_nl80211_get_station(m, &it->item);
|
||||
tll_foreach(m->ifaces, it) send_nl80211_get_station(m, &it->item);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1300,11 +1297,10 @@ parse_genl_reply(struct module *mod, const struct nlmsghdr *hdr, size_t len)
|
|||
switch (genl->cmd) {
|
||||
case NL80211_CMD_NEW_INTERFACE:
|
||||
if (foreach_nlattr(mod, NULL, genl, msg_size, &find_nl80211_iface, &iface))
|
||||
continue;
|
||||
continue;
|
||||
|
||||
LOG_DBG("%s: got interface information", iface->name);
|
||||
foreach_nlattr(
|
||||
mod, iface, genl, msg_size, &handle_nl80211_new_interface, NULL);
|
||||
foreach_nlattr(mod, iface, genl, msg_size, &handle_nl80211_new_interface, NULL);
|
||||
break;
|
||||
|
||||
case NL80211_CMD_CONNECT:
|
||||
|
@ -1324,7 +1320,7 @@ parse_genl_reply(struct module *mod, const struct nlmsghdr *hdr, size_t len)
|
|||
|
||||
case NL80211_CMD_DISCONNECT:
|
||||
if (foreach_nlattr(mod, NULL, genl, msg_size, &find_nl80211_iface, &iface))
|
||||
continue;
|
||||
continue;
|
||||
|
||||
LOG_DBG("%s: disconnected, resetting SSID etc", iface->name);
|
||||
|
||||
|
@ -1338,20 +1334,18 @@ parse_genl_reply(struct module *mod, const struct nlmsghdr *hdr, size_t len)
|
|||
|
||||
case NL80211_CMD_NEW_STATION:
|
||||
if (foreach_nlattr(mod, NULL, genl, msg_size, &find_nl80211_iface, &iface))
|
||||
continue;
|
||||
continue;
|
||||
|
||||
LOG_DBG("%s: got station information", iface->name);
|
||||
foreach_nlattr(mod, iface, genl, msg_size, &handle_nl80211_new_station, NULL);
|
||||
|
||||
LOG_DBG("%s: signal: %d dBm, RX=%u Mbit/s, TX=%u Mbit/s",
|
||||
iface->name, iface->signal_strength_dbm,
|
||||
iface->rx_bitrate / 1000 / 1000,
|
||||
iface->tx_bitrate / 1000 / 1000);
|
||||
LOG_DBG("%s: signal: %d dBm, RX=%u Mbit/s, TX=%u Mbit/s", iface->name, iface->signal_strength_dbm,
|
||||
iface->rx_bitrate / 1000 / 1000, iface->tx_bitrate / 1000 / 1000);
|
||||
break;
|
||||
|
||||
case NL80211_CMD_NEW_SCAN_RESULTS:
|
||||
if (foreach_nlattr(mod, NULL, genl, msg_size, &find_nl80211_iface, &iface))
|
||||
continue;
|
||||
continue;
|
||||
|
||||
LOG_DBG("%s: got scan results", iface->name);
|
||||
foreach_nlattr(mod, iface, genl, msg_size, &handle_nl80211_scan_results, NULL);
|
||||
|
@ -1372,15 +1366,12 @@ parse_genl_reply(struct module *mod, const struct nlmsghdr *hdr, size_t len)
|
|||
else if (nl_errno == ENOENT)
|
||||
; /* iface down? */
|
||||
else {
|
||||
LOG_ERRNO_P(nl_errno, "nl80211 reply (seq-nr: %u)",
|
||||
hdr->nlmsg_seq);
|
||||
LOG_ERRNO_P(nl_errno, "nl80211 reply (seq-nr: %u)", hdr->nlmsg_seq);
|
||||
}
|
||||
}
|
||||
|
||||
else {
|
||||
LOG_WARN(
|
||||
"unrecognized netlink message type: 0x%x",
|
||||
hdr->nlmsg_type);
|
||||
LOG_WARN("unrecognized netlink message type: 0x%x", hdr->nlmsg_type);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -1422,9 +1413,7 @@ run(struct module *mod)
|
|||
if (m->rt_sock < 0 || m->genl_sock < 0)
|
||||
goto out;
|
||||
|
||||
if (!send_rt_request(m, RTM_GETLINK) ||
|
||||
!send_ctrl_get_family_request(m))
|
||||
{
|
||||
if (!send_rt_request(m, RTM_GETLINK) || !send_ctrl_get_family_request(m)) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
@ -1442,9 +1431,7 @@ run(struct module *mod)
|
|||
if (fds[0].revents & (POLLIN | POLLHUP))
|
||||
break;
|
||||
|
||||
if ((fds[1].revents & POLLHUP) ||
|
||||
(fds[2].revents & POLLHUP))
|
||||
{
|
||||
if ((fds[1].revents & POLLHUP) || (fds[2].revents & POLLHUP)) {
|
||||
LOG_ERR("disconnected from netlink socket");
|
||||
break;
|
||||
}
|
||||
|
@ -1493,7 +1480,8 @@ run(struct module *mod)
|
|||
break;
|
||||
}
|
||||
|
||||
tll_foreach(m->ifaces, it) {
|
||||
tll_foreach(m->ifaces, it)
|
||||
{
|
||||
send_nl80211_get_station(m, &it->item);
|
||||
send_rt_getstats_request(m, &it->item);
|
||||
};
|
||||
|
@ -1502,7 +1490,7 @@ run(struct module *mod)
|
|||
|
||||
ret = 0;
|
||||
|
||||
out:
|
||||
out:
|
||||
if (m->rt_sock >= 0)
|
||||
close(m->rt_sock);
|
||||
if (m->genl_sock >= 0)
|
||||
|
@ -1552,14 +1540,12 @@ from_conf(const struct yml_node *node, struct conf_inherit inherited)
|
|||
const struct yml_node *left_spacing = yml_get_value(node, "left-spacing");
|
||||
const struct yml_node *right_spacing = yml_get_value(node, "right-spacing");
|
||||
|
||||
int left = spacing != NULL ? yml_value_as_int(spacing) :
|
||||
left_spacing != NULL ? yml_value_as_int(left_spacing) : 0;
|
||||
int right = spacing != NULL ? yml_value_as_int(spacing) :
|
||||
right_spacing != NULL ? yml_value_as_int(right_spacing) : 0;
|
||||
int left = spacing != NULL ? yml_value_as_int(spacing) : left_spacing != NULL ? yml_value_as_int(left_spacing) : 0;
|
||||
int right = spacing != NULL ? yml_value_as_int(spacing)
|
||||
: right_spacing != NULL ? yml_value_as_int(right_spacing)
|
||||
: 0;
|
||||
|
||||
return network_new(
|
||||
conf_to_particle(content, inherited),
|
||||
poll != NULL ? yml_value_as_int(poll) : 0, left, right);
|
||||
return network_new(conf_to_particle(content, inherited), poll != NULL ? yml_value_as_int(poll) : 0, left, right);
|
||||
}
|
||||
|
||||
static bool
|
||||
|
@ -1570,8 +1556,7 @@ conf_verify_poll_interval(keychain_t *chain, const struct yml_node *node)
|
|||
|
||||
int interval = yml_value_as_int(node);
|
||||
if (interval > 0 && interval < min_poll_interval) {
|
||||
LOG_ERR("%s: interval value cannot be less than %ldms",
|
||||
conf_err_prefix(chain, node), min_poll_interval);
|
||||
LOG_ERR("%s: interval value cannot be less than %ldms", conf_err_prefix(chain, node), min_poll_interval);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -867,9 +867,7 @@ content(struct module *module)
|
|||
|
||||
/* sink */
|
||||
output_informations
|
||||
= (private->data->target_sink == NULL
|
||||
? &output_informations_null
|
||||
: &private->sink_informations);
|
||||
= (private->data->target_sink == NULL ? &output_informations_null : &private->sink_informations);
|
||||
|
||||
struct tag_set sink_tag_set = (struct tag_set){
|
||||
.tags = (struct tag *[]){
|
||||
|
@ -888,9 +886,7 @@ content(struct module *module)
|
|||
|
||||
/* source */
|
||||
output_informations
|
||||
= (private->data->target_source == NULL
|
||||
? &output_informations_null
|
||||
: &private->source_informations);
|
||||
= (private->data->target_source == NULL ? &output_informations_null : &private->source_informations);
|
||||
|
||||
struct tag_set source_tag_set = (struct tag_set){
|
||||
.tags = (struct tag *[]){
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <unistd.h>
|
||||
#include <sys/timerfd.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <pulse/pulseaudio.h>
|
||||
|
||||
|
@ -17,7 +17,8 @@
|
|||
#include "../log.h"
|
||||
#include "../plugin.h"
|
||||
|
||||
struct private {
|
||||
struct private
|
||||
{
|
||||
char *sink_name;
|
||||
char *source_name;
|
||||
struct particle *label;
|
||||
|
@ -69,9 +70,9 @@ content(struct module *mod)
|
|||
|
||||
mtx_lock(&mod->lock);
|
||||
|
||||
pa_volume_t sink_volume_max = pa_cvolume_max(&priv->sink_volume);
|
||||
pa_volume_t sink_volume_max = pa_cvolume_max(&priv->sink_volume);
|
||||
pa_volume_t source_volume_max = pa_cvolume_max(&priv->source_volume);
|
||||
int sink_percent = round(100.0 * sink_volume_max / PA_VOLUME_NORM);
|
||||
int sink_percent = round(100.0 * sink_volume_max / PA_VOLUME_NORM);
|
||||
int source_percent = round(100.0 * source_volume_max / PA_VOLUME_NORM);
|
||||
|
||||
struct tag_set tags = {
|
||||
|
@ -106,11 +107,7 @@ context_error(pa_context *c)
|
|||
}
|
||||
|
||||
static void
|
||||
abort_event_cb(pa_mainloop_api *api,
|
||||
pa_io_event *event,
|
||||
int fd,
|
||||
pa_io_event_flags_t flags,
|
||||
void *userdata)
|
||||
abort_event_cb(pa_mainloop_api *api, pa_io_event *event, int fd, pa_io_event_flags_t flags, void *userdata)
|
||||
{
|
||||
struct module *mod = userdata;
|
||||
struct private *priv = mod->private;
|
||||
|
@ -119,11 +116,7 @@ abort_event_cb(pa_mainloop_api *api,
|
|||
}
|
||||
|
||||
static void
|
||||
refresh_timer_cb(pa_mainloop_api *api,
|
||||
pa_io_event *event,
|
||||
int fd,
|
||||
pa_io_event_flags_t flags,
|
||||
void *userdata)
|
||||
refresh_timer_cb(pa_mainloop_api *api, pa_io_event *event, int fd, pa_io_event_flags_t flags, void *userdata)
|
||||
{
|
||||
struct module *mod = userdata;
|
||||
struct private *priv = mod->private;
|
||||
|
@ -155,8 +148,8 @@ schedule_refresh(struct module *mod)
|
|||
|
||||
// Start the refresh timer.
|
||||
struct itimerspec t = {
|
||||
.it_interval = { .tv_sec = 0, .tv_nsec = 0 },
|
||||
.it_value = { .tv_sec = 0, .tv_nsec = 50000000 },
|
||||
.it_interval = {.tv_sec = 0, .tv_nsec = 0},
|
||||
.it_value = {.tv_sec = 0, .tv_nsec = 50000000},
|
||||
};
|
||||
timerfd_settime(priv->refresh_timer_fd, 0, &t, NULL);
|
||||
|
||||
|
@ -200,12 +193,10 @@ set_sink_info(struct module *mod, const pa_sink_info *sink_info)
|
|||
free(priv->sink_port);
|
||||
|
||||
priv->sink_online = true;
|
||||
priv->sink_index = sink_info->index;
|
||||
priv->sink_index = sink_info->index;
|
||||
priv->sink_volume = sink_info->volume;
|
||||
priv->sink_muted = sink_info->mute;
|
||||
priv->sink_port = sink_info->active_port != NULL
|
||||
? strdup(sink_info->active_port->description)
|
||||
: NULL;
|
||||
priv->sink_muted = sink_info->mute;
|
||||
priv->sink_port = sink_info->active_port != NULL ? strdup(sink_info->active_port->description) : NULL;
|
||||
|
||||
mtx_unlock(&mod->lock);
|
||||
|
||||
|
@ -234,12 +225,10 @@ set_source_info(struct module *mod, const pa_source_info *source_info)
|
|||
free(priv->source_port);
|
||||
|
||||
priv->source_online = true;
|
||||
priv->source_index = source_info->index;
|
||||
priv->source_index = source_info->index;
|
||||
priv->source_volume = source_info->volume;
|
||||
priv->source_muted = source_info->mute;
|
||||
priv->source_port = source_info->active_port != NULL
|
||||
? strdup(source_info->active_port->description)
|
||||
: NULL;
|
||||
priv->source_muted = source_info->mute;
|
||||
priv->source_port = source_info->active_port != NULL ? strdup(source_info->active_port->description) : NULL;
|
||||
|
||||
mtx_unlock(&mod->lock);
|
||||
|
||||
|
@ -293,32 +282,28 @@ server_info_cb(pa_context *c, const pa_server_info *i, void *userdata)
|
|||
static void
|
||||
get_sink_info_by_name(pa_context *c, const char *name, void *userdata)
|
||||
{
|
||||
pa_operation *o =
|
||||
pa_context_get_sink_info_by_name(c, name, sink_info_cb, userdata);
|
||||
pa_operation *o = pa_context_get_sink_info_by_name(c, name, sink_info_cb, userdata);
|
||||
pa_operation_unref(o);
|
||||
}
|
||||
|
||||
static void
|
||||
get_source_info_by_name(pa_context *c, const char *name, void *userdata)
|
||||
{
|
||||
pa_operation *o =
|
||||
pa_context_get_source_info_by_name(c, name, source_info_cb, userdata);
|
||||
pa_operation *o = pa_context_get_source_info_by_name(c, name, source_info_cb, userdata);
|
||||
pa_operation_unref(o);
|
||||
}
|
||||
|
||||
static void
|
||||
get_sink_info_by_index(pa_context *c, uint32_t index, void *userdata)
|
||||
{
|
||||
pa_operation *o =
|
||||
pa_context_get_sink_info_by_index(c, index, sink_info_cb, userdata);
|
||||
pa_operation *o = pa_context_get_sink_info_by_index(c, index, sink_info_cb, userdata);
|
||||
pa_operation_unref(o);
|
||||
}
|
||||
|
||||
static void
|
||||
get_source_info_by_index(pa_context *c, uint32_t index, void *userdata)
|
||||
{
|
||||
pa_operation *o =
|
||||
pa_context_get_source_info_by_index(c, index, source_info_cb, userdata);
|
||||
pa_operation *o = pa_context_get_source_info_by_index(c, index, source_info_cb, userdata);
|
||||
pa_operation_unref(o);
|
||||
}
|
||||
|
||||
|
@ -332,15 +317,12 @@ get_server_info(pa_context *c, void *userdata)
|
|||
static void
|
||||
subscribe(pa_context *c, void *userdata)
|
||||
{
|
||||
pa_subscription_mask_t mask = PA_SUBSCRIPTION_MASK_SERVER
|
||||
| PA_SUBSCRIPTION_MASK_SINK
|
||||
| PA_SUBSCRIPTION_MASK_SOURCE;
|
||||
pa_subscription_mask_t mask = PA_SUBSCRIPTION_MASK_SERVER | PA_SUBSCRIPTION_MASK_SINK | PA_SUBSCRIPTION_MASK_SOURCE;
|
||||
pa_operation *o = pa_context_subscribe(c, mask, NULL, userdata);
|
||||
pa_operation_unref(o);
|
||||
}
|
||||
|
||||
static pa_context *
|
||||
connect_to_server(struct module *mod);
|
||||
static pa_context *connect_to_server(struct module *mod);
|
||||
|
||||
static void
|
||||
context_state_change_cb(pa_context *c, void *userdata)
|
||||
|
@ -380,16 +362,13 @@ context_state_change_cb(pa_context *c, void *userdata)
|
|||
}
|
||||
|
||||
static void
|
||||
subscription_event_cb(pa_context *c,
|
||||
pa_subscription_event_type_t event_type,
|
||||
uint32_t index,
|
||||
void *userdata)
|
||||
subscription_event_cb(pa_context *c, pa_subscription_event_type_t event_type, uint32_t index, void *userdata)
|
||||
{
|
||||
struct module *mod = userdata;
|
||||
struct private *priv = mod->private;
|
||||
|
||||
int facility = event_type & PA_SUBSCRIPTION_EVENT_FACILITY_MASK;
|
||||
int type = event_type & PA_SUBSCRIPTION_EVENT_TYPE_MASK;
|
||||
int type = event_type & PA_SUBSCRIPTION_EVENT_TYPE_MASK;
|
||||
|
||||
switch (facility) {
|
||||
case PA_SUBSCRIPTION_EVENT_SERVER:
|
||||
|
@ -435,8 +414,7 @@ connect_to_server(struct module *mod)
|
|||
pa_context_set_subscribe_callback(c, subscription_event_cb, mod);
|
||||
|
||||
// Connect to server.
|
||||
pa_context_flags_t flags = PA_CONTEXT_NOFAIL
|
||||
| PA_CONTEXT_NOAUTOSPAWN;
|
||||
pa_context_flags_t flags = PA_CONTEXT_NOFAIL | PA_CONTEXT_NOAUTOSPAWN;
|
||||
if (pa_context_connect(c, NULL, flags, NULL) < 0) {
|
||||
LOG_ERR("failed to connect to PulseAudio server: %s", context_error(c));
|
||||
pa_context_unref(c);
|
||||
|
@ -477,10 +455,8 @@ run(struct module *mod)
|
|||
|
||||
// Poll refresh timer and abort event.
|
||||
pa_mainloop_api *api = pa_mainloop_get_api(priv->mainloop);
|
||||
api->io_new(api, priv->refresh_timer_fd, PA_IO_EVENT_INPUT,
|
||||
refresh_timer_cb, mod);
|
||||
api->io_new(api, mod->abort_fd, PA_IO_EVENT_INPUT | PA_IO_EVENT_HANGUP,
|
||||
abort_event_cb, mod);
|
||||
api->io_new(api, priv->refresh_timer_fd, PA_IO_EVENT_INPUT, refresh_timer_cb, mod);
|
||||
api->io_new(api, mod->abort_fd, PA_IO_EVENT_INPUT | PA_IO_EVENT_HANGUP, abort_event_cb, mod);
|
||||
|
||||
// Run main loop.
|
||||
if (pa_mainloop_run(priv->mainloop, &ret) < 0) {
|
||||
|
@ -497,9 +473,7 @@ run(struct module *mod)
|
|||
}
|
||||
|
||||
static struct module *
|
||||
pulse_new(const char *sink_name,
|
||||
const char *source_name,
|
||||
struct particle *label)
|
||||
pulse_new(const char *sink_name, const char *source_name, struct particle *label)
|
||||
{
|
||||
struct private *priv = calloc(1, sizeof *priv);
|
||||
priv->label = label;
|
||||
|
@ -522,10 +496,9 @@ from_conf(const struct yml_node *node, struct conf_inherit inherited)
|
|||
const struct yml_node *source = yml_get_value(node, "source");
|
||||
const struct yml_node *content = yml_get_value(node, "content");
|
||||
|
||||
return pulse_new(
|
||||
sink != NULL ? yml_value_as_string(sink) : "@DEFAULT_SINK@",
|
||||
source != NULL ? yml_value_as_string(source) : "@DEFAULT_SOURCE@",
|
||||
conf_to_particle(content, inherited));
|
||||
return pulse_new(sink != NULL ? yml_value_as_string(sink) : "@DEFAULT_SINK@",
|
||||
source != NULL ? yml_value_as_string(source) : "@DEFAULT_SOURCE@",
|
||||
conf_to_particle(content, inherited));
|
||||
}
|
||||
|
||||
static bool
|
||||
|
|
|
@ -1,15 +1,15 @@
|
|||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <inttypes.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <inttypes.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <poll.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include <libudev.h>
|
||||
|
||||
|
@ -17,10 +17,10 @@
|
|||
|
||||
#define LOG_MODULE "removables"
|
||||
#define LOG_ENABLE_DBG 0
|
||||
#include "../log.h"
|
||||
#include "../bar/bar.h"
|
||||
#include "../config.h"
|
||||
#include "../config-verify.h"
|
||||
#include "../config.h"
|
||||
#include "../log.h"
|
||||
#include "../particles/dynlist.h"
|
||||
#include "../plugin.h"
|
||||
|
||||
|
@ -54,7 +54,8 @@ struct block_device {
|
|||
tll(struct partition) partitions;
|
||||
};
|
||||
|
||||
struct private {
|
||||
struct private
|
||||
{
|
||||
struct particle *label;
|
||||
int left_spacing;
|
||||
int right_spacing;
|
||||
|
@ -75,8 +76,7 @@ free_partition(struct partition *p)
|
|||
static void
|
||||
free_device(struct block_device *b)
|
||||
{
|
||||
tll_foreach(b->partitions, it)
|
||||
free_partition(&it->item);
|
||||
tll_foreach(b->partitions, it) free_partition(&it->item);
|
||||
tll_free(b->partitions);
|
||||
|
||||
free(b->sys_path);
|
||||
|
@ -91,8 +91,7 @@ destroy(struct module *mod)
|
|||
struct private *m = mod->private;
|
||||
m->label->destroy(m->label);
|
||||
|
||||
tll_foreach(m->devices, it)
|
||||
free_device(&it->item);
|
||||
tll_foreach(m->devices, it) free_device(&it->item);
|
||||
tll_free(m->devices);
|
||||
tll_free_and_free(m->ignore, free);
|
||||
|
||||
|
@ -113,24 +112,23 @@ content(struct module *mod)
|
|||
|
||||
tll(const struct partition *) partitions = tll_init();
|
||||
|
||||
tll_foreach(m->devices, dev) {
|
||||
tll_foreach(dev->item.partitions, part) {
|
||||
tll_push_back(partitions, &part->item);
|
||||
}
|
||||
tll_foreach(m->devices, dev)
|
||||
{
|
||||
tll_foreach(dev->item.partitions, part) { tll_push_back(partitions, &part->item); }
|
||||
}
|
||||
|
||||
struct exposable *exposables[max(tll_length(partitions), 1)];
|
||||
size_t idx = 0;
|
||||
|
||||
tll_foreach(partitions, it) {
|
||||
tll_foreach(partitions, it)
|
||||
{
|
||||
const struct partition *p = it->item;
|
||||
|
||||
char dummy_label[16];
|
||||
const char *label = p->label;
|
||||
|
||||
if (label == NULL) {
|
||||
snprintf(dummy_label, sizeof(dummy_label),
|
||||
"%.1f GB", (double)p->size / 1024 / 1024 / 1024 * 512);
|
||||
snprintf(dummy_label, sizeof(dummy_label), "%.1f GB", (double)p->size / 1024 / 1024 / 1024 * 512);
|
||||
label = dummy_label;
|
||||
}
|
||||
|
||||
|
@ -157,8 +155,7 @@ content(struct module *mod)
|
|||
}
|
||||
|
||||
tll_free(partitions);
|
||||
return dynlist_exposable_new(
|
||||
exposables, idx, m->left_spacing, m->right_spacing);
|
||||
return dynlist_exposable_new(exposables, idx, m->left_spacing, m->right_spacing);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -178,9 +175,7 @@ find_mount_points(const char *dev_path, mount_point_list_t *mount_points)
|
|||
while (fgets(line, sizeof(line), f) != NULL) {
|
||||
char *dev = NULL, *path = NULL;
|
||||
|
||||
if (sscanf(line, "%*u %*u %*u:%*u %*s %ms %*[^-] - %*s %ms %*s",
|
||||
&path, &dev) != 2)
|
||||
{
|
||||
if (sscanf(line, "%*u %*u %*u:%*u %*s %ms %*[^-] - %*s %ms %*s", &path, &dev) != 2) {
|
||||
LOG_ERR("failed to parse /proc/self/mountinfo: %s", line);
|
||||
free(dev);
|
||||
free(path);
|
||||
|
@ -207,9 +202,11 @@ update_mount_points(struct partition *partition)
|
|||
|
||||
/* Remove mount points that no longer exists (i.e. old mount
|
||||
* points that aren't in the new list) */
|
||||
tll_foreach(partition->mount_points, old) {
|
||||
tll_foreach(partition->mount_points, old)
|
||||
{
|
||||
bool gone = true;
|
||||
tll_foreach(new_mounts, new) {
|
||||
tll_foreach(new_mounts, new)
|
||||
{
|
||||
if (strcmp(new->item, old->item) == 0) {
|
||||
/* Remove from new list, as it's already in the
|
||||
* partitions list */
|
||||
|
@ -228,7 +225,8 @@ update_mount_points(struct partition *partition)
|
|||
|
||||
/* Add new mount points (i.e. mount points in the new list, that
|
||||
* aren't in the old list) */
|
||||
tll_foreach(new_mounts, new) {
|
||||
tll_foreach(new_mounts, new)
|
||||
{
|
||||
LOG_DBG("%s: mounted on %s", partition->dev_path, new->item);
|
||||
tll_push_back(partition->mount_points, new->item);
|
||||
|
||||
|
@ -242,14 +240,13 @@ update_mount_points(struct partition *partition)
|
|||
}
|
||||
|
||||
static struct partition *
|
||||
add_partition(struct module *mod, struct block_device *block,
|
||||
struct udev_device *dev)
|
||||
add_partition(struct module *mod, struct block_device *block, struct udev_device *dev)
|
||||
{
|
||||
struct private *m = mod->private;
|
||||
const char *_size = udev_device_get_sysattr_value(dev, "size");
|
||||
uint64_t size = 0;
|
||||
if (_size != NULL)
|
||||
sscanf(_size, "%"SCNu64, &size);
|
||||
sscanf(_size, "%" SCNu64, &size);
|
||||
|
||||
#if 0
|
||||
struct udev_list_entry *e = NULL;
|
||||
|
@ -260,7 +257,8 @@ add_partition(struct module *mod, struct block_device *block,
|
|||
|
||||
const char *devname = udev_device_get_property_value(dev, "DEVNAME");
|
||||
if (devname != NULL) {
|
||||
tll_foreach(m->ignore, it) {
|
||||
tll_foreach(m->ignore, it)
|
||||
{
|
||||
if (strcmp(it->item, devname) == 0) {
|
||||
LOG_DBG("ignoring %s because it is on the ignore list", devname);
|
||||
return NULL;
|
||||
|
@ -272,21 +270,17 @@ add_partition(struct module *mod, struct block_device *block,
|
|||
if (label == NULL)
|
||||
label = udev_device_get_property_value(dev, "ID_LABEL");
|
||||
|
||||
LOG_INFO("partition: add: %s: label=%s, size=%"PRIu64,
|
||||
udev_device_get_devnode(dev), label, size);
|
||||
LOG_INFO("partition: add: %s: label=%s, size=%" PRIu64, udev_device_get_devnode(dev), label, size);
|
||||
|
||||
mtx_lock(&mod->lock);
|
||||
|
||||
tll_push_back(
|
||||
block->partitions,
|
||||
((struct partition){
|
||||
.block = block,
|
||||
.sys_path = strdup(udev_device_get_devpath(dev)),
|
||||
.dev_path = strdup(udev_device_get_devnode(dev)),
|
||||
.label = label != NULL ? strdup(label) : NULL,
|
||||
.size = size,
|
||||
.audio_cd = false,
|
||||
.mount_points = tll_init()}));
|
||||
tll_push_back(block->partitions, ((struct partition){.block = block,
|
||||
.sys_path = strdup(udev_device_get_devpath(dev)),
|
||||
.dev_path = strdup(udev_device_get_devnode(dev)),
|
||||
.label = label != NULL ? strdup(label) : NULL,
|
||||
.size = size,
|
||||
.audio_cd = false,
|
||||
.mount_points = tll_init()}));
|
||||
|
||||
struct partition *p = &tll_back(block->partitions);
|
||||
update_mount_points(p);
|
||||
|
@ -296,14 +290,13 @@ add_partition(struct module *mod, struct block_device *block,
|
|||
}
|
||||
|
||||
static struct partition *
|
||||
add_audio_cd(struct module *mod, struct block_device *block,
|
||||
struct udev_device *dev)
|
||||
add_audio_cd(struct module *mod, struct block_device *block, struct udev_device *dev)
|
||||
{
|
||||
struct private *m = mod->private;
|
||||
const char *_size = udev_device_get_sysattr_value(dev, "size");
|
||||
uint64_t size = 0;
|
||||
if (_size != NULL)
|
||||
sscanf(_size, "%"SCNu64, &size);
|
||||
sscanf(_size, "%" SCNu64, &size);
|
||||
|
||||
#if 0
|
||||
struct udev_list_entry *e = NULL;
|
||||
|
@ -314,7 +307,8 @@ add_audio_cd(struct module *mod, struct block_device *block,
|
|||
|
||||
const char *devname = udev_device_get_property_value(dev, "DEVNAME");
|
||||
if (devname != NULL) {
|
||||
tll_foreach(m->ignore, it) {
|
||||
tll_foreach(m->ignore, it)
|
||||
{
|
||||
if (strcmp(it->item, devname) == 0) {
|
||||
LOG_DBG("ignoring %s because it is on the ignore list", devname);
|
||||
return NULL;
|
||||
|
@ -322,28 +316,24 @@ add_audio_cd(struct module *mod, struct block_device *block,
|
|||
}
|
||||
}
|
||||
|
||||
const char *_track_count = udev_device_get_property_value(
|
||||
dev, "ID_CDROM_MEDIA_TRACK_COUNT_AUDIO");
|
||||
const char *_track_count = udev_device_get_property_value(dev, "ID_CDROM_MEDIA_TRACK_COUNT_AUDIO");
|
||||
unsigned long track_count = strtoul(_track_count, NULL, 10);
|
||||
|
||||
char label[64];
|
||||
snprintf(label, sizeof(label), "Audio CD - %lu tracks", track_count);
|
||||
|
||||
LOG_INFO("audio CD: add: %s: tracks=%lu, label=%s, size=%"PRIu64,
|
||||
udev_device_get_devnode(dev), track_count, label, size);
|
||||
LOG_INFO("audio CD: add: %s: tracks=%lu, label=%s, size=%" PRIu64, udev_device_get_devnode(dev), track_count, label,
|
||||
size);
|
||||
|
||||
mtx_lock(&mod->lock);
|
||||
|
||||
tll_push_back(
|
||||
block->partitions,
|
||||
((struct partition){
|
||||
.block = block,
|
||||
.sys_path = strdup(udev_device_get_devpath(dev)),
|
||||
.dev_path = strdup(udev_device_get_devnode(dev)),
|
||||
.label = label != NULL ? strdup(label) : NULL,
|
||||
.size = size,
|
||||
.audio_cd = true,
|
||||
.mount_points = tll_init()}));
|
||||
tll_push_back(block->partitions, ((struct partition){.block = block,
|
||||
.sys_path = strdup(udev_device_get_devpath(dev)),
|
||||
.dev_path = strdup(udev_device_get_devnode(dev)),
|
||||
.label = label != NULL ? strdup(label) : NULL,
|
||||
.size = size,
|
||||
.audio_cd = true,
|
||||
.mount_points = tll_init()}));
|
||||
|
||||
struct partition *p = &tll_back(block->partitions);
|
||||
update_mount_points(p);
|
||||
|
@ -353,17 +343,15 @@ add_audio_cd(struct module *mod, struct block_device *block,
|
|||
}
|
||||
|
||||
static bool
|
||||
del_partition(struct module *mod, struct block_device *block,
|
||||
struct udev_device *dev)
|
||||
del_partition(struct module *mod, struct block_device *block, struct udev_device *dev)
|
||||
{
|
||||
const char *sys_path = udev_device_get_devpath(dev);
|
||||
mtx_lock(&mod->lock);
|
||||
|
||||
tll_foreach(block->partitions, it) {
|
||||
tll_foreach(block->partitions, it)
|
||||
{
|
||||
if (strcmp(it->item.sys_path, sys_path) == 0) {
|
||||
LOG_INFO("%s: del: %s",
|
||||
it->item.audio_cd ? "audio CD" : "partition",
|
||||
it->item.dev_path);
|
||||
LOG_INFO("%s: del: %s", it->item.audio_cd ? "audio CD" : "partition", it->item.dev_path);
|
||||
|
||||
free_partition(&it->item);
|
||||
tll_remove(block->partitions, it);
|
||||
|
@ -392,7 +380,8 @@ add_device(struct module *mod, struct udev_device *dev)
|
|||
|
||||
const char *devname = udev_device_get_property_value(dev, "DEVNAME");
|
||||
if (devname != NULL) {
|
||||
tll_foreach(m->ignore, it) {
|
||||
tll_foreach(m->ignore, it)
|
||||
{
|
||||
if (strcmp(it->item, devname) == 0) {
|
||||
LOG_DBG("ignoring %s because it is on the ignore list", devname);
|
||||
return NULL;
|
||||
|
@ -403,11 +392,12 @@ add_device(struct module *mod, struct udev_device *dev)
|
|||
const char *_size = udev_device_get_sysattr_value(dev, "size");
|
||||
uint64_t size = 0;
|
||||
if (_size != NULL)
|
||||
sscanf(_size, "%"SCNu64, &size);
|
||||
sscanf(_size, "%" SCNu64, &size);
|
||||
|
||||
#if 1
|
||||
struct udev_list_entry *e = NULL;
|
||||
udev_list_entry_foreach(e, udev_device_get_properties_list_entry(dev)) {
|
||||
udev_list_entry_foreach(e, udev_device_get_properties_list_entry(dev))
|
||||
{
|
||||
LOG_DBG("%s -> %s", udev_list_entry_get_name(e), udev_list_entry_get_value(e));
|
||||
}
|
||||
#endif
|
||||
|
@ -424,27 +414,22 @@ add_device(struct module *mod, struct udev_device *dev)
|
|||
const char *_fs_usage = udev_device_get_property_value(dev, "ID_FS_USAGE");
|
||||
bool have_fs = _fs_usage != NULL && strcmp(_fs_usage, "filesystem") == 0;
|
||||
|
||||
const char *_audio_track_count = udev_device_get_property_value(
|
||||
dev, "ID_CDROM_MEDIA_TRACK_COUNT_AUDIO");
|
||||
unsigned long audio_track_count =
|
||||
_audio_track_count != NULL ? strtoul(_audio_track_count, NULL, 10) : 0;
|
||||
const char *_audio_track_count = udev_device_get_property_value(dev, "ID_CDROM_MEDIA_TRACK_COUNT_AUDIO");
|
||||
unsigned long audio_track_count = _audio_track_count != NULL ? strtoul(_audio_track_count, NULL, 10) : 0;
|
||||
|
||||
LOG_DBG("device: add: %s: vendor=%s, model=%s, optical=%d, size=%"PRIu64,
|
||||
udev_device_get_devnode(dev), vendor, model, optical, size);
|
||||
LOG_DBG("device: add: %s: vendor=%s, model=%s, optical=%d, size=%" PRIu64, udev_device_get_devnode(dev), vendor,
|
||||
model, optical, size);
|
||||
|
||||
mtx_lock(&mod->lock);
|
||||
|
||||
tll_push_back(
|
||||
m->devices,
|
||||
((struct block_device){
|
||||
.sys_path = strdup(udev_device_get_devpath(dev)),
|
||||
.dev_path = strdup(udev_device_get_devnode(dev)),
|
||||
.size = size,
|
||||
.vendor = vendor != NULL ? strdup(vendor) : NULL,
|
||||
.model = model != NULL ? strdup(model) : NULL,
|
||||
.optical = optical,
|
||||
.media = media,
|
||||
.partitions = tll_init()}));
|
||||
tll_push_back(m->devices, ((struct block_device){.sys_path = strdup(udev_device_get_devpath(dev)),
|
||||
.dev_path = strdup(udev_device_get_devnode(dev)),
|
||||
.size = size,
|
||||
.vendor = vendor != NULL ? strdup(vendor) : NULL,
|
||||
.model = model != NULL ? strdup(model) : NULL,
|
||||
.optical = optical,
|
||||
.media = media,
|
||||
.partitions = tll_init()}));
|
||||
|
||||
mtx_unlock(&mod->lock);
|
||||
|
||||
|
@ -466,7 +451,8 @@ del_device(struct module *mod, struct udev_device *dev)
|
|||
const char *sys_path = udev_device_get_devpath(dev);
|
||||
mtx_lock(&mod->lock);
|
||||
|
||||
tll_foreach(m->devices, it) {
|
||||
tll_foreach(m->devices, it)
|
||||
{
|
||||
if (strcmp(it->item.sys_path, sys_path) == 0) {
|
||||
LOG_DBG("device: del: %s", it->item.dev_path);
|
||||
|
||||
|
@ -490,7 +476,8 @@ change_device(struct module *mod, struct udev_device *dev)
|
|||
|
||||
struct block_device *block = NULL;
|
||||
|
||||
tll_foreach(m->devices, it) {
|
||||
tll_foreach(m->devices, it)
|
||||
{
|
||||
if (strcmp(it->item.sys_path, sys_path) == 0) {
|
||||
block = &it->item;
|
||||
break;
|
||||
|
@ -511,10 +498,8 @@ change_device(struct module *mod, struct udev_device *dev)
|
|||
const char *_fs_usage = udev_device_get_property_value(dev, "ID_FS_USAGE");
|
||||
bool have_fs = _fs_usage != NULL && strcmp(_fs_usage, "filesystem") == 0;
|
||||
|
||||
const char *_audio_track_count = udev_device_get_property_value(
|
||||
dev, "ID_CDROM_MEDIA_TRACK_COUNT_AUDIO");
|
||||
unsigned long audio_track_count =
|
||||
_audio_track_count != NULL ? strtoul(_audio_track_count, NULL, 10) : 0;
|
||||
const char *_audio_track_count = udev_device_get_property_value(dev, "ID_CDROM_MEDIA_TRACK_COUNT_AUDIO");
|
||||
unsigned long audio_track_count = _audio_track_count != NULL ? strtoul(_audio_track_count, NULL, 10) : 0;
|
||||
|
||||
bool media_change = media != block->media;
|
||||
|
||||
|
@ -522,8 +507,7 @@ change_device(struct module *mod, struct udev_device *dev)
|
|||
mtx_unlock(&mod->lock);
|
||||
|
||||
if (media_change) {
|
||||
LOG_INFO("device: change: %s: media %s",
|
||||
block->dev_path, media ? "inserted" : "removed");
|
||||
LOG_INFO("device: change: %s: media %s", block->dev_path, media ? "inserted" : "removed");
|
||||
|
||||
if (media) {
|
||||
if (have_fs)
|
||||
|
@ -569,7 +553,8 @@ handle_udev_event(struct module *mod, struct udev_device *dev)
|
|||
struct udev_device *parent = udev_device_get_parent(dev);
|
||||
const char *parent_sys_path = udev_device_get_devpath(parent);
|
||||
|
||||
tll_foreach(m->devices, it) {
|
||||
tll_foreach(m->devices, it)
|
||||
{
|
||||
if (strcmp(it->item.sys_path, parent_sys_path) != 0)
|
||||
continue;
|
||||
|
||||
|
@ -578,8 +563,7 @@ handle_udev_event(struct module *mod, struct udev_device *dev)
|
|||
else if (del)
|
||||
return del_partition(mod, &it->item, dev);
|
||||
else {
|
||||
LOG_ERR("unimplemented: 'change' event on partition: %s",
|
||||
udev_device_get_devpath(dev));
|
||||
LOG_ERR("unimplemented: 'change' event on partition: %s", udev_device_get_devpath(dev));
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
|
@ -606,15 +590,15 @@ run(struct module *mod)
|
|||
udev_enumerate_add_match_subsystem(dev_enum, "block");
|
||||
|
||||
/* TODO: verify how an optical presents itself */
|
||||
//udev_enumerate_add_match_sysattr(dev_enum, "removable", "1");
|
||||
// udev_enumerate_add_match_sysattr(dev_enum, "removable", "1");
|
||||
udev_enumerate_add_match_property(dev_enum, "DEVTYPE", "disk");
|
||||
udev_enumerate_scan_devices(dev_enum);
|
||||
|
||||
/* Loop list, and for each device, enumerate its partitions */
|
||||
struct udev_list_entry *entry = NULL;
|
||||
udev_list_entry_foreach(entry, udev_enumerate_get_list_entry(dev_enum)) {
|
||||
struct udev_device *dev = udev_device_new_from_syspath(
|
||||
udev, udev_list_entry_get_name(entry));
|
||||
udev_list_entry_foreach(entry, udev_enumerate_get_list_entry(dev_enum))
|
||||
{
|
||||
struct udev_device *dev = udev_device_new_from_syspath(udev, udev_list_entry_get_name(entry));
|
||||
|
||||
struct block_device *block = add_device(mod, dev);
|
||||
if (block == NULL) {
|
||||
|
@ -631,9 +615,9 @@ run(struct module *mod)
|
|||
udev_enumerate_scan_devices(part_enum);
|
||||
|
||||
struct udev_list_entry *sub_entry = NULL;
|
||||
udev_list_entry_foreach(sub_entry, udev_enumerate_get_list_entry(part_enum)) {
|
||||
struct udev_device *partition = udev_device_new_from_syspath(
|
||||
udev, udev_list_entry_get_name(sub_entry));
|
||||
udev_list_entry_foreach(sub_entry, udev_enumerate_get_list_entry(part_enum))
|
||||
{
|
||||
struct udev_device *partition = udev_device_new_from_syspath(udev, udev_list_entry_get_name(sub_entry));
|
||||
add_partition(mod, block, partition);
|
||||
udev_device_unref(partition);
|
||||
}
|
||||
|
@ -673,8 +657,10 @@ run(struct module *mod)
|
|||
bool update = false;
|
||||
|
||||
if (fds[2].revents & POLLPRI) {
|
||||
tll_foreach(m->devices, dev) {
|
||||
tll_foreach(dev->item.partitions, part) {
|
||||
tll_foreach(m->devices, dev)
|
||||
{
|
||||
tll_foreach(dev->item.partitions, part)
|
||||
{
|
||||
if (update_mount_points(&part->item))
|
||||
update = true;
|
||||
}
|
||||
|
@ -703,8 +689,8 @@ run(struct module *mod)
|
|||
}
|
||||
|
||||
static struct module *
|
||||
removables_new(struct particle *label, int left_spacing, int right_spacing,
|
||||
size_t ignore_count, const char *ignore[static ignore_count])
|
||||
removables_new(struct particle *label, int left_spacing, int right_spacing, size_t ignore_count,
|
||||
const char *ignore[static ignore_count])
|
||||
{
|
||||
struct private *priv = calloc(1, sizeof(*priv));
|
||||
priv->label = label;
|
||||
|
@ -732,26 +718,22 @@ from_conf(const struct yml_node *node, struct conf_inherit inherited)
|
|||
const struct yml_node *right_spacing = yml_get_value(node, "right-spacing");
|
||||
const struct yml_node *ignore_list = yml_get_value(node, "ignore");
|
||||
|
||||
int left = spacing != NULL ? yml_value_as_int(spacing) :
|
||||
left_spacing != NULL ? yml_value_as_int(left_spacing) : 0;
|
||||
int right = spacing != NULL ? yml_value_as_int(spacing) :
|
||||
right_spacing != NULL ? yml_value_as_int(right_spacing) : 0;
|
||||
int left = spacing != NULL ? yml_value_as_int(spacing) : left_spacing != NULL ? yml_value_as_int(left_spacing) : 0;
|
||||
int right = spacing != NULL ? yml_value_as_int(spacing)
|
||||
: right_spacing != NULL ? yml_value_as_int(right_spacing)
|
||||
: 0;
|
||||
|
||||
size_t ignore_count = ignore_list != NULL ? yml_list_length(ignore_list) : 0;
|
||||
const char *ignore[max(ignore_count, 1)];
|
||||
|
||||
if (ignore_list != NULL) {
|
||||
size_t i = 0;
|
||||
for (struct yml_list_iter iter = yml_list_iter(ignore_list);
|
||||
iter.node != NULL;
|
||||
yml_list_next(&iter), i++)
|
||||
{
|
||||
for (struct yml_list_iter iter = yml_list_iter(ignore_list); iter.node != NULL; yml_list_next(&iter), i++) {
|
||||
ignore[i] = yml_value_as_string(iter.node);
|
||||
}
|
||||
}
|
||||
|
||||
return removables_new(
|
||||
conf_to_particle(content, inherited), left, right, ignore_count, ignore);
|
||||
return removables_new(conf_to_particle(content, inherited), left, right, ignore_count, ignore);
|
||||
}
|
||||
|
||||
static bool
|
||||
|
|
174
modules/river.c
174
modules/river.c
|
@ -1,17 +1,17 @@
|
|||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <poll.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <assert.h>
|
||||
#include <poll.h>
|
||||
|
||||
#include <wayland-client.h>
|
||||
#include <tllist.h>
|
||||
#include <wayland-client.h>
|
||||
|
||||
#define LOG_MODULE "river"
|
||||
#define LOG_ENABLE_DBG 0
|
||||
#include "../log.h"
|
||||
#include "../plugin.h"
|
||||
#include "../particles/dynlist.h"
|
||||
#include "../plugin.h"
|
||||
|
||||
#include "river-status-unstable-v1.h"
|
||||
#include "xdg-output-unstable-v1.h"
|
||||
|
@ -49,7 +49,8 @@ struct seat {
|
|||
struct output *output;
|
||||
};
|
||||
|
||||
struct private {
|
||||
struct private
|
||||
{
|
||||
struct module *mod;
|
||||
struct zxdg_output_manager_v1 *xdg_output_manager;
|
||||
struct zriver_status_manager_v1 *status_manager;
|
||||
|
@ -92,13 +93,12 @@ content(struct module *mod)
|
|||
uint32_t output_focused = 0;
|
||||
uint32_t seat_focused = 0;
|
||||
|
||||
tll_foreach(m->outputs, it) {
|
||||
tll_foreach(m->outputs, it)
|
||||
{
|
||||
const struct output *output = &it->item;
|
||||
|
||||
if (!m->all_monitors &&
|
||||
output_bar_is_on != NULL && output->name != NULL &&
|
||||
strcmp(output->name, output_bar_is_on) != 0)
|
||||
{
|
||||
if (!m->all_monitors && output_bar_is_on != NULL && output->name != NULL
|
||||
&& strcmp(output->name, output_bar_is_on) != 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -106,7 +106,8 @@ content(struct module *mod)
|
|||
urgent |= output->urgent;
|
||||
occupied |= output->occupied;
|
||||
|
||||
tll_foreach(m->seats, it2) {
|
||||
tll_foreach(m->seats, it2)
|
||||
{
|
||||
const struct seat *seat = &it2->item;
|
||||
if (seat->output == output) {
|
||||
seat_focused |= output->focused;
|
||||
|
@ -127,10 +128,7 @@ content(struct module *mod)
|
|||
bool is_urgent = urgent & (1u << i);
|
||||
bool is_occupied = occupied & (1u << i);
|
||||
|
||||
const char *state =
|
||||
is_urgent ? "urgent" :
|
||||
is_visible ? is_focused ? "focused" : "unfocused" :
|
||||
"invisible";
|
||||
const char *state = is_urgent ? "urgent" : is_visible ? is_focused ? "focused" : "unfocused" : "invisible";
|
||||
|
||||
#if 0
|
||||
LOG_DBG("tag: #%u, visible=%d, focused=%d, occupied=%d, state=%s",
|
||||
|
@ -155,12 +153,10 @@ content(struct module *mod)
|
|||
|
||||
if (m->title != NULL) {
|
||||
size_t i = 32;
|
||||
tll_foreach(m->seats, it) {
|
||||
tll_foreach(m->seats, it)
|
||||
{
|
||||
const struct seat *seat = &it->item;
|
||||
const char *layout =
|
||||
seat->output != NULL && seat->output->layout != NULL
|
||||
? seat->output->layout
|
||||
: "";
|
||||
const char *layout = seat->output != NULL && seat->output->layout != NULL ? seat->output->layout : "";
|
||||
|
||||
struct tag_set tags = {
|
||||
.tags = (struct tag *[]){
|
||||
|
@ -187,15 +183,15 @@ verify_iface_version(const char *iface, uint32_t version, uint32_t wanted)
|
|||
if (version >= wanted)
|
||||
return true;
|
||||
|
||||
LOG_ERR("%s: need interface version %u, but compositor only implements %u",
|
||||
iface, wanted, version);
|
||||
LOG_ERR("%s: need interface version %u, but compositor only implements %u", iface, wanted, version);
|
||||
return false;
|
||||
}
|
||||
|
||||
static void
|
||||
output_destroy(struct output *output)
|
||||
{
|
||||
tll_foreach(output->m->seats, it) {
|
||||
tll_foreach(output->m->seats, it)
|
||||
{
|
||||
struct seat *seat = &it->item;
|
||||
if (seat->output == output)
|
||||
seat->output = NULL;
|
||||
|
@ -223,8 +219,7 @@ seat_destroy(struct seat *seat)
|
|||
}
|
||||
|
||||
static void
|
||||
focused_tags(void *data, struct zriver_output_status_v1 *zriver_output_status_v1,
|
||||
uint32_t tags)
|
||||
focused_tags(void *data, struct zriver_output_status_v1 *zriver_output_status_v1, uint32_t tags)
|
||||
{
|
||||
struct output *output = data;
|
||||
|
||||
|
@ -241,8 +236,7 @@ focused_tags(void *data, struct zriver_output_status_v1 *zriver_output_status_v1
|
|||
}
|
||||
|
||||
static void
|
||||
view_tags(void *data, struct zriver_output_status_v1 *zriver_output_status_v1,
|
||||
struct wl_array *tags)
|
||||
view_tags(void *data, struct zriver_output_status_v1 *zriver_output_status_v1, struct wl_array *tags)
|
||||
{
|
||||
struct output *output = data;
|
||||
struct module *mod = output->m->mod;
|
||||
|
@ -254,9 +248,7 @@ view_tags(void *data, struct zriver_output_status_v1 *zriver_output_status_v1,
|
|||
/* Each entry in the list is a view, and the value is the tags
|
||||
* associated with that view */
|
||||
uint32_t *set;
|
||||
wl_array_for_each(set, tags) {
|
||||
output->occupied |= *set;
|
||||
}
|
||||
wl_array_for_each(set, tags) { output->occupied |= *set; }
|
||||
|
||||
LOG_DBG("output: %s: occupied tags: 0x%0x", output->name, output->occupied);
|
||||
}
|
||||
|
@ -265,8 +257,7 @@ view_tags(void *data, struct zriver_output_status_v1 *zriver_output_status_v1,
|
|||
}
|
||||
|
||||
static void
|
||||
urgent_tags(void *data, struct zriver_output_status_v1 *zriver_output_status_v1,
|
||||
uint32_t tags)
|
||||
urgent_tags(void *data, struct zriver_output_status_v1 *zriver_output_status_v1, uint32_t tags)
|
||||
{
|
||||
struct output *output = data;
|
||||
struct module *mod = output->m->mod;
|
||||
|
@ -281,9 +272,7 @@ urgent_tags(void *data, struct zriver_output_status_v1 *zriver_output_status_v1,
|
|||
|
||||
#if defined(ZRIVER_OUTPUT_STATUS_V1_LAYOUT_NAME_SINCE_VERSION)
|
||||
static void
|
||||
layout_name(void *data,
|
||||
struct zriver_output_status_v1 *zriver_output_status_v1,
|
||||
const char *name)
|
||||
layout_name(void *data, struct zriver_output_status_v1 *zriver_output_status_v1, const char *name)
|
||||
{
|
||||
struct output *output = data;
|
||||
struct module *mod = output->m->mod;
|
||||
|
@ -300,8 +289,7 @@ layout_name(void *data,
|
|||
|
||||
#if defined(ZRIVER_OUTPUT_STATUS_V1_LAYOUT_NAME_CLEAR_SINCE_VERSION)
|
||||
static void
|
||||
layout_name_clear(void *data,
|
||||
struct zriver_output_status_v1 *zriver_output_status_v1)
|
||||
layout_name_clear(void *data, struct zriver_output_status_v1 *zriver_output_status_v1)
|
||||
{
|
||||
struct output *output = data;
|
||||
struct module *mod = output->m->mod;
|
||||
|
@ -329,15 +317,12 @@ static const struct zriver_output_status_v1_listener river_status_output_listene
|
|||
};
|
||||
|
||||
static void
|
||||
xdg_output_handle_logical_position(void *data,
|
||||
struct zxdg_output_v1 *xdg_output,
|
||||
int32_t x, int32_t y)
|
||||
xdg_output_handle_logical_position(void *data, struct zxdg_output_v1 *xdg_output, int32_t x, int32_t y)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
xdg_output_handle_logical_size(void *data, struct zxdg_output_v1 *xdg_output,
|
||||
int32_t width, int32_t height)
|
||||
xdg_output_handle_logical_size(void *data, struct zxdg_output_v1 *xdg_output, int32_t width, int32_t height)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -347,8 +332,7 @@ xdg_output_handle_done(void *data, struct zxdg_output_v1 *xdg_output)
|
|||
}
|
||||
|
||||
static void
|
||||
xdg_output_handle_name(void *data, struct zxdg_output_v1 *xdg_output,
|
||||
const char *name)
|
||||
xdg_output_handle_name(void *data, struct zxdg_output_v1 *xdg_output, const char *name)
|
||||
{
|
||||
struct output *output = data;
|
||||
struct module *mod = output->m->mod;
|
||||
|
@ -363,8 +347,7 @@ xdg_output_handle_name(void *data, struct zxdg_output_v1 *xdg_output,
|
|||
}
|
||||
|
||||
static void
|
||||
xdg_output_handle_description(void *data, struct zxdg_output_v1 *xdg_output,
|
||||
const char *description)
|
||||
xdg_output_handle_description(void *data, struct zxdg_output_v1 *xdg_output, const char *description)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -391,36 +374,32 @@ update_output(struct output *output)
|
|||
output->status = NULL;
|
||||
}
|
||||
|
||||
output->status = zriver_status_manager_v1_get_river_output_status(
|
||||
output->m->status_manager, output->wl_output);
|
||||
output->status = zriver_status_manager_v1_get_river_output_status(output->m->status_manager, output->wl_output);
|
||||
|
||||
if (output->status != NULL) {
|
||||
zriver_output_status_v1_add_listener(
|
||||
output->status, &river_status_output_listener, output);
|
||||
zriver_output_status_v1_add_listener(output->status, &river_status_output_listener, output);
|
||||
}
|
||||
}
|
||||
|
||||
if (output->m->xdg_output_manager != NULL && output->xdg_output == NULL) {
|
||||
output->xdg_output = zxdg_output_manager_v1_get_xdg_output(
|
||||
output->m->xdg_output_manager, output->wl_output);
|
||||
output->xdg_output = zxdg_output_manager_v1_get_xdg_output(output->m->xdg_output_manager, output->wl_output);
|
||||
|
||||
if (output->xdg_output != NULL) {
|
||||
zxdg_output_v1_add_listener(
|
||||
output->xdg_output, &xdg_output_listener, output);
|
||||
zxdg_output_v1_add_listener(output->xdg_output, &xdg_output_listener, output);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
focused_output(void *data, struct zriver_seat_status_v1 *zriver_seat_status_v1,
|
||||
struct wl_output *wl_output)
|
||||
focused_output(void *data, struct zriver_seat_status_v1 *zriver_seat_status_v1, struct wl_output *wl_output)
|
||||
{
|
||||
struct seat *seat = data;
|
||||
struct private *m = seat->m;
|
||||
struct module *mod = m->mod;
|
||||
|
||||
struct output *output = NULL;
|
||||
tll_foreach(m->outputs, it) {
|
||||
tll_foreach(m->outputs, it)
|
||||
{
|
||||
if (it->item.wl_output == wl_output) {
|
||||
output = &it->item;
|
||||
break;
|
||||
|
@ -441,8 +420,7 @@ focused_output(void *data, struct zriver_seat_status_v1 *zriver_seat_status_v1,
|
|||
}
|
||||
|
||||
static void
|
||||
unfocused_output(void *data, struct zriver_seat_status_v1 *zriver_seat_status_v1,
|
||||
struct wl_output *wl_output)
|
||||
unfocused_output(void *data, struct zriver_seat_status_v1 *zriver_seat_status_v1, struct wl_output *wl_output)
|
||||
{
|
||||
struct seat *seat = data;
|
||||
struct private *m = seat->m;
|
||||
|
@ -451,7 +429,8 @@ unfocused_output(void *data, struct zriver_seat_status_v1 *zriver_seat_status_v1
|
|||
mtx_lock(&mod->lock);
|
||||
{
|
||||
struct output *output = NULL;
|
||||
tll_foreach(m->outputs, it) {
|
||||
tll_foreach(m->outputs, it)
|
||||
{
|
||||
if (it->item.wl_output == wl_output) {
|
||||
output = &it->item;
|
||||
break;
|
||||
|
@ -469,8 +448,7 @@ unfocused_output(void *data, struct zriver_seat_status_v1 *zriver_seat_status_v1
|
|||
}
|
||||
|
||||
static void
|
||||
focused_view(void *data, struct zriver_seat_status_v1 *zriver_seat_status_v1,
|
||||
const char *title)
|
||||
focused_view(void *data, struct zriver_seat_status_v1 *zriver_seat_status_v1, const char *title)
|
||||
{
|
||||
struct seat *seat = data;
|
||||
struct module *mod = seat->m->mod;
|
||||
|
@ -485,11 +463,9 @@ focused_view(void *data, struct zriver_seat_status_v1 *zriver_seat_status_v1,
|
|||
|
||||
const char *output_bar_is_on = mod->bar->output_name(mod->bar);
|
||||
|
||||
if (seat->m->all_monitors ||
|
||||
(output_bar_is_on != NULL &&
|
||||
seat->output != NULL && seat->output->name != NULL &&
|
||||
strcmp(output_bar_is_on, seat->output->name) == 0))
|
||||
{
|
||||
if (seat->m->all_monitors
|
||||
|| (output_bar_is_on != NULL && seat->output != NULL && seat->output->name != NULL
|
||||
&& strcmp(output_bar_is_on, seat->output->name) == 0)) {
|
||||
mtx_lock(&mod->lock);
|
||||
{
|
||||
free(seat->title);
|
||||
|
@ -502,8 +478,7 @@ focused_view(void *data, struct zriver_seat_status_v1 *zriver_seat_status_v1,
|
|||
|
||||
#if defined(ZRIVER_SEAT_STATUS_V1_MODE_SINCE_VERSION)
|
||||
static void
|
||||
mode(void *data, struct zriver_seat_status_v1 *zriver_seat_status_v1,
|
||||
const char *name)
|
||||
mode(void *data, struct zriver_seat_status_v1 *zriver_seat_status_v1, const char *name)
|
||||
{
|
||||
struct seat *seat = data;
|
||||
struct module *mod = seat->m->mod;
|
||||
|
@ -531,8 +506,7 @@ static const struct zriver_seat_status_v1_listener river_seat_status_listener =
|
|||
};
|
||||
|
||||
static void
|
||||
seat_handle_capabilities(void *data, struct wl_seat *wl_seat,
|
||||
enum wl_seat_capability caps)
|
||||
seat_handle_capabilities(void *data, struct wl_seat *wl_seat, enum wl_seat_capability caps)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -569,19 +543,16 @@ update_seat(struct seat *seat)
|
|||
seat->status = NULL;
|
||||
}
|
||||
|
||||
seat->status = zriver_status_manager_v1_get_river_seat_status(
|
||||
seat->m->status_manager, seat->wl_seat);
|
||||
seat->status = zriver_status_manager_v1_get_river_seat_status(seat->m->status_manager, seat->wl_seat);
|
||||
|
||||
if (seat->status == NULL)
|
||||
return;
|
||||
|
||||
zriver_seat_status_v1_add_listener(
|
||||
seat->status, &river_seat_status_listener, seat);
|
||||
zriver_seat_status_v1_add_listener(seat->status, &river_seat_status_listener, seat);
|
||||
}
|
||||
|
||||
static void
|
||||
handle_global(void *data, struct wl_registry *registry,
|
||||
uint32_t name, const char *interface, uint32_t version)
|
||||
handle_global(void *data, struct wl_registry *registry, uint32_t name, const char *interface, uint32_t version)
|
||||
{
|
||||
struct private *m = data;
|
||||
|
||||
|
@ -590,8 +561,7 @@ handle_global(void *data, struct wl_registry *registry,
|
|||
if (!verify_iface_version(interface, version, required))
|
||||
return;
|
||||
|
||||
struct wl_output *wl_output = wl_registry_bind(
|
||||
registry, name, &wl_output_interface, required);
|
||||
struct wl_output *wl_output = wl_registry_bind(registry, name, &wl_output_interface, required);
|
||||
|
||||
if (wl_output == NULL)
|
||||
return;
|
||||
|
@ -605,8 +575,7 @@ handle_global(void *data, struct wl_registry *registry,
|
|||
mtx_lock(&m->mod->lock);
|
||||
tll_push_back(m->outputs, output);
|
||||
update_output(&tll_back(m->outputs));
|
||||
tll_foreach(m->seats, it)
|
||||
update_seat(&it->item);
|
||||
tll_foreach(m->seats, it) update_seat(&it->item);
|
||||
mtx_unlock(&m->mod->lock);
|
||||
}
|
||||
|
||||
|
@ -615,12 +584,10 @@ handle_global(void *data, struct wl_registry *registry,
|
|||
if (!verify_iface_version(interface, version, required))
|
||||
return;
|
||||
|
||||
m->xdg_output_manager = wl_registry_bind(
|
||||
registry, name, &zxdg_output_manager_v1_interface, required);
|
||||
m->xdg_output_manager = wl_registry_bind(registry, name, &zxdg_output_manager_v1_interface, required);
|
||||
|
||||
mtx_lock(&m->mod->lock);
|
||||
tll_foreach(m->outputs, it)
|
||||
update_output(&it->item);
|
||||
tll_foreach(m->outputs, it) update_output(&it->item);
|
||||
mtx_unlock(&m->mod->lock);
|
||||
}
|
||||
|
||||
|
@ -629,8 +596,7 @@ handle_global(void *data, struct wl_registry *registry,
|
|||
if (!verify_iface_version(interface, version, required))
|
||||
return;
|
||||
|
||||
struct wl_seat *wl_seat = wl_registry_bind(
|
||||
registry, name, &wl_seat_interface, required);
|
||||
struct wl_seat *wl_seat = wl_registry_bind(registry, name, &wl_seat_interface, required);
|
||||
|
||||
if (wl_seat == NULL)
|
||||
return;
|
||||
|
@ -649,14 +615,11 @@ handle_global(void *data, struct wl_registry *registry,
|
|||
if (!verify_iface_version(interface, version, required))
|
||||
return;
|
||||
|
||||
m->status_manager = wl_registry_bind(
|
||||
registry, name, &zriver_status_manager_v1_interface, min(version, 4));
|
||||
m->status_manager = wl_registry_bind(registry, name, &zriver_status_manager_v1_interface, min(version, 4));
|
||||
|
||||
mtx_lock(&m->mod->lock);
|
||||
tll_foreach(m->outputs, it)
|
||||
update_output(&it->item);
|
||||
tll_foreach(m->seats, it)
|
||||
update_seat(&it->item);
|
||||
tll_foreach(m->outputs, it) update_output(&it->item);
|
||||
tll_foreach(m->seats, it) update_seat(&it->item);
|
||||
mtx_unlock(&m->mod->lock);
|
||||
}
|
||||
}
|
||||
|
@ -667,7 +630,8 @@ handle_global_remove(void *data, struct wl_registry *registry, uint32_t name)
|
|||
struct private *m = data;
|
||||
|
||||
mtx_lock(&m->mod->lock);
|
||||
tll_foreach(m->outputs, it) {
|
||||
tll_foreach(m->outputs, it)
|
||||
{
|
||||
if (it->item.wl_name == name) {
|
||||
output_destroy(&it->item);
|
||||
tll_remove(m->outputs, it);
|
||||
|
@ -676,7 +640,8 @@ handle_global_remove(void *data, struct wl_registry *registry, uint32_t name)
|
|||
}
|
||||
}
|
||||
|
||||
tll_foreach(m->seats, it) {
|
||||
tll_foreach(m->seats, it)
|
||||
{
|
||||
if (it->item.wl_name == name) {
|
||||
seat_destroy(&it->item);
|
||||
tll_remove(m->seats, it);
|
||||
|
@ -707,9 +672,8 @@ run(struct module *mod)
|
|||
goto out;
|
||||
}
|
||||
|
||||
if ((registry = wl_display_get_registry(display)) == NULL ||
|
||||
wl_registry_add_listener(registry, ®istry_listener, m) != 0)
|
||||
{
|
||||
if ((registry = wl_display_get_registry(display)) == NULL
|
||||
|| wl_registry_add_listener(registry, ®istry_listener, m) != 0) {
|
||||
LOG_ERR("failed to get Wayland registry");
|
||||
goto out;
|
||||
}
|
||||
|
@ -754,11 +718,9 @@ run(struct module *mod)
|
|||
|
||||
ret = 0;
|
||||
out:
|
||||
tll_foreach(m->seats, it)
|
||||
seat_destroy(&it->item);
|
||||
tll_foreach(m->seats, it) seat_destroy(&it->item);
|
||||
tll_free(m->seats);
|
||||
tll_foreach(m->outputs, it)
|
||||
output_destroy(&it->item);
|
||||
tll_foreach(m->outputs, it) output_destroy(&it->item);
|
||||
tll_free(m->outputs);
|
||||
|
||||
if (m->xdg_output_manager != NULL)
|
||||
|
@ -797,10 +759,8 @@ from_conf(const struct yml_node *node, struct conf_inherit inherited)
|
|||
const struct yml_node *title = yml_get_value(node, "title");
|
||||
const struct yml_node *all_monitors = yml_get_value(node, "all-monitors");
|
||||
|
||||
return river_new(
|
||||
conf_to_particle(c, inherited),
|
||||
title != NULL ? conf_to_particle(title, inherited) : NULL,
|
||||
all_monitors != NULL ? yml_value_as_bool(all_monitors) : false);
|
||||
return river_new(conf_to_particle(c, inherited), title != NULL ? conf_to_particle(title, inherited) : NULL,
|
||||
all_monitors != NULL ? yml_value_as_bool(all_monitors) : false);
|
||||
}
|
||||
|
||||
static bool
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <assert.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <libgen.h>
|
||||
#include <signal.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <poll.h>
|
||||
#include <fcntl.h>
|
||||
#include <poll.h>
|
||||
|
||||
#include <sys/stat.h>
|
||||
#include <sys/time.h>
|
||||
|
@ -16,15 +16,16 @@
|
|||
|
||||
#define LOG_MODULE "script"
|
||||
#define LOG_ENABLE_DBG 0
|
||||
#include "../log.h"
|
||||
#include "../config.h"
|
||||
#include "../config-verify.h"
|
||||
#include "../config.h"
|
||||
#include "../log.h"
|
||||
#include "../module.h"
|
||||
#include "../plugin.h"
|
||||
|
||||
static const long min_poll_interval = 250;
|
||||
|
||||
struct private {
|
||||
struct private
|
||||
{
|
||||
char *path;
|
||||
size_t argc;
|
||||
char **argv;
|
||||
|
@ -110,9 +111,8 @@ process_line(struct module *mod, const char *line, size_t len)
|
|||
|
||||
size_t value_len = line + len - _value;
|
||||
|
||||
LOG_DBG("%.*s: name=\"%.*s\", type=\"%.*s\", value=\"%.*s\"",
|
||||
(int)len, line,
|
||||
(int)name_len, _name, (int)type_len, type, (int)value_len, _value);
|
||||
LOG_DBG("%.*s: name=\"%.*s\", type=\"%.*s\", value=\"%.*s\"", (int)len, line, (int)name_len, _name, (int)type_len,
|
||||
type, (int)value_len, _value);
|
||||
|
||||
name = malloc(name_len + 1);
|
||||
memcpy(name, _name, name_len);
|
||||
|
@ -165,16 +165,12 @@ process_line(struct module *mod, const char *line, size_t len)
|
|||
tag = tag_new_float(mod, name, v);
|
||||
}
|
||||
|
||||
else if ((type_len > 6 && memcmp(type, "range:", 6) == 0) ||
|
||||
(type_len > 9 && memcmp(type, "realtime:", 9) == 0))
|
||||
{
|
||||
else if ((type_len > 6 && memcmp(type, "range:", 6) == 0) || (type_len > 9 && memcmp(type, "realtime:", 9) == 0)) {
|
||||
const char *_start = type + 6;
|
||||
const char *split = memchr(_start, '-', type_len - 6);
|
||||
|
||||
if (split == NULL || split == _start || (split + 1) - type >= type_len) {
|
||||
LOG_ERR(
|
||||
"tag range delimiter ('-') not found in type: %.*s",
|
||||
(int)type_len, type);
|
||||
LOG_ERR("tag range delimiter ('-') not found in type: %.*s", (int)type_len, type);
|
||||
goto bad_tag;
|
||||
}
|
||||
|
||||
|
@ -186,9 +182,7 @@ process_line(struct module *mod, const char *line, size_t len)
|
|||
long start = 0;
|
||||
for (size_t i = 0; i < start_len; i++) {
|
||||
if (!(_start[i] >= '0' && _start[i] <= '9')) {
|
||||
LOG_ERR(
|
||||
"tag range start is not an integer: %.*s",
|
||||
(int)start_len, _start);
|
||||
LOG_ERR("tag range start is not an integer: %.*s", (int)start_len, _start);
|
||||
goto bad_tag;
|
||||
}
|
||||
|
||||
|
@ -199,9 +193,7 @@ process_line(struct module *mod, const char *line, size_t len)
|
|||
long end = 0;
|
||||
for (size_t i = 0; i < end_len; i++) {
|
||||
if (!(_end[i] >= '0' && _end[i] <= '9')) {
|
||||
LOG_ERR(
|
||||
"tag range end is not an integer: %.*s",
|
||||
(int)end_len, _end);
|
||||
LOG_ERR("tag range end is not an integer: %.*s", (int)end_len, _end);
|
||||
goto bad_tag;
|
||||
}
|
||||
|
||||
|
@ -223,8 +215,7 @@ process_line(struct module *mod, const char *line, size_t len)
|
|||
}
|
||||
|
||||
if (v < start || v > end) {
|
||||
LOG_ERR("tag value is outside range: %ld <= %ld <= %ld",
|
||||
start, v, end);
|
||||
LOG_ERR("tag value is outside range: %ld <= %ld <= %ld", start, v, end);
|
||||
goto bad_tag;
|
||||
}
|
||||
|
||||
|
@ -326,9 +317,7 @@ data_received(struct module *mod, const char *data, size_t len)
|
|||
process_transaction(mod, transaction_size);
|
||||
|
||||
assert(m->recv_buf.idx >= transaction_size + 1);
|
||||
memmove(m->recv_buf.data,
|
||||
&m->recv_buf.data[transaction_size + 1],
|
||||
m->recv_buf.idx - (transaction_size + 1));
|
||||
memmove(m->recv_buf.data, &m->recv_buf.data[transaction_size + 1], m->recv_buf.idx - (transaction_size + 1));
|
||||
m->recv_buf.idx -= transaction_size + 1;
|
||||
}
|
||||
|
||||
|
@ -432,11 +421,8 @@ execute_script(struct module *mod)
|
|||
sigemptyset(&mask);
|
||||
|
||||
const struct sigaction sa = {.sa_handler = SIG_DFL};
|
||||
if (sigaction(SIGINT, &sa, NULL) < 0 ||
|
||||
sigaction(SIGTERM, &sa, NULL) < 0 ||
|
||||
sigaction(SIGCHLD, &sa, NULL) < 0 ||
|
||||
sigprocmask(SIG_SETMASK, &mask, NULL) < 0)
|
||||
{
|
||||
if (sigaction(SIGINT, &sa, NULL) < 0 || sigaction(SIGTERM, &sa, NULL) < 0 || sigaction(SIGCHLD, &sa, NULL) < 0
|
||||
|| sigprocmask(SIG_SETMASK, &mask, NULL) < 0) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
|
@ -452,9 +438,7 @@ execute_script(struct module *mod)
|
|||
if (dev_null < 0)
|
||||
goto fail;
|
||||
|
||||
if (dup2(dev_null, STDIN_FILENO) < 0 ||
|
||||
dup2(comm_pipe[1], STDOUT_FILENO) < 0)
|
||||
{
|
||||
if (dup2(dev_null, STDIN_FILENO) < 0 || dup2(comm_pipe[1], STDOUT_FILENO) < 0) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
|
@ -533,9 +517,7 @@ execute_script(struct module *mod)
|
|||
usleep(10000);
|
||||
|
||||
pid_t waited_pid;
|
||||
while ((waited_pid = waitpid(
|
||||
pid, NULL, timeout > 0 ? WNOHANG : 0)) == 0)
|
||||
{
|
||||
while ((waited_pid = waitpid(pid, NULL, timeout > 0 ? WNOHANG : 0)) == 0) {
|
||||
struct timeval now;
|
||||
gettimeofday(&now, NULL);
|
||||
|
||||
|
@ -547,7 +529,7 @@ execute_script(struct module *mod)
|
|||
|
||||
/* Don't spinning */
|
||||
thrd_yield();
|
||||
usleep(100000); /* 100ms */
|
||||
usleep(100000); /* 100ms */
|
||||
}
|
||||
|
||||
if (waited_pid == pid) {
|
||||
|
@ -580,7 +562,7 @@ run(struct module *mod)
|
|||
break;
|
||||
|
||||
struct timeval now;
|
||||
if (gettimeofday(&now, NULL) < 0) {
|
||||
if (gettimeofday(&now, NULL) < 0) {
|
||||
LOG_ERRNO("failed to get current time");
|
||||
break;
|
||||
}
|
||||
|
@ -631,8 +613,7 @@ run(struct module *mod)
|
|||
}
|
||||
|
||||
static struct module *
|
||||
script_new(char *path, size_t argc, const char *const argv[static argc],
|
||||
int poll_interval, struct particle *_content)
|
||||
script_new(char *path, size_t argc, const char *const argv[static argc], int poll_interval, struct particle *_content)
|
||||
{
|
||||
struct private *m = calloc(1, sizeof(*m));
|
||||
m->path = path;
|
||||
|
@ -665,10 +646,7 @@ from_conf(const struct yml_node *node, struct conf_inherit inherited)
|
|||
|
||||
if (args != NULL) {
|
||||
size_t i = 0;
|
||||
for (struct yml_list_iter iter = yml_list_iter(args);
|
||||
iter.node != NULL;
|
||||
yml_list_next(&iter), i++)
|
||||
{
|
||||
for (struct yml_list_iter iter = yml_list_iter(args); iter.node != NULL; yml_list_next(&iter), i++) {
|
||||
argv[i] = yml_value_as_string(iter.node);
|
||||
}
|
||||
}
|
||||
|
@ -691,10 +669,8 @@ from_conf(const struct yml_node *node, struct conf_inherit inherited)
|
|||
} else
|
||||
path = strdup(yml_path);
|
||||
|
||||
return script_new(
|
||||
path, argc, argv,
|
||||
poll_interval != NULL ? yml_value_as_int(poll_interval) : 0,
|
||||
conf_to_particle(c, inherited));
|
||||
return script_new(path, argc, argv, poll_interval != NULL ? yml_value_as_int(poll_interval) : 0,
|
||||
conf_to_particle(c, inherited));
|
||||
}
|
||||
|
||||
static bool
|
||||
|
@ -709,8 +685,7 @@ conf_verify_path(keychain_t *chain, const struct yml_node *node)
|
|||
const bool is_absolute = path[0] == '/';
|
||||
|
||||
if (!is_tilde && !is_absolute) {
|
||||
LOG_ERR("%s: path must either be absolute, or begin with '~/'",
|
||||
conf_err_prefix(chain, node));
|
||||
LOG_ERR("%s: path must either be absolute, or begin with '~/'", conf_err_prefix(chain, node));
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -730,8 +705,7 @@ conf_verify_poll_interval(keychain_t *chain, const struct yml_node *node)
|
|||
return false;
|
||||
|
||||
if (yml_value_as_int(node) < min_poll_interval) {
|
||||
LOG_ERR("%s: interval value cannot be less than %ldms",
|
||||
conf_err_prefix(chain, node), min_poll_interval);
|
||||
LOG_ERR("%s: interval value cannot be less than %ldms", conf_err_prefix(chain, node), min_poll_interval);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -3,15 +3,15 @@
|
|||
|
||||
#define LOG_MODULE "sway-xkb"
|
||||
#define LOG_ENABLE_DBG 0
|
||||
#include "../log.h"
|
||||
#include "../bar/bar.h"
|
||||
#include "../config-verify.h"
|
||||
#include "../config.h"
|
||||
#include "../log.h"
|
||||
#include "../particles/dynlist.h"
|
||||
#include "../plugin.h"
|
||||
|
||||
#include "i3-ipc.h"
|
||||
#include "i3-common.h"
|
||||
#include "i3-ipc.h"
|
||||
|
||||
#define max(x, y) ((x) > (y) ? (x) : (y))
|
||||
|
||||
|
@ -21,7 +21,8 @@ struct input {
|
|||
char *layout;
|
||||
};
|
||||
|
||||
struct private {
|
||||
struct private
|
||||
{
|
||||
struct particle *template;
|
||||
int left_spacing;
|
||||
int right_spacing;
|
||||
|
@ -89,8 +90,7 @@ content(struct module *mod)
|
|||
}
|
||||
|
||||
mtx_unlock(&mod->lock);
|
||||
return dynlist_exposable_new(
|
||||
particles, m->num_existing_inputs, m->left_spacing, m->right_spacing);
|
||||
return dynlist_exposable_new(particles, m->num_existing_inputs, m->left_spacing, m->right_spacing);
|
||||
}
|
||||
|
||||
static bool
|
||||
|
@ -121,8 +121,7 @@ handle_input_reply(int sock, int type, const struct json_object *json, void *_mo
|
|||
struct input *input = NULL;
|
||||
for (size_t i = 0; i < m->num_inputs; i++) {
|
||||
struct input *maybe_input = &m->inputs[i];
|
||||
if (strcmp(maybe_input->identifier, id) == 0 && !maybe_input->exists)
|
||||
{
|
||||
if (strcmp(maybe_input->identifier, id) == 0 && !maybe_input->exists) {
|
||||
input = maybe_input;
|
||||
|
||||
LOG_DBG("adding: %s", id);
|
||||
|
@ -142,8 +141,7 @@ handle_input_reply(int sock, int type, const struct json_object *json, void *_mo
|
|||
|
||||
/* Get current/active layout */
|
||||
struct json_object *layout;
|
||||
if (!json_object_object_get_ex(
|
||||
obj, "xkb_active_layout_name", &layout))
|
||||
if (!json_object_object_get_ex(obj, "xkb_active_layout_name", &layout))
|
||||
return false;
|
||||
|
||||
const char *new_layout_str = json_object_get_string(layout);
|
||||
|
@ -240,8 +238,7 @@ handle_input_event(int sock, int type, const struct json_object *json, void *_mo
|
|||
|
||||
/* Get current/active layout */
|
||||
struct json_object *layout;
|
||||
if (!json_object_object_get_ex(
|
||||
obj, "xkb_active_layout_name", &layout))
|
||||
if (!json_object_object_get_ex(obj, "xkb_active_layout_name", &layout))
|
||||
return false;
|
||||
|
||||
const char *new_layout_str = json_object_get_string(layout);
|
||||
|
@ -309,8 +306,8 @@ run(struct module *mod)
|
|||
}
|
||||
|
||||
static struct module *
|
||||
sway_xkb_new(struct particle *template, const char *identifiers[],
|
||||
size_t num_identifiers, int left_spacing, int right_spacing)
|
||||
sway_xkb_new(struct particle *template, const char *identifiers[], size_t num_identifiers, int left_spacing,
|
||||
int right_spacing)
|
||||
{
|
||||
struct private *m = calloc(1, sizeof(*m));
|
||||
m->template = template;
|
||||
|
@ -343,40 +340,32 @@ from_conf(const struct yml_node *node, struct conf_inherit inherited)
|
|||
const struct yml_node *left_spacing = yml_get_value(node, "left-spacing");
|
||||
const struct yml_node *right_spacing = yml_get_value(node, "right-spacing");
|
||||
|
||||
int left = spacing != NULL ? yml_value_as_int(spacing) :
|
||||
left_spacing != NULL ? yml_value_as_int(left_spacing) : 0;
|
||||
int right = spacing != NULL ? yml_value_as_int(spacing) :
|
||||
right_spacing != NULL ? yml_value_as_int(right_spacing) : 0;
|
||||
int left = spacing != NULL ? yml_value_as_int(spacing) : left_spacing != NULL ? yml_value_as_int(left_spacing) : 0;
|
||||
int right = spacing != NULL ? yml_value_as_int(spacing)
|
||||
: right_spacing != NULL ? yml_value_as_int(right_spacing)
|
||||
: 0;
|
||||
|
||||
const struct yml_node *ids = yml_get_value(node, "identifiers");
|
||||
const size_t num_ids = yml_list_length(ids);
|
||||
const char *identifiers[num_ids];
|
||||
|
||||
size_t i = 0;
|
||||
for (struct yml_list_iter it = yml_list_iter(ids);
|
||||
it.node != NULL;
|
||||
yml_list_next(&it), i++)
|
||||
{
|
||||
for (struct yml_list_iter it = yml_list_iter(ids); it.node != NULL; yml_list_next(&it), i++) {
|
||||
identifiers[i] = yml_value_as_string(it.node);
|
||||
}
|
||||
|
||||
return sway_xkb_new(
|
||||
conf_to_particle(c, inherited), identifiers, num_ids, left, right);
|
||||
return sway_xkb_new(conf_to_particle(c, inherited), identifiers, num_ids, left, right);
|
||||
}
|
||||
|
||||
static bool
|
||||
verify_identifiers(keychain_t *chain, const struct yml_node *node)
|
||||
{
|
||||
if (!yml_is_list(node)) {
|
||||
LOG_ERR("%s: identifiers must be a list of strings",
|
||||
conf_err_prefix(chain, node));
|
||||
LOG_ERR("%s: identifiers must be a list of strings", conf_err_prefix(chain, node));
|
||||
return false;
|
||||
}
|
||||
|
||||
for (struct yml_list_iter it = yml_list_iter(node);
|
||||
it.node != NULL;
|
||||
yml_list_next(&it))
|
||||
{
|
||||
for (struct yml_list_iter it = yml_list_iter(node); it.node != NULL; yml_list_next(&it)) {
|
||||
if (!conf_verify_string(chain, it.node))
|
||||
return false;
|
||||
}
|
||||
|
@ -404,5 +393,5 @@ const struct module_iface module_sway_xkb_iface = {
|
|||
};
|
||||
|
||||
#if defined(CORE_PLUGINS_AS_SHARED_LIBRARIES)
|
||||
extern const struct module_iface iface __attribute__((weak, alias("module_sway_xkb_iface"))) ;
|
||||
extern const struct module_iface iface __attribute__((weak, alias("module_sway_xkb_iface")));
|
||||
#endif
|
||||
|
|
145
modules/xkb.c
145
modules/xkb.c
|
@ -1,7 +1,7 @@
|
|||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <poll.h>
|
||||
|
||||
|
@ -10,10 +10,10 @@
|
|||
|
||||
#define LOG_MODULE "xkb"
|
||||
#define LOG_ENABLE_DBG 0
|
||||
#include "../log.h"
|
||||
#include "../bar/bar.h"
|
||||
#include "../config.h"
|
||||
#include "../config-verify.h"
|
||||
#include "../config.h"
|
||||
#include "../log.h"
|
||||
#include "../plugin.h"
|
||||
#include "../xcb.h"
|
||||
|
||||
|
@ -32,7 +32,8 @@ struct indicators {
|
|||
char **names;
|
||||
};
|
||||
|
||||
struct private {
|
||||
struct private
|
||||
{
|
||||
struct particle *label;
|
||||
struct indicators indicators;
|
||||
struct layouts layouts;
|
||||
|
@ -117,10 +118,8 @@ xkb_enable(xcb_connection_t *conn)
|
|||
{
|
||||
xcb_generic_error_t *err;
|
||||
|
||||
xcb_xkb_use_extension_cookie_t cookie = xcb_xkb_use_extension(
|
||||
conn, XCB_XKB_MAJOR_VERSION, XCB_XKB_MINOR_VERSION);
|
||||
xcb_xkb_use_extension_reply_t *reply = xcb_xkb_use_extension_reply(
|
||||
conn, cookie, &err);
|
||||
xcb_xkb_use_extension_cookie_t cookie = xcb_xkb_use_extension(conn, XCB_XKB_MAJOR_VERSION, XCB_XKB_MINOR_VERSION);
|
||||
xcb_xkb_use_extension_reply_t *reply = xcb_xkb_use_extension_reply(conn, cookie, &err);
|
||||
|
||||
if (err != NULL) {
|
||||
LOG_ERR("failed to query for XKB extension: %s", xcb_error(err));
|
||||
|
@ -142,8 +141,7 @@ xkb_enable(xcb_connection_t *conn)
|
|||
static int
|
||||
get_xkb_event_base(xcb_connection_t *conn)
|
||||
{
|
||||
const struct xcb_query_extension_reply_t *reply = xcb_get_extension_data(
|
||||
conn, &xcb_xkb_id);
|
||||
const struct xcb_query_extension_reply_t *reply = xcb_get_extension_data(conn, &xcb_xkb_id);
|
||||
|
||||
if (reply == NULL) {
|
||||
LOG_ERR("failed to get XKB extension data");
|
||||
|
@ -159,19 +157,14 @@ get_xkb_event_base(xcb_connection_t *conn)
|
|||
}
|
||||
|
||||
static bool
|
||||
get_layouts_and_indicators(xcb_connection_t *conn, struct layouts *layouts,
|
||||
struct indicators *indicators)
|
||||
get_layouts_and_indicators(xcb_connection_t *conn, struct layouts *layouts, struct indicators *indicators)
|
||||
{
|
||||
xcb_generic_error_t *err;
|
||||
xcb_xkb_get_names_cookie_t cookie = xcb_xkb_get_names(
|
||||
conn,
|
||||
XCB_XKB_ID_USE_CORE_KBD,
|
||||
XCB_XKB_NAME_DETAIL_GROUP_NAMES |
|
||||
XCB_XKB_NAME_DETAIL_SYMBOLS |
|
||||
XCB_XKB_NAME_DETAIL_INDICATOR_NAMES);
|
||||
xcb_xkb_get_names_cookie_t cookie = xcb_xkb_get_names(conn, XCB_XKB_ID_USE_CORE_KBD,
|
||||
XCB_XKB_NAME_DETAIL_GROUP_NAMES | XCB_XKB_NAME_DETAIL_SYMBOLS
|
||||
| XCB_XKB_NAME_DETAIL_INDICATOR_NAMES);
|
||||
|
||||
xcb_xkb_get_names_reply_t *reply = xcb_xkb_get_names_reply(
|
||||
conn, cookie, &err);
|
||||
xcb_xkb_get_names_reply_t *reply = xcb_xkb_get_names_reply(conn, cookie, &err);
|
||||
|
||||
if (err != NULL) {
|
||||
LOG_ERR("failed to get layouts and indicators: %s", xcb_error(err));
|
||||
|
@ -181,22 +174,18 @@ get_layouts_and_indicators(xcb_connection_t *conn, struct layouts *layouts,
|
|||
|
||||
xcb_xkb_get_names_value_list_t vlist;
|
||||
void *buf = xcb_xkb_get_names_value_list(reply);
|
||||
xcb_xkb_get_names_value_list_unpack(
|
||||
buf, reply->nTypes, reply->indicators, reply->virtualMods,
|
||||
reply->groupNames, reply->nKeys, reply->nKeyAliases,
|
||||
reply->nRadioGroups, reply->which, &vlist);
|
||||
xcb_xkb_get_names_value_list_unpack(buf, reply->nTypes, reply->indicators, reply->virtualMods, reply->groupNames,
|
||||
reply->nKeys, reply->nKeyAliases, reply->nRadioGroups, reply->which, &vlist);
|
||||
|
||||
/* Number of groups (aka layouts) */
|
||||
layouts->count = xcb_xkb_get_names_value_list_groups_length(reply, &vlist);
|
||||
layouts->layouts = calloc(layouts->count, sizeof(layouts->layouts[0]));
|
||||
|
||||
/* Number of indicators */
|
||||
indicators->count = xcb_xkb_get_names_value_list_indicator_names_length(
|
||||
reply, &vlist);
|
||||
indicators->count = xcb_xkb_get_names_value_list_indicator_names_length(reply, &vlist);
|
||||
indicators->names = calloc(indicators->count, sizeof(indicators->names[0]));
|
||||
|
||||
xcb_get_atom_name_cookie_t symbols_name_cookie = xcb_get_atom_name(
|
||||
conn, vlist.symbolsName);
|
||||
xcb_get_atom_name_cookie_t symbols_name_cookie = xcb_get_atom_name(conn, vlist.symbolsName);
|
||||
|
||||
xcb_get_atom_name_cookie_t group_name_cookies[layouts->count];
|
||||
for (size_t i = 0; i < layouts->count; i++)
|
||||
|
@ -209,17 +198,14 @@ get_layouts_and_indicators(xcb_connection_t *conn, struct layouts *layouts,
|
|||
char *symbols = NULL;
|
||||
|
||||
/* Get layout short names (e.g. "us") */
|
||||
xcb_get_atom_name_reply_t *atom_name = xcb_get_atom_name_reply(
|
||||
conn, symbols_name_cookie, &err);
|
||||
xcb_get_atom_name_reply_t *atom_name = xcb_get_atom_name_reply(conn, symbols_name_cookie, &err);
|
||||
if (err != NULL) {
|
||||
LOG_ERR("failed to get 'symbols' atom name: %s", xcb_error(err));
|
||||
free(err);
|
||||
goto err;
|
||||
}
|
||||
|
||||
symbols = strndup(
|
||||
xcb_get_atom_name_name(atom_name),
|
||||
xcb_get_atom_name_name_length(atom_name));
|
||||
symbols = strndup(xcb_get_atom_name_name(atom_name), xcb_get_atom_name_name_length(atom_name));
|
||||
LOG_DBG("symbols: %s", symbols);
|
||||
free(atom_name);
|
||||
|
||||
|
@ -232,9 +218,7 @@ get_layouts_and_indicators(xcb_connection_t *conn, struct layouts *layouts,
|
|||
goto err;
|
||||
}
|
||||
|
||||
layouts->layouts[i].name = strndup(
|
||||
xcb_get_atom_name_name(atom_name),
|
||||
xcb_get_atom_name_name_length(atom_name));
|
||||
layouts->layouts[i].name = strndup(xcb_get_atom_name_name(atom_name), xcb_get_atom_name_name_length(atom_name));
|
||||
|
||||
LOG_DBG("layout #%zd: long name: %s", i, layouts->layouts[i].name);
|
||||
free(atom_name);
|
||||
|
@ -249,9 +233,7 @@ get_layouts_and_indicators(xcb_connection_t *conn, struct layouts *layouts,
|
|||
goto err;
|
||||
}
|
||||
|
||||
indicators->names[i] = strndup(
|
||||
xcb_get_atom_name_name(atom_name),
|
||||
xcb_get_atom_name_name_length(atom_name));
|
||||
indicators->names[i] = strndup(xcb_get_atom_name_name(atom_name), xcb_get_atom_name_name_length(atom_name));
|
||||
|
||||
LOG_DBG("indicator #%zd: %s", i, indicators->names[i]);
|
||||
free(atom_name);
|
||||
|
@ -259,8 +241,7 @@ get_layouts_and_indicators(xcb_connection_t *conn, struct layouts *layouts,
|
|||
|
||||
/* e.g. pc+us+inet(evdev)+group(..) */
|
||||
size_t layout_idx = 0;
|
||||
for (char *tok_ctx = NULL, *tok = strtok_r(symbols, "+", &tok_ctx);
|
||||
tok != NULL;
|
||||
for (char *tok_ctx = NULL, *tok = strtok_r(symbols, "+", &tok_ctx); tok != NULL;
|
||||
tok = strtok_r(NULL, "+", &tok_ctx)) {
|
||||
|
||||
char *fname = strtok(tok, "()");
|
||||
|
@ -279,8 +260,7 @@ get_layouts_and_indicators(xcb_connection_t *conn, struct layouts *layouts,
|
|||
continue;
|
||||
|
||||
if (layout_idx >= layouts->count) {
|
||||
LOG_ERR("layout vs group name count mismatch: %zd > %zd",
|
||||
layout_idx + 1, layouts->count);
|
||||
LOG_ERR("layout vs group name count mismatch: %zd > %zd", layout_idx + 1, layouts->count);
|
||||
goto err;
|
||||
}
|
||||
|
||||
|
@ -290,8 +270,7 @@ get_layouts_and_indicators(xcb_connection_t *conn, struct layouts *layouts,
|
|||
}
|
||||
|
||||
if (layout_idx != layouts->count) {
|
||||
LOG_ERR("layout vs group name count mismatch: %zd != %zd",
|
||||
layout_idx, layouts->count);
|
||||
LOG_ERR("layout vs group name count mismatch: %zd != %zd", layout_idx, layouts->count);
|
||||
goto err;
|
||||
}
|
||||
|
||||
|
@ -312,10 +291,8 @@ get_current_layout(xcb_connection_t *conn)
|
|||
{
|
||||
xcb_generic_error_t *err;
|
||||
|
||||
xcb_xkb_get_state_cookie_t cookie = xcb_xkb_get_state(
|
||||
conn, XCB_XKB_ID_USE_CORE_KBD);
|
||||
xcb_xkb_get_state_reply_t *reply = xcb_xkb_get_state_reply(
|
||||
conn, cookie, &err);
|
||||
xcb_xkb_get_state_cookie_t cookie = xcb_xkb_get_state(conn, XCB_XKB_ID_USE_CORE_KBD);
|
||||
xcb_xkb_get_state_reply_t *reply = xcb_xkb_get_state_reply(conn, cookie, &err);
|
||||
|
||||
if (err != NULL) {
|
||||
LOG_ERR("failed to get XKB state: %s", xcb_error(err));
|
||||
|
@ -332,10 +309,8 @@ static uint32_t
|
|||
get_indicator_state(xcb_connection_t *conn)
|
||||
{
|
||||
xcb_generic_error_t *err;
|
||||
xcb_xkb_get_indicator_state_cookie_t cookie = xcb_xkb_get_indicator_state(
|
||||
conn, XCB_XKB_ID_USE_CORE_KBD);
|
||||
xcb_xkb_get_indicator_state_reply_t *reply = xcb_xkb_get_indicator_state_reply(
|
||||
conn, cookie, &err);
|
||||
xcb_xkb_get_indicator_state_cookie_t cookie = xcb_xkb_get_indicator_state(conn, XCB_XKB_ID_USE_CORE_KBD);
|
||||
xcb_xkb_get_indicator_state_reply_t *reply = xcb_xkb_get_indicator_state_reply(conn, cookie, &err);
|
||||
|
||||
if (err != NULL) {
|
||||
LOG_ERR("failed to get indicator state: %s", xcb_error(err));
|
||||
|
@ -353,23 +328,14 @@ get_indicator_state(xcb_connection_t *conn)
|
|||
static bool
|
||||
register_for_events(xcb_connection_t *conn)
|
||||
{
|
||||
xcb_void_cookie_t cookie = xcb_xkb_select_events_checked(
|
||||
conn,
|
||||
XCB_XKB_ID_USE_CORE_KBD,
|
||||
(
|
||||
XCB_XKB_EVENT_TYPE_NEW_KEYBOARD_NOTIFY |
|
||||
XCB_XKB_EVENT_TYPE_STATE_NOTIFY |
|
||||
XCB_XKB_EVENT_TYPE_MAP_NOTIFY |
|
||||
XCB_XKB_EVENT_TYPE_INDICATOR_STATE_NOTIFY
|
||||
),
|
||||
0,
|
||||
(
|
||||
XCB_XKB_EVENT_TYPE_NEW_KEYBOARD_NOTIFY |
|
||||
XCB_XKB_EVENT_TYPE_STATE_NOTIFY |
|
||||
XCB_XKB_EVENT_TYPE_MAP_NOTIFY |
|
||||
XCB_XKB_EVENT_TYPE_INDICATOR_STATE_NOTIFY
|
||||
),
|
||||
0, 0, NULL);
|
||||
xcb_void_cookie_t cookie
|
||||
= xcb_xkb_select_events_checked(conn, XCB_XKB_ID_USE_CORE_KBD,
|
||||
(XCB_XKB_EVENT_TYPE_NEW_KEYBOARD_NOTIFY | XCB_XKB_EVENT_TYPE_STATE_NOTIFY
|
||||
| XCB_XKB_EVENT_TYPE_MAP_NOTIFY | XCB_XKB_EVENT_TYPE_INDICATOR_STATE_NOTIFY),
|
||||
0,
|
||||
(XCB_XKB_EVENT_TYPE_NEW_KEYBOARD_NOTIFY | XCB_XKB_EVENT_TYPE_STATE_NOTIFY
|
||||
| XCB_XKB_EVENT_TYPE_MAP_NOTIFY | XCB_XKB_EVENT_TYPE_INDICATOR_STATE_NOTIFY),
|
||||
0, 0, NULL);
|
||||
|
||||
xcb_generic_error_t *err = xcb_request_check(conn, cookie);
|
||||
if (err != NULL) {
|
||||
|
@ -393,10 +359,7 @@ event_loop(struct module *mod, xcb_connection_t *conn, int xkb_event_base)
|
|||
assert(xcb_fd >= 0);
|
||||
|
||||
while (!has_error) {
|
||||
struct pollfd pfds[] = {
|
||||
{.fd = mod->abort_fd, .events = POLLIN },
|
||||
{.fd = xcb_fd, .events = POLLIN | POLLHUP }
|
||||
};
|
||||
struct pollfd pfds[] = {{.fd = mod->abort_fd, .events = POLLIN}, {.fd = xcb_fd, .events = POLLIN | POLLHUP}};
|
||||
|
||||
/* Use poll() since xcb_wait_for_events() doesn't return on signals */
|
||||
if (poll(pfds, sizeof(pfds) / sizeof(pfds[0]), -1) < 0) {
|
||||
|
@ -425,9 +388,7 @@ event_loop(struct module *mod, xcb_connection_t *conn, int xkb_event_base)
|
|||
* not for long though...
|
||||
*/
|
||||
|
||||
for (xcb_generic_event_t *_evt = xcb_wait_for_event(conn);
|
||||
_evt != NULL;
|
||||
_evt = xcb_poll_for_event(conn)) {
|
||||
for (xcb_generic_event_t *_evt = xcb_wait_for_event(conn); _evt != NULL; _evt = xcb_poll_for_event(conn)) {
|
||||
|
||||
if (_evt->response_type != xkb_event_base) {
|
||||
LOG_WARN("non-XKB event ignored: %d", _evt->response_type);
|
||||
|
@ -435,7 +396,7 @@ event_loop(struct module *mod, xcb_connection_t *conn, int xkb_event_base)
|
|||
continue;
|
||||
}
|
||||
|
||||
switch(_evt->pad0) {
|
||||
switch (_evt->pad0) {
|
||||
default:
|
||||
LOG_WARN("unimplemented XKB event: %d", _evt->pad0);
|
||||
break;
|
||||
|
@ -463,7 +424,7 @@ event_loop(struct module *mod, xcb_connection_t *conn, int xkb_event_base)
|
|||
mtx_unlock(&mod->lock);
|
||||
bar->refresh(bar);
|
||||
} else {
|
||||
/* Can happen while transitioning to a new map */
|
||||
/* Can happen while transitioning to a new map */
|
||||
free_layouts(layouts);
|
||||
free_indicators(indicators);
|
||||
}
|
||||
|
@ -472,8 +433,7 @@ event_loop(struct module *mod, xcb_connection_t *conn, int xkb_event_base)
|
|||
}
|
||||
|
||||
case XCB_XKB_STATE_NOTIFY: {
|
||||
const xcb_xkb_state_notify_event_t *evt =
|
||||
(const xcb_xkb_state_notify_event_t *)_evt;
|
||||
const xcb_xkb_state_notify_event_t *evt = (const xcb_xkb_state_notify_event_t *)_evt;
|
||||
|
||||
if (evt->changed & XCB_XKB_STATE_PART_GROUP_STATE) {
|
||||
mtx_lock(&mod->lock);
|
||||
|
@ -490,8 +450,8 @@ event_loop(struct module *mod, xcb_connection_t *conn, int xkb_event_base)
|
|||
break;
|
||||
|
||||
case XCB_XKB_INDICATOR_STATE_NOTIFY: {
|
||||
const xcb_xkb_indicator_state_notify_event_t *evt =
|
||||
(const xcb_xkb_indicator_state_notify_event_t *)_evt;
|
||||
const xcb_xkb_indicator_state_notify_event_t *evt
|
||||
= (const xcb_xkb_indicator_state_notify_event_t *)_evt;
|
||||
|
||||
#if 0
|
||||
size_t idx = __builtin_ctz(evt->stateChanged);
|
||||
|
@ -508,8 +468,7 @@ event_loop(struct module *mod, xcb_connection_t *conn, int xkb_event_base)
|
|||
continue;
|
||||
|
||||
bool enabled = (evt->state >> i) & 1;
|
||||
LOG_DBG("%s: %s", m->indicators.names[i],
|
||||
enabled ? "enabled" : "disabled");
|
||||
LOG_DBG("%s: %s", m->indicators.names[i], enabled ? "enabled" : "disabled");
|
||||
|
||||
const char *name = m->indicators.names[i];
|
||||
bool is_caps = strcasecmp(name, "caps lock") == 0;
|
||||
|
@ -609,18 +568,12 @@ talk_to_xkb(struct module *mod, xcb_connection_t *conn)
|
|||
size_t idx = 0;
|
||||
|
||||
for (size_t i = 0; i < layouts.count; i++) {
|
||||
idx += snprintf(&buf[idx], sizeof(buf) - idx, "%s%s (%s)%s",
|
||||
i == m->current ? "*" : "",
|
||||
layouts.layouts[i].name,
|
||||
layouts.layouts[i].symbol,
|
||||
i + 1 < layouts.count ? ", " : "");
|
||||
idx += snprintf(&buf[idx], sizeof(buf) - idx, "%s%s (%s)%s", i == m->current ? "*" : "",
|
||||
layouts.layouts[i].name, layouts.layouts[i].symbol, i + 1 < layouts.count ? ", " : "");
|
||||
}
|
||||
|
||||
LOG_INFO("layouts: %s, caps-lock:%s, num-lock:%s, scroll-lock:%s",
|
||||
buf,
|
||||
caps_lock ? "on" : "off",
|
||||
num_lock ? "on" : "off",
|
||||
scroll_lock ? "on" : "off");
|
||||
LOG_INFO("layouts: %s, caps-lock:%s, num-lock:%s, scroll-lock:%s", buf, caps_lock ? "on" : "off",
|
||||
num_lock ? "on" : "off", scroll_lock ? "on" : "off");
|
||||
}
|
||||
|
||||
mtx_lock(&mod->lock);
|
||||
|
|
|
@ -1,29 +1,30 @@
|
|||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <libgen.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <threads.h>
|
||||
#include <libgen.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <poll.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <xcb/xcb.h>
|
||||
#include <xcb/xcb_aux.h>
|
||||
#include <xcb/xcb_event.h>
|
||||
|
||||
#define LOG_MODULE "xwindow"
|
||||
#include "../log.h"
|
||||
#include "../bar/bar.h"
|
||||
#include "../config.h"
|
||||
#include "../config-verify.h"
|
||||
#include "../config.h"
|
||||
#include "../log.h"
|
||||
#include "../plugin.h"
|
||||
#include "../xcb.h"
|
||||
|
||||
struct private {
|
||||
struct private
|
||||
{
|
||||
/* Accessed from bar thread only */
|
||||
struct particle *label;
|
||||
|
||||
|
@ -48,23 +49,19 @@ static void
|
|||
update_active_window(struct private *m)
|
||||
{
|
||||
if (m->active_win != 0) {
|
||||
xcb_void_cookie_t c = xcb_change_window_attributes_checked(
|
||||
m->conn, m->active_win, XCB_CW_EVENT_MASK,
|
||||
(const uint32_t []){XCB_EVENT_MASK_NO_EVENT});
|
||||
xcb_void_cookie_t c = xcb_change_window_attributes_checked(m->conn, m->active_win, XCB_CW_EVENT_MASK,
|
||||
(const uint32_t[]){XCB_EVENT_MASK_NO_EVENT});
|
||||
|
||||
xcb_generic_error_t *e = xcb_request_check(m->conn, c);
|
||||
if (e != NULL) {
|
||||
LOG_DBG(
|
||||
"failed to de-register events on previous active window: %s",
|
||||
xcb_error(e));
|
||||
LOG_DBG("failed to de-register events on previous active window: %s", xcb_error(e));
|
||||
free(e);
|
||||
}
|
||||
|
||||
m->active_win = 0;
|
||||
}
|
||||
|
||||
xcb_get_property_cookie_t c = xcb_get_property(
|
||||
m->conn, 0, m->root_win, _NET_ACTIVE_WINDOW, XCB_ATOM_WINDOW, 0, 32);
|
||||
xcb_get_property_cookie_t c = xcb_get_property(m->conn, 0, m->root_win, _NET_ACTIVE_WINDOW, XCB_ATOM_WINDOW, 0, 32);
|
||||
|
||||
xcb_generic_error_t *e;
|
||||
xcb_get_property_reply_t *r = xcb_get_property_reply(m->conn, c, &e);
|
||||
|
@ -86,9 +83,8 @@ update_active_window(struct private *m)
|
|||
free(r);
|
||||
|
||||
if (m->active_win != 0) {
|
||||
xcb_change_window_attributes(
|
||||
m->conn, m->active_win, XCB_CW_EVENT_MASK,
|
||||
(const uint32_t []){XCB_EVENT_MASK_PROPERTY_CHANGE});
|
||||
xcb_change_window_attributes(m->conn, m->active_win, XCB_CW_EVENT_MASK,
|
||||
(const uint32_t[]){XCB_EVENT_MASK_PROPERTY_CHANGE});
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -105,8 +101,7 @@ update_application(struct module *mod)
|
|||
if (m->active_win == 0)
|
||||
return;
|
||||
|
||||
xcb_get_property_cookie_t c = xcb_get_property(
|
||||
m->conn, 0, m->active_win, _NET_WM_PID, XCB_ATOM_CARDINAL, 0, 32);
|
||||
xcb_get_property_cookie_t c = xcb_get_property(m->conn, 0, m->active_win, _NET_WM_PID, XCB_ATOM_CARDINAL, 0, 32);
|
||||
|
||||
xcb_generic_error_t *e;
|
||||
xcb_get_property_reply_t *r = xcb_get_property_reply(m->conn, c, &e);
|
||||
|
@ -164,12 +159,11 @@ update_title(struct module *mod)
|
|||
if (m->active_win == 0)
|
||||
return;
|
||||
|
||||
xcb_get_property_cookie_t c1 = xcb_get_property(
|
||||
m->conn, 0, m->active_win, _NET_WM_VISIBLE_NAME, UTF8_STRING, 0, 1000);
|
||||
xcb_get_property_cookie_t c2 = xcb_get_property(
|
||||
m->conn, 0, m->active_win, _NET_WM_NAME, UTF8_STRING, 0, 1000);
|
||||
xcb_get_property_cookie_t c3 = xcb_get_property(
|
||||
m->conn, 0, m->active_win, XCB_ATOM_WM_NAME, XCB_ATOM_STRING, 0, 1000);
|
||||
xcb_get_property_cookie_t c1
|
||||
= xcb_get_property(m->conn, 0, m->active_win, _NET_WM_VISIBLE_NAME, UTF8_STRING, 0, 1000);
|
||||
xcb_get_property_cookie_t c2 = xcb_get_property(m->conn, 0, m->active_win, _NET_WM_NAME, UTF8_STRING, 0, 1000);
|
||||
xcb_get_property_cookie_t c3
|
||||
= xcb_get_property(m->conn, 0, m->active_win, XCB_ATOM_WM_NAME, XCB_ATOM_STRING, 0, 1000);
|
||||
|
||||
xcb_generic_error_t *e1, *e2, *e3;
|
||||
xcb_get_property_reply_t *r1 = xcb_get_property_reply(m->conn, c1, &e1);
|
||||
|
@ -207,7 +201,7 @@ update_title(struct module *mod)
|
|||
free(r1);
|
||||
free(r2);
|
||||
free(r3);
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
run(struct module *mod)
|
||||
|
@ -227,19 +221,16 @@ run(struct module *mod)
|
|||
|
||||
/* Need a window(?) to be able to process events */
|
||||
m->monitor_win = xcb_generate_id(m->conn);
|
||||
xcb_create_window(m->conn, screen->root_depth, m->monitor_win, screen->root,
|
||||
-1, -1, 1, 1,
|
||||
0,
|
||||
XCB_WINDOW_CLASS_INPUT_OUTPUT, screen->root_visual,
|
||||
XCB_CW_OVERRIDE_REDIRECT, (const uint32_t []){1});
|
||||
xcb_create_window(m->conn, screen->root_depth, m->monitor_win, screen->root, -1, -1, 1, 1, 0,
|
||||
XCB_WINDOW_CLASS_INPUT_OUTPUT, screen->root_visual, XCB_CW_OVERRIDE_REDIRECT,
|
||||
(const uint32_t[]){1});
|
||||
|
||||
xcb_map_window(m->conn, m->monitor_win);
|
||||
|
||||
/* Register for property changes on root window. This allows us to
|
||||
* catch e.g. window switches etc */
|
||||
xcb_change_window_attributes(
|
||||
m->conn, screen->root, XCB_CW_EVENT_MASK,
|
||||
(const uint32_t []){XCB_EVENT_MASK_PROPERTY_CHANGE});
|
||||
xcb_change_window_attributes(m->conn, screen->root, XCB_CW_EVENT_MASK,
|
||||
(const uint32_t[]){XCB_EVENT_MASK_PROPERTY_CHANGE});
|
||||
|
||||
xcb_flush(m->conn);
|
||||
|
||||
|
@ -252,8 +243,7 @@ run(struct module *mod)
|
|||
|
||||
int xcb_fd = xcb_get_file_descriptor(m->conn);
|
||||
while (true) {
|
||||
struct pollfd fds[] = {{.fd = mod->abort_fd, .events = POLLIN},
|
||||
{.fd = xcb_fd, .events = POLLIN}};
|
||||
struct pollfd fds[] = {{.fd = mod->abort_fd, .events = POLLIN}, {.fd = xcb_fd, .events = POLLIN}};
|
||||
if (poll(fds, sizeof(fds) / sizeof(fds[0]), -1) < 0) {
|
||||
if (errno == EINTR)
|
||||
continue;
|
||||
|
@ -267,10 +257,7 @@ run(struct module *mod)
|
|||
break;
|
||||
}
|
||||
|
||||
for (xcb_generic_event_t *_e = xcb_wait_for_event(m->conn);
|
||||
_e != NULL;
|
||||
_e = xcb_poll_for_event(m->conn))
|
||||
{
|
||||
for (xcb_generic_event_t *_e = xcb_wait_for_event(m->conn); _e != NULL; _e = xcb_poll_for_event(m->conn)) {
|
||||
switch (XCB_EVENT_RESPONSE_TYPE(_e)) {
|
||||
case 0:
|
||||
LOG_ERR("XCB: %s", xcb_error((const xcb_generic_error_t *)_e));
|
||||
|
@ -278,18 +265,13 @@ run(struct module *mod)
|
|||
|
||||
case XCB_PROPERTY_NOTIFY: {
|
||||
xcb_property_notify_event_t *e = (xcb_property_notify_event_t *)_e;
|
||||
if (e->atom == _NET_ACTIVE_WINDOW ||
|
||||
e->atom == _NET_CURRENT_DESKTOP)
|
||||
{
|
||||
if (e->atom == _NET_ACTIVE_WINDOW || e->atom == _NET_CURRENT_DESKTOP) {
|
||||
/* Active desktop and/or window changed */
|
||||
update_active_window(m);
|
||||
update_application(mod);
|
||||
update_title(mod);
|
||||
mod->bar->refresh(mod->bar);
|
||||
} else if (e->atom == _NET_WM_VISIBLE_NAME ||
|
||||
e->atom == _NET_WM_NAME ||
|
||||
e->atom == XCB_ATOM_WM_NAME)
|
||||
{
|
||||
} else if (e->atom == _NET_WM_VISIBLE_NAME || e->atom == _NET_WM_NAME || e->atom == XCB_ATOM_WM_NAME) {
|
||||
assert(e->window == m->active_win);
|
||||
update_title(mod);
|
||||
mod->bar->refresh(mod->bar);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue