2019-03-24 16:31:05 -06:00
# include <stdlib.h>
# include <stdio.h>
# include <string.h>
# include <unistd.h>
# include <signal.h>
# include <X11/Xlib.h>
# define LENGTH(X) (sizeof(X) / sizeof (X[0]))
2019-11-30 14:43:33 -07:00
# define CMDLENGTH 50
2019-03-24 21:51:40 -06:00
2019-03-24 16:31:05 -06:00
typedef struct {
2019-03-29 21:10:46 -06:00
char * icon ;
2019-03-24 16:31:05 -06:00
char * command ;
unsigned int interval ;
unsigned int signal ;
} Block ;
void sighandler ( int num ) ;
2019-03-24 21:51:40 -06:00
void replace ( char * str , char old , char new ) ;
void getcmds ( int time ) ;
2019-12-16 14:35:29 -07:00
# ifndef __OpenBSD__
2019-03-24 21:51:40 -06:00
void getsigcmds ( int signal ) ;
void setupsignals ( ) ;
2019-12-16 14:35:29 -07:00
void sighandler ( int signum ) ;
# endif
2019-11-13 13:58:20 -07:00
int getstatus ( char * str , char * last ) ;
2019-03-24 21:51:40 -06:00
void setroot ( ) ;
void statusloop ( ) ;
void termhandler ( int signum ) ;
2019-03-24 16:31:05 -06:00
# include "blocks.h"
static Display * dpy ;
static int screen ;
static Window root ;
2019-11-30 14:43:33 -07:00
static char statusbar [ LENGTH ( blocks ) ] [ CMDLENGTH ] = { 0 } ;
2019-11-13 13:58:20 -07:00
static char statusstr [ 2 ] [ 256 ] ;
static int statusContinue = 1 ;
2019-11-26 22:43:16 -07:00
static void ( * writestatus ) ( ) = setroot ;
2019-03-24 16:31:05 -06:00
void replace ( char * str , char old , char new )
{
int N = strlen ( str ) ;
for ( int i = 0 ; i < N ; i + + )
if ( str [ i ] = = old )
str [ i ] = new ;
}
2019-03-24 21:51:40 -06:00
//opens process *cmd and stores output in *output
2019-03-29 21:10:46 -06:00
void getcmd ( const Block * block , char * output )
2019-03-24 16:31:05 -06:00
{
2019-03-29 21:10:46 -06:00
strcpy ( output , block - > icon ) ;
char * cmd = block - > command ;
2019-03-24 16:31:05 -06:00
FILE * cmdf = popen ( cmd , " r " ) ;
if ( ! cmdf )
return ;
char c ;
2019-11-07 13:07:19 -07:00
int i = strlen ( block - > icon ) ;
2019-11-30 14:43:33 -07:00
fgets ( output + i , CMDLENGTH - i , cmdf ) ;
i = strlen ( output ) ;
2019-11-07 13:07:19 -07:00
if ( delim ! = ' \0 ' & & - - i )
output [ i + + ] = delim ;
output [ i + + ] = ' \0 ' ;
2019-03-24 16:31:05 -06:00
pclose ( cmdf ) ;
}
void getcmds ( int time )
{
const Block * current ;
for ( int i = 0 ; i < LENGTH ( blocks ) ; i + + )
{
current = blocks + i ;
if ( ( current - > interval ! = 0 & & time % current - > interval = = 0 ) | | time = = - 1 )
2019-03-29 21:10:46 -06:00
getcmd ( current , statusbar [ i ] ) ;
2019-03-24 16:31:05 -06:00
}
}
2019-12-16 14:35:29 -07:00
# ifndef __OpenBSD__
2019-03-24 16:31:05 -06:00
void getsigcmds ( int signal )
{
const Block * current ;
for ( int i = 0 ; i < LENGTH ( blocks ) ; i + + )
{
current = blocks + i ;
if ( current - > signal = = signal )
2019-03-29 21:10:46 -06:00
getcmd ( current , statusbar [ i ] ) ;
2019-03-24 16:31:05 -06:00
}
}
void setupsignals ( )
{
for ( int i = 0 ; i < LENGTH ( blocks ) ; i + + )
{
if ( blocks [ i ] . signal > 0 )
signal ( SIGRTMIN + blocks [ i ] . signal , sighandler ) ;
}
}
2019-12-16 14:35:29 -07:00
# endif
2019-03-24 16:31:05 -06:00
2019-11-13 13:58:20 -07:00
int getstatus ( char * str , char * last )
2019-03-24 16:31:05 -06:00
{
2019-11-13 13:58:20 -07:00
strcpy ( last , str ) ;
2019-11-26 22:43:16 -07:00
str [ 0 ] = ' \0 ' ;
for ( int i = 0 ; i < LENGTH ( blocks ) ; i + + )
strcat ( str , statusbar [ i ] ) ;
str [ strlen ( str ) - 1 ] = ' \0 ' ;
2019-11-13 13:58:20 -07:00
return strcmp ( str , last ) ; //0 if they are the same
2019-03-24 16:31:05 -06:00
}
void setroot ( )
{
2019-11-13 13:58:20 -07:00
if ( ! getstatus ( statusstr [ 0 ] , statusstr [ 1 ] ) ) //Only set root if text has changed.
return ;
2019-03-24 16:31:05 -06:00
Display * d = XOpenDisplay ( NULL ) ;
if ( d ) {
dpy = d ;
}
screen = DefaultScreen ( dpy ) ;
root = RootWindow ( dpy , screen ) ;
2019-11-13 13:58:20 -07:00
XStoreName ( dpy , root , statusstr [ 0 ] ) ;
2019-03-24 16:31:05 -06:00
XCloseDisplay ( dpy ) ;
}
2019-11-26 22:43:16 -07:00
void pstdout ( )
{
if ( ! getstatus ( statusstr [ 0 ] , statusstr [ 1 ] ) ) //Only write out if text has changed.
return ;
printf ( " %s \n " , statusstr [ 0 ] ) ;
fflush ( stdout ) ;
}
2019-03-24 16:31:05 -06:00
2019-03-24 21:51:40 -06:00
void statusloop ( )
2019-03-24 16:31:05 -06:00
{
2019-12-16 14:35:29 -07:00
# ifndef __OpenBSD__
2019-03-24 16:31:05 -06:00
setupsignals ( ) ;
2019-12-16 14:35:29 -07:00
# endif
2019-03-24 16:31:05 -06:00
int i = 0 ;
getcmds ( - 1 ) ;
while ( statusContinue )
{
getcmds ( i ) ;
2019-11-26 22:43:16 -07:00
writestatus ( ) ;
2019-03-24 16:31:05 -06:00
sleep ( 1.0 ) ;
i + + ;
}
}
2019-12-16 14:35:29 -07:00
# ifndef __OpenBSD__
2019-03-24 16:31:05 -06:00
void sighandler ( int signum )
{
getsigcmds ( signum - SIGRTMIN ) ;
2019-11-26 22:43:16 -07:00
writestatus ( ) ;
2019-03-24 16:31:05 -06:00
}
2019-12-16 14:35:29 -07:00
# endif
2019-03-24 16:31:05 -06:00
void termhandler ( int signum )
{
statusContinue = 0 ;
exit ( 0 ) ;
}
2019-03-29 21:10:46 -06:00
int main ( int argc , char * * argv )
2019-03-24 16:31:05 -06:00
{
2019-03-29 21:10:46 -06:00
for ( int i = 0 ; i < argc ; i + + )
{
if ( ! strcmp ( " -d " , argv [ i ] ) )
2019-11-07 13:07:19 -07:00
delim = argv [ + + i ] [ 0 ] ;
2019-11-26 22:43:16 -07:00
else if ( ! strcmp ( " -p " , argv [ i ] ) )
writestatus = pstdout ;
2019-03-29 21:10:46 -06:00
}
2019-03-24 16:31:05 -06:00
signal ( SIGTERM , termhandler ) ;
signal ( SIGINT , termhandler ) ;
2019-11-30 14:43:33 -07:00
statusloop ( ) ;
2019-03-24 16:31:05 -06:00
}