/*
* ----------------------------------------------------------------------------
* "THE BEER-WARE LICENSE" (Revision 42):
* <fredde at shapeshifter dot se> wrote this file. As long as you retain this
* notice you can do whatever you want with this stuff. If we meet some day,
* and you think this stuff is worth it, you can buy me a beer in return.
* Fredrik Lindberg
* ----------------------------------------------------------------------------
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <signal.h>
#include <sys/types.h>
#include <time.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include "xwlans.h"
u_char flg_run = 1;
int
main(int argc, char *argv[])
{
int i, geo_mask = NoValue, opt_fork = 1;
char *iface = 0;
struct xw_t xw;
struct opt_t *opts;
pid_t pid;
xw.opt_shadow = 0;
opts = _malloc(sizeof(struct opt_t));
memset(opts, 0, sizeof(struct opt_t));
for (i = 1; i < argc; i++)
{
if (strcmp(argv[i], "-h") == 0) {
usage(argv[0]);
exit(EXIT_SUCCESS);
}
else if (strcmp(argv[i], "-i") == 0) {
iface = argv[++i];
}
else if (strcmp(argv[i], "-g") == 0) {
geo_mask = XParseGeometry(argv[++i], &opts->x, &opts->y, &opts->width, &opts->height);
}
else if (strcmp(argv[i], "-f") == 0) {
opts->fname = argv[++i];
}
else if (strcmp(argv[i], "-ct") == 0) {
opts->tcolor = argv[++i];
}
else if (strcmp(argv[i], "-cb") == 0) {
opts->bcolor = argv[++i];
}
else if (strcmp(argv[i], "-cs") == 0) {
xw.opt_shadow = 1;
opts->scolor = argv[++i];
}
else if (strcmp(argv[i], "-nf") == 0) {
opt_fork = 0;
}
else if (strcmp(argv[i], "-display") == 0) {
opts->dispn = argv[++i];
}
else if (strcmp(argv[i], "-b") == 0) {
opts->bmax = argv[++i];
}
else if (strcmp(argv[i], "-n") == 0) {
opts->interval = argv[++i];
}
else if (strcmp(argv[i], "-d") == 0) {
opts->dynamic = 1;
}
else if (strcmp(argv[i], "-m") == 0) {
opts->measure = argv[++i];
}
else
{
fprintf(stderr, "Unknown option: %s\n", argv[i]);
exit(EXIT_FAILURE);
}
}
/* no use to continue without an interface */
if (iface == 0) {
usage(argv[0]);
exit(EXIT_FAILURE);
}
xw.display = (opts->dispn != 0) ? opts->dispn : NULL;
if (init_win(&xw) != 0)
exit(EXIT_FAILURE);
xw.x = (geo_mask & XValue) ? opts->x : DEF_X;
xw.y = (geo_mask & YValue) ? opts->y : DEF_Y;
xw.x += (geo_mask & XNegative) ? DisplayWidth(xw.disp, xw.screen) : 0;
xw.y += (geo_mask & YNegative) ? DisplayHeight(xw.disp, xw.screen) : 0;
xw.width = (geo_mask & WidthValue) ? opts->width : DEF_WIDTH;
xw.height = (geo_mask & HeightValue) ? opts->height : DEF_HEIGHT;
xw.font = XLoadFont(xw.disp, (opts->fname != 0) ? opts->fname : DEF_FONT);
XSetFont(xw.disp, xw.winGC, xw.font);
xw.xfs = XQueryFont(xw.disp, xw.font);
xw.f_height = xw.xfs->max_bounds.ascent + xw.xfs->max_bounds.descent;
xw.c_text = get_color(&xw, (opts->tcolor != 0) ? opts->tcolor : DEF_TC);
xw.c_bar = get_color(&xw, (opts->bcolor != 0) ? opts->bcolor : DEF_BC);
xw.c_shadow = get_color(&xw, (opts->scolor != 0) ? opts->scolor : DEF_SC);
xw.bmax = (opts->bmax != 0) ? atoi(opts->bmax) : DEF_BMAX;
xw.interval = (opts->interval != 0) ? atoi(opts->interval) : DEF_INTERVAL;
xw.opt_dyn = (opts->dynamic != 0) ? 1 : 0;
if (opts->measure != 0) {
xw.opt_measure = atoi(opts->measure);
xw.opt_measure = ((xw.opt_measure >= 0) && (xw.opt_measure <= 1)) ?
xw.opt_measure : DEF_MEASURE;
}
else {
xw.opt_measure = DEF_MEASURE;
}
free(opts);
if (opt_fork == 1)
{
pid = fork();
if (pid > 0)
exit(EXIT_SUCCESS);
else if (pid == -1)
fprintf(stderr, "Unable to fork into background: %s\n", strerror(errno));
}
signal(SIGHUP, (void *)set_flg);
signal(SIGINT, (void *)set_flg);
signal(SIGKILL, (void *)set_flg);
signal(SIGTERM, (void *)set_flg);
signal(SIGQUIT, (void *)set_flg);
main_loop(&xw, iface);
close_win(&xw);
return 0;
}
void
main_loop(struct xw_t *xw, char *iface)
{
XEvent xev;
int tmpval = 0, maxval = 0;
char flg_update = 1;
time_t timeval = time(NULL);
while(flg_run == 1)
{
if (flg_update == 1)
{
tmpval = get_strength(iface, xw->opt_measure);
maxval = (tmpval > maxval) ? tmpval : maxval;
if (xw->opt_dyn == 1)
xw->bmax = maxval;
flg_update = 0;
timeval = time(NULL);
clear_win(xw);
redraw(xw, tmpval, maxval);
XSync(xw->disp, False);
}
while(XPending(xw->disp))
{
XNextEvent(xw->disp, &xev);
if (xev.type == Expose)
{
/* Did the exposure happen inside our drawing area? */
if (((xev.xexpose.x >= xw->x) && (xev.xexpose.x <= (xw->x + xw->width))) ||
((xev.xexpose.y >= xw->y) && (xev.xexpose.y <= (xw->y + xw->height))))
{
redraw(xw, tmpval, maxval);
XSync(xw->disp, False);
}
/* The whole screen was exposed */
else if ((xev.xexpose.x == 0) && (xev.xexpose.y == 0))
{
redraw(xw, tmpval, maxval);
XSync(xw->disp, False);
}
}
}
usleep(1000);
if ((time(NULL) - timeval) >= xw->interval)
flg_update = 1;
}
}
void
set_flg()
{
flg_run = 0;
}
void
usage(char *exec)
{
printf("X WaveLan Strength monitor %s\n", VERSION);
printf("Usage %s -i <interface> [options]\n", exec);
printf("Options:\n");
printf(" -display disp \t Displayname\n");
printf(" -g geometry \t [<width>{xX}<height>][{+-}<xoffset>{+-}<yoffset>]\n");
printf(" -f font \t Font name (default fixed)\n");
printf(" -ct color \t Text color (default rgb:ff/ff/ff)\n");
printf(" -cb color \t Bar color (default rgb:ff/ff/ff)\n");
printf(" -cs color \t Shadow color\n");
printf(" -b int \t Maximum measureable dBm value (default 110)\n");
printf(" -d \t\t Dynamic maximum measureable dBm value (overrides -b)\n");
printf(" -n seconds \t Update interval (default 3)\n");
printf(" -m 0/1 \t What to measure, 0 = Quality, 1 = Signal (default Signal)\n");
printf(" -nf \t\t Don't fork into background\n");
}
syntax highlighted by Code2HTML, v. 0.9.1