Skip to content

Instantly share code, notes, and snippets.

@dvdkon
Created October 25, 2015 17:36
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dvdkon/facb5721f280efaf7706 to your computer and use it in GitHub Desktop.
Save dvdkon/facb5721f280efaf7706 to your computer and use it in GitHub Desktop.
A simple C program for feeding data into a lemonbar-like panel
/* Copyright 2015 David Koňařík
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
#include <math.h>
#include <sys/time.h>
#include <unistd.h>
#include <errno.h>
#define OUTLEN 2048
#define CMDOUTLEN 512
struct command
{
struct timeval interval;
char *command;
//Caches the output of the comand, set to "" on init
char curr_out[CMDOUTLEN];
//When the command will be run, set to 0 on init
struct timeval next_run;
};
#define CMD(sec, msec, cmd) {{sec, msec * 1000}, cmd, "", {0}}
struct command commands[] = {
CMD(10, 0, "amixer get 'Master' | sed -nEe "
"'/^ Front Left/ {s/.*\\[([0-9]+%)\\].*/\\1/g; p}'"),
CMD(10, 0, "mpc volume | cut -d ' ' -f 2 | sed -e 's/volume://g'"),
CMD(1, 0, "~/.config/lemonbar/mpd_playing_now.sh"),
CMD(10, 0, "~/.config/lemonbar/desktops.sh"),
CMD(10, 0, "~/.config/lemonbar/battery.sh"),
CMD(0, 500, "date +'%d.%m.%Y %H:%M'")
};
static const char format[] = "%{l}"
"%{B#000549} \ue152 %{B-} $0 " //Volume
"%{B#0F0F85} \ue0ed %{B-} $1 " //mpd volume
"$2" //mpd "Playing now"
"%{c}"
"$3" //Desktops
"%{r}"
"$4 " //Battery
"%{B#780808} \ue015 %{B-} $5"; //Clock
void process_command(struct command *cmd)
{
char cmdout[CMDOUTLEN];
cmd->curr_out[0] = '\0';
FILE *cmdfp = popen(cmd->command, "r");
if(cmdfp == NULL)
{
printf("Command %s failed to run: %s\n", cmd->command,
strerror(errno));
exit(1);
}
while(fgets(cmdout, CMDOUTLEN, cmdfp) != NULL)
{
if(strlen(cmdout) + strlen(cmd->curr_out) > CMDOUTLEN)
{
printf("Command buffer is full\n");
exit(2);
}
if(cmdout[strlen(cmdout) - 1] == '\n')
{
cmdout[strlen(cmdout) - 1] = '\0'; //Strip newlines
}
strcat(cmd->curr_out, cmdout);
}
fclose(cmdfp);
struct timeval time;
gettimeofday(&time, NULL);
timeradd(&time, &cmd->interval, &cmd->next_run);
}
void create_output(char *out)
{
size_t i;
size_t cmdnum = 0;
unsigned int command_pos = 0;
size_t tmp_out_strlen = 0;
for(i = 0; i < strlen(format); i++)
{
if(command_pos)
{
if(isdigit(format[i]))
{
cmdnum += (format[i] - '0') * pow(10, command_pos - 1);
}
else
{
strcat(out, commands[cmdnum].curr_out);
command_pos = 0;
cmdnum = 0;
}
}
if(format[i] == '$')
{
command_pos = 1;
}
if(!command_pos)
{
tmp_out_strlen = strlen(out);
out[tmp_out_strlen] = format[i];
out[tmp_out_strlen + 1] = '\0';
}
}
if(command_pos != 0)
{
strcat(out, commands[cmdnum].curr_out);
}
}
int main(int argc, char *argv[])
{
size_t i = 0;
for(i = 0; i < sizeof(commands) / sizeof(struct command); i++)
{
process_command(&commands[i]);
}
char out[OUTLEN] = "";
create_output(out);
printf("%s\n", out);
fflush(stdout);
struct timeval time;
struct command *next_command;
struct timeval delta;
while(1)
{
gettimeofday(&time, NULL);
next_command = &commands[0];
for(i = 0; i < sizeof(commands) / sizeof(struct command); i++)
{
if(timercmp(&commands[i].next_run, &next_command->next_run, <))
{
next_command = &commands[i];
}
}
timersub(&next_command->next_run, &time, &delta);
long time_to_wait = delta.tv_sec * 1000 * 1000 + delta.tv_usec;
usleep(time_to_wait > 0 ? time_to_wait : 0);
process_command(next_command);
out[0] = '\0';
create_output(out);
printf("%s\n", out);
fflush(stdout);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment