wmaker-eukara/dockapps/wmnd/src/display.c

547 lines
13 KiB
C

/*
* display: commod graphic functions
* Copyright(c) 1997 by Alfredo K. Kojima
* Copyright(c) 2001-2008 by wave++ "Yuri D'Elia" <wavexx@users.sf.net>
* Distributed under GNU GPL (v2 or above) WITHOUT ANY WARRANTY.
*/
/* local headers */
#include "display.h"
#include "wmnd.h"
/* system headers */
#include <math.h>
#include <X11/Xlib.h>
/*
* get the bits-per-pixel for the specified maximal value, considering
* the actual scale mode (auto, max, log).
*/
int
getBpp(unsigned size, unsigned long max)
{
int bpp;
if(wmnd.maxScale && bit_get(CFG_MODE))
{
bpp = wmnd.maxScale / size;
if((wmnd.maxScale % size) > 0)
++bpp;
}
else
{
if(max > size)
{
bpp = max / size;
if((max % size) > 0)
++bpp;
}
else
bpp = 1;
}
return bpp;
}
/* truncate values below size in a stacked way */
void
trunc_stacked(unsigned size, unsigned* rx, unsigned* tx)
{
/* handle values below max */
if((*rx + *tx) > size)
{
if(*rx > size)
*rx = size;
if((*rx + *tx) > size)
*tx = size - *rx;
}
}
/* truncate values below size */
void
trunc_normal(unsigned size, unsigned* rx, unsigned* tx)
{
*rx = MIN(size, *rx);
*tx = MIN(size, *tx);
}
#ifdef USE_DRW_TRADITIONAL
/* Traditional mode */
void
drwTraditional(unsigned long* hist, unsigned mIn, unsigned mOut,
unsigned size, unsigned long long rx_max, unsigned long long tx_max)
{
unsigned int k, txlev, rxlev, nolev;
int bpp = getBpp(size, rx_max + tx_max);
for(k = 0; k < 58; k++)
{
rxlev = hist[mIn] / bpp;
txlev = hist[mOut] / bpp;
trunc_stacked(size, &rxlev, &txlev);
nolev = (rxlev + txlev);
copy_xpm_area(66, 0, 1, txlev, k + 3, 53 - nolev);
copy_xpm_area(65, 0, 1, size - nolev, k + 3, 53 - size);
copy_xpm_area(67, 0, 1, rxlev, k + 3, 53 - rxlev);
hist += 4;
}
copy_xpm_area(70, 1, 58, 1, 3, 53 - size);
}
#endif
#ifdef USE_DRW_MGRAPH
/* MGraph mode */
void
drwMGraph(unsigned long* hist, unsigned mIn, unsigned mOut,
unsigned size, unsigned long long rx_max, unsigned long long tx_max)
{
/* max scale */
unsigned int k, txlev, rxlev;
int bpp = getBpp(size, MAX(tx_max, rx_max));
/* process the whole history */
for(k = 0; k < 58; ++k)
{
rxlev = hist[mIn] / bpp;
txlev = hist[mOut] / bpp;
trunc_normal(size, &rxlev, &txlev);
/* clear the top area */
copy_xpm_area(65, 0, 1, size - MAX(rxlev, txlev), k + 3, 53 - size);
/* draw the tx/rx bars */
if(rxlev > txlev)
{
/* rx is major */
copy_xpm_area(67, 0, 1, rxlev - txlev, k + 3, 53 - rxlev);
copy_xpm_area(66, 0, 1, txlev, k + 3, 53 - txlev);
}
else
{
/* tx is major */
copy_xpm_area(66, 0, 1, txlev - rxlev, k + 3, 53 - txlev);
copy_xpm_area(67, 0, 1, rxlev, k + 3, 53 - rxlev);
}
/* advance */
hist += 4;
}
copy_xpm_area(70, 1, 58, 1, 3, 53 - size);
}
#endif
#ifdef USE_DRW_WAVEFORM
/* Waveform mode */
void
drwWaveform(unsigned long* hist, unsigned mIn, unsigned mOut,
unsigned size, unsigned long long rx_max, unsigned long long tx_max)
{
unsigned int k, txlev, rxlev, center;
int bpp = getBpp(size, rx_max + tx_max);
for(k = 0; k < 58; k++)
{
rxlev = hist[mIn] / bpp / 2;
txlev = hist[mOut] / bpp / 2;
trunc_stacked(size / 2, &rxlev, &txlev);
center = 53 - size / 2;
copy_xpm_area(65, 0, 1, size, k + 3, 53 - size);
copy_xpm_area(66, 0, 1, txlev, k + 3,
(center - rxlev) - txlev);
copy_xpm_area(66, 0, 1, txlev, k + 3, (center + rxlev));
copy_xpm_area(67, 0, 1, rxlev * 2, k + 3, center - rxlev);
hist += 4;
}
copy_xpm_area(70, 1, 58, 1, 3, 53 - size);
copy_xpm_area(70, 0, 58, 1, 3, 53 - size / 2);
}
#endif
#ifdef USE_DRW_WMWAVE
/* Reverse wmnet mode */
void
drwWmwave(unsigned long* hist, unsigned mIn, unsigned mOut,
unsigned size, unsigned long long rx_max, unsigned long long tx_max)
{
unsigned int k, msize, bpp, txlev, rxlev, center;
msize = (unsigned)((double)size / 2);
bpp = getBpp(msize, MAX(tx_max, rx_max));
for(k = 0; k < 58; k++)
{
rxlev = hist[mIn] / bpp;
txlev = hist[mOut] / bpp;
trunc_normal(msize, &rxlev, &txlev);
center = 53 - msize;
copy_xpm_area(65, 0, 1, size, k + 3, 53 - size);
copy_xpm_area(66, 0, 1, txlev, k + 3, center - txlev);
copy_xpm_area(67, 0, 1, rxlev, k + 3, center);
hist += 4;
}
copy_xpm_area(70, 1, 58, 1, 3, 53 - size);
copy_xpm_area(70, 0, 58, 1, 3, 53 - msize);
}
#endif
#ifdef USE_DRW_WMNET
/* Wmnet like modeness */
void
drwWmnet(unsigned long* hist, unsigned mIn, unsigned mOut, unsigned size,
unsigned long long rx_max, unsigned long long tx_max)
{
unsigned int k, txlev, rxlev, nolev;
int bpp = getBpp(size, rx_max + tx_max);
for(k = 0; k < 58; k++)
{
rxlev = hist[mIn] / bpp;
txlev = hist[mOut] / bpp;
trunc_normal(size, &rxlev, &txlev);
/* handle overlap, smaller in front */
if((rxlev + txlev) > size)
{
if(rxlev > txlev)
rxlev = size - txlev;
else
txlev = size - rxlev;
}
nolev = size - (rxlev + txlev);
copy_xpm_area(66, 0, 1, txlev, k + 3, 53 - size);
copy_xpm_area(65, 0, 1, nolev, k + 3, (53 - size) + txlev);
copy_xpm_area(67, 0, 1, rxlev, k + 3, 53 - rxlev);
hist += 4;
}
copy_xpm_area(70, 1, 58, 1, 3, 53 - size);
}
#endif
#ifdef USE_DRW_SEPGRAPHS
/* Separated graphs mode */
void
drwSepgraphs(unsigned long* hist, unsigned mIn, unsigned mOut,
unsigned size, unsigned long long rx_max, unsigned long long tx_max)
{
unsigned int k, msize, txlev, rxlev, center, rxBpp, txBpp;
msize = (unsigned)((double)size / 2);
rxBpp = getBpp(msize, rx_max);
txBpp = getBpp(msize, tx_max);
for(k = 0; k < 58; k++)
{
rxlev = hist[mIn] / rxBpp;
txlev = hist[mOut] / txBpp;
trunc_normal(msize, &rxlev, &txlev);
center = 53 - msize;
copy_xpm_area(65, 0, 1, size, k + 3, 53 - size);
copy_xpm_area(66, 0, 1, txlev, k + 3, center - txlev);
copy_xpm_area(67, 0, 1, rxlev, k + 3, 53 - rxlev);
hist += 4;
}
copy_xpm_area(70, 1, 58, 1, 3, 53 - size);
copy_xpm_area(70, 0, 58, 1, 3, 53 - msize);
}
#endif
#ifdef USE_DRW_TWISTED
/* Twisted mode */
void
drwTwisted(unsigned long* hist, unsigned mIn, unsigned mOut,
unsigned size, unsigned long long rx_max, unsigned long long tx_max)
{
unsigned int k, stpos, itn, txlev, rxlev;
int bpp = getBpp(29, MAX(tx_max, rx_max));
stpos = 53 - size;
itn = 53 - stpos;
hist += 4 * (58-itn);
for(k = 0; k < itn; k++)
{
rxlev = hist[mIn] / bpp;
txlev = hist[mOut] / bpp;
trunc_normal(29, &rxlev, &txlev);
/* Tx on the right, flowing up */
copy_xpm_area(70, 3, 29, 1, 32, stpos + k);
if (txlev)
copy_xpm_area(70, 4, txlev, 1, 32 + (29-txlev)/2, stpos + k)
else
copy_xpm_area(70, 0, 1, 1, 46, stpos + k);
/* Rx on the left, flowing down */
copy_xpm_area(70, 3, 29, 1, 3, 52 - k);
if (rxlev)
copy_xpm_area(70, 5, rxlev, 1, 3 + (29 - rxlev) / 2, 52 - k)
else
copy_xpm_area(70, 0, 1, 1, 17, 52 - k);
hist += 4;
}
copy_xpm_area(70, 1, 58, 1, 3, 53 - size);
}
#endif
#if defined(USE_DRW_CHARTS) || defined(USE_DRW_NEEDLE)
/* func utils */
void
drwGetMeds(const unsigned long* hist, const unsigned mIn,
const unsigned mOut, unsigned long* tx_med,
unsigned long* rx_med)
{
unsigned int k;
*tx_med = *rx_med = 0;
for(k = 0; k < 58; k++)
{
*tx_med += hist[mOut];
*rx_med += hist[mIn];
hist += 4;
}
*tx_med /= 58;
*rx_med /= 58;
}
#endif
#ifdef USE_DRW_CHARTS
/* Charts mode */
void drwCharts(unsigned long* hist, unsigned mIn, unsigned mOut, unsigned size,
unsigned long long rx_max, unsigned long long tx_max)
{
unsigned int k, j, stpos, spc;
unsigned long tx_med = 0, rx_med = 0, x_max;
stpos = 53 - size;
drwGetMeds(hist, mIn, mOut, &tx_med, &rx_med);
hist += 4 * 57;
spc = (size - 34) / 3;
x_max = MAX(rx_max, tx_max);
if (!x_max)
x_max = 1;
/* clear zones */
copy_xpm_area(70, 3, 58, 1, 3, stpos + 1);
copy_xpm_area(70, 1, 58, 1, 3, 53 - size);
copy_xpm_area(70, 3, 58, 1, 3, 52);
for(k = 0; k < 3; k++)
for(j = 0; j < spc; j++)
copy_xpm_area(70, 3, 58, 1, 3, stpos + 10 + (8*k) + (k*spc) + j);
/* tx current */
copy_xpm_area(70, 8, 58, 8, 3, stpos + 2);
copy_xpm_area(70, 17, (int)((double)54*hist[mOut]/x_max), 6, 5, stpos + 3);
/* tx average */
copy_xpm_area(70, 8, 58, 8, 3, stpos + 10 + spc);
copy_xpm_area(70, 17, (int)((double)54*tx_med/x_max), 6, 5, stpos + 11 + spc);
/* rx current */
copy_xpm_area(70, 8, 58, 8, 3, stpos + 18 + spc*2);
copy_xpm_area(70, 17, (int)((double)54*hist[mIn]/x_max), 6, 5,
stpos + 19 + spc * 2);
/* rx average */
copy_xpm_area(70, 8, 58, 8, 3, stpos + 26 + spc*3);
copy_xpm_area(70, 17, (int)((double)54*rx_med/x_max), 6, 5,
stpos + 27 + spc * 3);
}
#endif
#ifdef USE_DRW_NEEDLE
/* simple utility function for rotating points */
void
drwRotPoint(const unsigned len, const double rad,
unsigned* nX, unsigned* nY)
{
*nX = (unsigned)((double)len * sin(rad));
*nY = (unsigned)((double)len * cos(rad));
}
/* needle mode */
void drwNeedle(unsigned long* hist, unsigned mIn, unsigned mOut, unsigned size,
unsigned long long rx_max, unsigned long long tx_max)
{
unsigned int k, stpos, offset, nX, nY;
unsigned long tx_med = 0, rx_med = 0, x_max;
double angle;
static int gcinit = 0;
static GC gcs[3];
/* gc initialization */
if (!gcinit)
{
XGCValues gcval;
gcval.foreground = dockapp.stdColors.txColor;
gcval.graphics_exposures = False;
gcs[0] = XCreateGC(dockapp.d, dockapp.pixmap, GCForeground |
GCGraphicsExposures, &gcval);
gcval.foreground = dockapp.stdColors.rxColor;
gcs[1] = XCreateGC(dockapp.d, dockapp.pixmap, GCForeground |
GCGraphicsExposures, &gcval);
gcval.foreground = dockapp.stdColors.mdColor;
gcs[2] = XCreateGC(dockapp.d, dockapp.pixmap, GCForeground |
GCGraphicsExposures, &gcval);
gcinit = 1;
}
stpos = 53 - size;
offset = (size - 34) / 2 + 1;
/* background pixmap */
copy_xpm_area(129, 0, 58, 34, 3, stpos + offset);
/* clean up */
copy_xpm_area(70, 1, 58, 1, 3, 53 - size);
for(k = 1; k < offset; k++)
{
copy_xpm_area(70, 3, 58, 1, 3, stpos + k);
copy_xpm_area(70, 3, 58, 1, 3, 53 - k);
}
drwGetMeds(hist, mIn, mOut, &tx_med, &rx_med);
x_max = MAX(rx_max, tx_max);
if (!x_max)
x_max=1;
/* tx needle */
angle = 1.57 * tx_med / x_max;
drwRotPoint(13, angle, &nX, &nY);
XDrawLine(dockapp.d, dockapp.pixmap, gcs[0], 5, stpos + offset + 2,
5 + nX, stpos + offset + 2 + nY);
/* rx needle */
angle = 1.57 * rx_med / x_max;
drwRotPoint(13, angle, &nX, &nY);
XDrawLine(dockapp.d, dockapp.pixmap, gcs[1], 5, stpos + offset + 31,
5 + nX, stpos + offset + 31 - nY);
/* central needle */
if (!(tx_max+rx_max))
tx_max=1;
angle = 0.65*(rx_med+tx_med)/(rx_max+tx_max)+1.25;
drwRotPoint(44, angle, &nX, &nY);
XDrawLine(dockapp.d, dockapp.pixmap, gcs[2], 14, stpos + offset + 17,
14 + nX, stpos + offset + 17 + nY);
}
#endif
#ifdef USE_DRW_LINES
/* lines mode */
void drwLines(unsigned long* hist, unsigned mIn, unsigned mOut, unsigned size,
unsigned long long rx_max, unsigned long long tx_max)
{
unsigned int k, oTxlev, oRxlev, txlev, rxlev;
int bpp = getBpp(size - 2, MAX(tx_max, rx_max));
static int gcinit = 0;
static GC gcs[2];
/* gc initialization */
if (!gcinit)
{
XGCValues gcval;
gcval.foreground = dockapp.stdColors.txColor;
gcval.graphics_exposures = False;
gcs[0] = XCreateGC(dockapp.d, dockapp.pixmap, GCForeground |
GCGraphicsExposures, &gcval);
gcval.foreground = dockapp.stdColors.rxColor;
gcs[1] = XCreateGC(dockapp.d, dockapp.pixmap, GCForeground |
GCGraphicsExposures, &gcval);
gcinit = 1;
}
/* fake old values */
oRxlev = hist[mIn] / bpp;
oTxlev = hist[mOut] / bpp;
trunc_normal(size - 2, &oRxlev, &oTxlev);
for(k = 0; k < 58; k++)
{
rxlev = hist[mIn] / bpp;
txlev = hist[mOut] / bpp;
trunc_normal(size - 2, &rxlev, &txlev);
/* clear the area */
copy_xpm_area(65, 0, 1, size, k + 3, 53 - size);
/* tx and rx */
XDrawLine(dockapp.d, dockapp.pixmap, gcs[0],
k + 3, 52 - oTxlev, k + 3, 52 - txlev);
XDrawLine(dockapp.d, dockapp.pixmap, gcs[1],
k + 3, 52 - oRxlev, k + 3, 52 - rxlev);
/* advance */
hist += 4;
oTxlev = txlev;
oRxlev = rxlev;
}
copy_xpm_area(70, 1, 58, 1, 3, 53 - size);
}
#endif
/* function's structure list */
struct drwStruct drwFuncs[] =
{
#ifdef USE_DRW_TRADITIONAL
{ "traditional", drwTraditional },
#endif
#ifdef USE_DRW_MGRAPH
{ "mgraph", drwMGraph },
#endif
#ifdef USE_DRW_WAVEFORM
{ "waveform", drwWaveform },
#endif
#ifdef USE_DRW_WMWAVE
{ "wmwave", drwWmwave },
#endif
#ifdef USE_DRW_WMNET
{ "wmnet", drwWmnet },
#endif
#ifdef USE_DRW_SEPGRAPHS
{ "sepgraphs", drwSepgraphs },
#endif
#ifdef USE_DRW_TWISTED
{ "twisted", drwTwisted },
#endif
#ifdef USE_DRW_CHARTS
{ "charts", drwCharts },
#endif
#ifdef USE_DRW_NEEDLE
{ "needle", drwNeedle },
#endif
#ifdef USE_DRW_LINES
{ "lines", drwLines },
#endif
{ NULL, NULL, }
};