/* This file is part of tagr.
Copyright (C) 2009 Sergey Poznyakoff
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, 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 . */
#ifdef HAVE_CONFIG_H
# include
#endif
#include
#include
struct grid
{
struct grid_class *class;
queue_t *q;
unsigned long vmin;
unsigned long vmax;
unsigned long cur;
char *str;
void *data;
};
grid_t
grid_create (struct grid_class *class, queue_t *q,
unsigned long vmin, unsigned long vmax, void *cdata)
{
grid_t grid;
if (!class)
return NULL;
grid = xmalloc (sizeof (*grid));
grid->class = class;
grid->q = q;
grid->vmin = vmin;
grid->vmax = vmax;
grid->cur = 0;
if (class->create)
grid->data = class->create (grid, cdata);
else
grid->data = NULL;
grid->str = NULL;
return grid;
}
unsigned long
grid_next (grid_t grid, char **str, int *mark)
{
return grid->class->next (grid, str, mark);
}
void
grid_destroy (grid_t grid)
{
if (grid)
{
if (grid->str)
free (grid->str);
if (grid->class->dealloc)
grid->class->dealloc (grid->data);
free (grid);
}
}
static void
grid_free_data (void *ptr)
{
free (ptr);
}
/* FIXME: Suffixes not yet used. */
static char *short_suffix[] = {"", "k", "M", "G", "T"};
char **number_suffix = short_suffix;
size_t number_suffix_count = sizeof (short_suffix) / sizeof (short_suffix[0]);
struct ygrid_data
{
unsigned long step;
};
static void *
ygrid_create (grid_t grid, void *cdata)
{
struct monitor *mon = cdata;
struct ygrid_data *gr = xmalloc (sizeof (*gr));
gr->step = mon->ystep;
return gr;
}
static unsigned long
ygrid_next (grid_t grid, char **str, int *mark)
{
struct ygrid_data *gr = grid->data;
if (mark)
*mark = 0;
grid->cur += gr->step;
if (grid->cur < grid->vmax)
{
if (grid->str)
{
free (grid->str);
grid->str = NULL;
}
asprintf (&grid->str, "%6.1f", (double) grid->cur);
*str = grid->str;
}
return grid->cur;
}
struct grid_class grid_class_y = {
ygrid_create,
ygrid_next,
grid_free_data
};
struct xgrid_data
{
time_t start;
unsigned off;
unsigned unit;
};
#define TWOHRS (2*3600)
static void *
xgrid_2h_create (grid_t grid, void *cdata)
{
time_t start = *(time_t*)cdata;
struct xgrid_data *gr = xmalloc (sizeof (*gr));
unsigned long frac = start % 3600;
unsigned long h;
struct tm *tm;
gr->start = start - frac;
tm = localtime (&gr->start);
h = tm->tm_hour % 2;
gr->off = frac + h * TWOHRS;
gr->unit = tm->tm_hour - h;
return gr;
}
static unsigned long
xgrid_2h_next (grid_t grid, char **str, int *mark)
{
struct xgrid_data *gr = grid->data;
unsigned long ret = gr->off;
if (grid->str)
{
free (grid->str);
grid->str = NULL;
}
asprintf (&grid->str, "%02d", gr->unit);
*str = grid->str;
if (mark)
*mark = gr->unit == 0;
gr->off += TWOHRS;
gr->unit = (gr->unit + 24 - 2) % 24;
return ret;
}
struct grid_class grid_class_x_2h = {
xgrid_2h_create,
xgrid_2h_next,
grid_free_data
};
#define TWENTYFOURHRS 86400
static void *
xgrid_wday_create (grid_t grid, void *cdata)
{
time_t start = *(time_t*)cdata;
struct xgrid_data *gr = xmalloc (sizeof (*gr));
struct tm *tm = localtime (&start);
unsigned long frac;
frac = (tm->tm_hour * 60 + tm->tm_min) * 60 + tm->tm_sec;
gr->start = start - frac;
gr->off = frac;
gr->unit = tm->tm_wday;
return gr;
}
static unsigned long
xgrid_wday_next (grid_t grid, char **str, int *mark)
{
struct xgrid_data *gr = grid->data;
unsigned long ret = gr->off;
char buf[80];
struct tm *tm = localtime (&gr->start);
if (grid->str)
{
free (grid->str);
grid->str = NULL;
}
strftime (buf, sizeof buf, "%a", tm);
grid->str = xstrdup (buf);
*str = grid->str;
if (mark)
*mark = tm->tm_wday == 0;
gr->start -= TWENTYFOURHRS;
gr->off += TWENTYFOURHRS;
return ret;
}
struct grid_class grid_class_x_wday = {
xgrid_wday_create,
xgrid_wday_next,
grid_free_data
};
#define SEVENDAYS (7*TWENTYFOURHRS)
static void *
xgrid_week_create (grid_t grid, void *cdata)
{
time_t start = *(time_t*)cdata;
struct xgrid_data *gr = xmalloc (sizeof (*gr));
struct tm *tm = localtime (&start);
unsigned long frac;
frac = ((tm->tm_wday * 24 + tm->tm_hour) * 60 + tm->tm_min) * 60
+ tm->tm_sec;
gr->start = start - frac;
gr->off = frac;
gr->unit = 0;
return gr;
}
static unsigned long
xgrid_week_next (grid_t grid, char **str, int *mark)
{
struct xgrid_data *gr = grid->data;
unsigned long ret = gr->off;
struct tm *tm = localtime (&gr->start);
if (tm->tm_mday && tm->tm_mday < 7 && mark && gr->unit == 0)
{
int diff = (tm->tm_mday - 1) * TWENTYFOURHRS;
ret += diff;
*mark = 1;
*str = NULL;
gr->unit = 1;
}
else
{
gr->unit = 0;
if (grid->str)
{
free (grid->str);
grid->str = NULL;
}
asprintf (&grid->str, _("Week %2d"), tm->tm_yday / 7 + 1);
*str = grid->str;
if (mark)
*mark = 0;
gr->start -= SEVENDAYS;
gr->off += SEVENDAYS;
}
return ret;
}
struct grid_class grid_class_x_week = {
xgrid_week_create,
xgrid_week_next,
grid_free_data
};
static void *
xgrid_month_create (grid_t grid, void *cdata)
{
time_t start = *(time_t*)cdata;
struct xgrid_data *gr = xmalloc (sizeof (*gr));
struct tm *tm = localtime (&start);
unsigned long frac;
frac = (((tm->tm_mday - 1) * 24 + tm->tm_hour) * 60 + tm->tm_min) * 60
+ tm->tm_sec;
gr->start = start - frac;
gr->off = frac;
return gr;
}
static unsigned long
xgrid_month_next (grid_t grid, char **str, int *mark)
{
struct xgrid_data *gr = grid->data;
unsigned long ret = gr->off;
unsigned long frac;
struct tm *tm = localtime (&gr->start);
int mon;
char buf[80];
if (grid->str)
{
free (grid->str);
grid->str = NULL;
}
strftime (buf, sizeof buf, "%b", tm);
grid->str = xstrdup (buf);
*str = grid->str;
if (mark)
*mark = tm->tm_mon == 0;
if (tm->tm_mon == 0)
mon = 11;
else
mon = tm->tm_mon - 1;
do
{
gr->start -= TWENTYFOURHRS;
gr->off += TWENTYFOURHRS;
tm = localtime (&gr->start);
}
while (!(mon == tm->tm_mon && tm->tm_mday == 1));
frac = (((tm->tm_mday - 1) * 24 + tm->tm_hour) * 60 + tm->tm_min) * 60
+ tm->tm_sec;
gr->start -= frac;
gr->off += frac;
return ret;
}
struct grid_class grid_class_x_month = {
xgrid_month_create,
xgrid_month_next,
grid_free_data
};