aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDimitri Sokolyuk <demon@dim13.org>2014-09-10 21:21:43 +0000
committerDimitri Sokolyuk <demon@dim13.org>2014-09-10 21:21:43 +0000
commitce4c20d0acc9cec5551934131feae7ecd11ddedf (patch)
tree11610670bfa274dc3ad6bc053686f529fb9c2b29
parentb610c168ab0b5b964f72554bedd0b8c3a3365a39 (diff)
split code
-rw-r--r--Makefile2
-rw-r--r--cms.h10
-rw-r--r--spectrogram.c342
-rw-r--r--widget.c310
-rw-r--r--widget.h71
5 files changed, 403 insertions, 332 deletions
diff --git a/Makefile b/Makefile
index 6f9ec6c..1380b09 100644
--- a/Makefile
+++ b/Makefile
@@ -2,7 +2,7 @@
VERSION=2.0
PROG= spectrogram
-SRCS= spectrogram.c sio.c fft.c cms.c aux.c
+SRCS= spectrogram.c sio.c fft.c cms.c aux.c widget.c
BINDIR= /usr/local/bin
HEADERS=sio.h fft.h cms.h aux.h
LIBS= fftw3 x11
diff --git a/cms.h b/cms.h
index 111b3ae..e98f576 100644
--- a/cms.h
+++ b/cms.h
@@ -18,6 +18,16 @@
#ifndef __CMS_H
#define __CMS_H
+/*
+struct hsl {
+ double h, s, l;
+};
+
+struct palette {
+ struct hsl from, to;
+};
+ */
+
__BEGIN_DECLS
void hsv2rgb(
unsigned short *r, unsigned short *g, unsigned short *b,
diff --git a/spectrogram.c b/spectrogram.c
index 96683a1..08ddb5d 100644
--- a/spectrogram.c
+++ b/spectrogram.c
@@ -17,117 +17,22 @@
#include <X11/Xlib.h>
#include <X11/Xutil.h>
-#include <X11/keysym.h>
-#include <sys/types.h>
-#include <sys/time.h>
-
-#include <assert.h>
#include <err.h>
-#include <math.h>
#include <signal.h>
-#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
-#include <string.h>
#include <unistd.h>
#include "aux.h"
#include "cms.h"
#include "fft.h"
#include "sio.h"
-
-#define HGAP 4
-#define VGAP 1
+#include "widget.h"
extern char *__progname;
int die = 0;
-struct pixmap {
- Pixmap pix;
- GC gc;
-};
-
-struct background {
- Pixmap pix;
- Pixmap mask;
- GC gc;
- XRectangle geo;
-};
-
-struct subwin {
- Window win;
- Pixmap pix; /* buffer */
- GC gc;
- XRectangle geo;
-};
-
-struct panel {
- Window win; /* container */
- struct subwin *wf;
- struct subwin *sp;
- struct background *bg;
- struct background *shadow;
- int mirror;
- int maxval;
- double *data;
- unsigned long *palette;
-};
-
-struct hsl {
- float h, s, l;
-};
-
-struct palette {
- struct hsl from, to;
-};
-
-enum mirror { LTR, RTL };
-
-struct palette p_spectr = {{ 120.0, 100.0, 75.0 }, { 0.0, 100.0, 25.0 }};
-struct palette p_shadow = {{ 120.0, 100.0, 10.0 }, { 0.0, 100.0, 10.0 }};
-struct palette p_waterfall = {{ 210.0, 75.0, 0.0 }, { 180.0, 100.0, 100.0 }};
-struct hsl hsl_gray = {0.0, 0.0, 20.0};
-
-unsigned long
-hslcolor(Display *d, struct hsl hsl)
-{
- int scr = DefaultScreen(d);
- Colormap cmap = DefaultColormap(d, scr);
- XColor c;
-
- hsl2rgb(&c.red, &c.green, &c.blue, hsl.h, hsl.s, hsl.l);
- c.flags = DoRed|DoGreen|DoBlue;
-
- XAllocColor(d, cmap, &c);
-
- return c.pixel;
-}
-
-unsigned long *
-init_palette(Display *d, struct palette pal, int n)
-{
- unsigned long *p;
- float hstep, sstep, lstep;
- int i;
-
- p = calloc(n, sizeof(unsigned long));
- assert(p);
-
- hstep = (pal.to.h - pal.from.h) / (n - 1);
- sstep = (pal.to.s - pal.from.s) / (n - 1);
- lstep = (pal.to.l - pal.from.l) / (n - 1);
-
- for (i = 0; i < n; i++) {
- p[i] = hslcolor(d, pal.from);
- pal.from.h += hstep;
- pal.from.s += sstep;
- pal.from.l += lstep;
- }
-
- return p;
-}
-
void
catch(int notused)
{
@@ -148,234 +53,6 @@ usage(void)
exit(0);
}
-void
-blit(Display *d, Drawable p, GC gc, XRectangle r)
-{
- XCopyArea(d, p, p, gc, 0, 0, r.width, r.height - 1, 0, 1);
-}
-
-void
-clear(Display *d, Drawable p, GC gc, XRectangle r)
-{
- XSetForeground(d, gc, BlackPixel(d, DefaultScreen(d)));
- XFillRectangle(d, p, gc, 0, 0, r.width, r.height);
-}
-
-void
-copy(Display *d, Drawable from, Drawable to, GC gc, XRectangle r, Drawable mask)
-{
- XSetClipMask(d, gc, mask);
- XCopyArea(d, from, to, gc, 0, 0, r.width, r.height, 0, 0);
- XSetClipMask(d, gc, None);
-}
-
-void
-draw_panel(Display *d, struct panel *p)
-{
- int i, v, x;
-
- /* blit waterfall */
- blit(d, p->wf->pix, p->wf->gc, p->wf->geo);
- /* blit shadow mask */
- blit(d, p->shadow->mask, p->shadow->gc, p->shadow->geo);
-
- /* clear spectrogram */
- clear(d, p->sp->pix, p->sp->gc, p->sp->geo);
- /* clear mask */
- clear(d, p->bg->mask, p->bg->gc, p->bg->geo);
-
- for (i = 0; i < p->sp->geo.width; i++) {
- /* limit maxval */
- v = p->data[i] >= p->maxval ? p->maxval - 1 : p->data[i];
- x = p->mirror ? p->sp->geo.width - i - 1 : i;
-
- /* draw waterfall */
- XSetForeground(d, p->wf->gc, p->palette[v]);
- XDrawPoint(d, p->wf->pix, p->wf->gc, x, 0);
-
- /* draw spectrogram */
- XSetForeground(d, p->bg->gc, 1);
- XDrawLine(d, p->bg->mask, p->bg->gc,
- x, p->bg->geo.height - v,
- x, p->bg->geo.height);
- }
-
- /* copy mask to shadow mask */
- copy(d, p->bg->mask, p->shadow->mask, p->shadow->gc, p->shadow->geo,
- p->bg->mask);
- /* shadow to buffer */
- copy(d, p->shadow->pix, p->sp->pix, p->sp->gc, p->sp->geo,
- p->shadow->mask);
- /* spectrogram to buffer */
- copy(d, p->bg->pix, p->sp->pix, p->sp->gc, p->sp->geo,
- p->bg->mask);
-}
-
-void
-flip(Display *d, struct subwin *p)
-{
- XCopyArea(d, p->pix, p->win, p->gc,
- 0, 0, p->geo.width, p->geo.height, 0, 0);
-}
-
-void
-flip_panel(Display *d, struct panel *p)
-{
- /* flip spectrogram */
- flip(d, p->sp);
- /* flip waterfall */
- flip(d, p->wf);
-}
-
-void
-draw_background(Display *d, Pixmap pix, GC gc, XRectangle r, unsigned long *pal)
-{
- int i, x, y;
-
- x = r.width - 1;
- for (i = 0; i < r.height; i++) {
- y = r.height - i - 1;
- XSetForeground(d, gc, pal[i]);
- XDrawLine(d, pix, gc, 0, y, x, y);
- }
-}
-
-struct background *
-init_background(Display *d, Drawable parent, XRectangle r)
-{
- struct background *p;
- int scr = DefaultScreen(d);
- int planes = DisplayPlanes(d, scr);
- int black = BlackPixel(d, scr);
-
- p = malloc(sizeof(struct subwin));
- assert(p);
-
- p->pix = XCreatePixmap(d, parent, r.width, r.height, planes);
- p->mask = XCreatePixmap(d, parent, r.width, r.height, 1);
- p->gc = XCreateGC(d, p->mask, 0, NULL);
- p->geo = r;
-
- /* clear */
- XSetForeground(d, p->gc, black);
- XFillRectangle(d, p->mask, p->gc, 0, 0, r.width, r.height);
-
- return p;
-}
-
-struct subwin *
-init_subwin(Display *d, Drawable parent, XRectangle r)
-{
- struct subwin *p;
- int scr = DefaultScreen(d);
- int white = WhitePixel(d, scr);
- int black = BlackPixel(d, scr);
- int planes = DisplayPlanes(d, scr);
-
- p = malloc(sizeof(struct subwin));
- assert(p);
-
- p->win = XCreateSimpleWindow(d, parent, r.x, r.y,
- r.width, r.height, 0, white, black);
- p->pix = XCreatePixmap(d, p->win, r.width, r.height, planes);
- p->gc = XCreateGC(d, p->pix, 0, NULL);
- p->geo = r;
-
- /* clear */
- XSetForeground(d, p->gc, black);
- XFillRectangle(d, p->pix, p->gc, 0, 0, r.width, r.height);
-
- XMapWindow(d, p->win);
-
- return p;
-}
-
-struct panel *
-init_panel(Display *d, Window win, XRectangle r, enum mirror m)
-{
- struct panel *p;
- int scr = DefaultScreen(d);
- unsigned long white = WhitePixel(d, scr);
- unsigned long gray = hslcolor(d, hsl_gray);
- unsigned long *palette;
- unsigned int maxval = r.height / 4;
- XRectangle geo;
-
- p = malloc(sizeof(struct panel));
- assert(p);
-
- p->data = calloc(2 * r.width, sizeof(double));
- assert(p->data);
-
- /* main panel window */
- p->win = XCreateSimpleWindow(d, win,
- r.x, r.y, r.width, r.height,
- 0, white, gray);
-
- /* sperctrogram window and its bitmasks */
- geo.x = 0;
- geo.y = 0;
- geo.width = r.width;
- geo.height = maxval;
- p->sp = init_subwin(d, p->win, geo);
-
- p->bg = init_background(d, p->sp->win, geo);
- palette = init_palette(d, p_spectr, maxval);
- draw_background(d, p->bg->pix, p->sp->gc, p->bg->geo, palette);
- free(palette);
-
- p->shadow = init_background(d, p->sp->win, geo);
- palette = init_palette(d, p_shadow, maxval);
- draw_background(d, p->shadow->pix, p->sp->gc, p->shadow->geo, palette);
- free(palette);
-
- p->palette = init_palette(d, p_waterfall, maxval);
- p->maxval = maxval;
- p->mirror = m;
-
- /* waterfall window and double buffer */
- geo.x = 0;
- geo.y = p->sp->geo.height + VGAP;
- geo.width = r.width;
- geo.height = r.height - maxval;
- p->wf = init_subwin(d, p->win, geo);
-
- XMapWindow(d, p->win);
-
- return p;
-}
-
-void
-free_background(Display *d, struct background *p)
-{
- XFreePixmap(d, p->pix);
- XFreePixmap(d, p->mask);
- XFreeGC(d, p->gc);
-}
-
-void
-free_subwin(Display *d, struct subwin *p)
-{
- XFreePixmap(d, p->pix);
- XFreeGC(d, p->gc);
- XUnmapWindow(d, p->win);
- XDestroyWindow(d, p->win);
-}
-
-void
-free_panel(Display *d, struct panel *p)
-{
- free_background(d, p->bg);
- free_background(d, p->shadow);
- free_subwin(d, p->sp);
- free_subwin(d, p->wf);
- XUnmapWindow(d, p->win);
- XDestroyWindow(d, p->win);
- free(p->palette);
- free(p->data);
- free(p);
-}
-
int
main(int argc, char **argv)
{
@@ -390,6 +67,7 @@ main(int argc, char **argv)
int scr;
struct panel *left, *right;
+ double *ldata, *rdata;
int dflag = 0; /* daemonize */
int fflag = 0; /* fullscreen */
@@ -494,12 +172,14 @@ main(int argc, char **argv)
geo.width = round / 2;
geo.height = height;
left = init_panel(dsp, container, geo, RTL);
+ ldata = dataptr(left);
geo.x = round / 2 + HGAP;
geo.y = 0;
geo.width = round / 2;
geo.height = height;
right = init_panel(dsp, container, geo, LTR);
+ rdata = dataptr(right);
XClearWindow(dsp, win);
XMapRaised(dsp, win); /* XMapWindow */
@@ -523,14 +203,14 @@ main(int argc, char **argv)
die = 1;
break;
case XK_1:
- left->mirror ^= 1;
+ toggle_mirror(left);
break;
case XK_2:
- right->mirror ^= 1;
+ toggle_mirror(right);
break;
case XK_3:
- left->mirror ^= 1;
- right->mirror ^= 1;
+ toggle_mirror(left);
+ toggle_mirror(right);
break;
default:
break;
@@ -547,10 +227,10 @@ main(int argc, char **argv)
}
}
- read_sio(left->data, right->data, round);
+ read_sio(ldata, rdata, round);
- exec_fft(left->data);
- exec_fft(right->data);
+ exec_fft(ldata);
+ exec_fft(rdata);
draw_panel(dsp, left);
draw_panel(dsp, right);
diff --git a/widget.c b/widget.c
new file mode 100644
index 0000000..e0b9921
--- /dev/null
+++ b/widget.c
@@ -0,0 +1,310 @@
+/* $Id$ */
+/*
+ * Copyright (c) 2010 Dimitri Sokolyuk <demon@dim13.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <X11/Xlib.h>
+
+#include <assert.h>
+#include <stdlib.h>
+
+#include "widget.h"
+#include "cms.h"
+
+struct palette p_spectr = {{ 120.0, 100.0, 75.0 }, { 0.0, 100.0, 25.0 }};
+struct palette p_shadow = {{ 120.0, 100.0, 10.0 }, { 0.0, 100.0, 10.0 }};
+struct palette p_waterfall = {{ 210.0, 75.0, 0.0 }, { 180.0, 100.0, 100.0 }};
+
+struct hsl hsl_gray = {0.0, 0.0, 20.0};
+
+unsigned long
+hslcolor(Display *d, struct hsl hsl)
+{
+ int scr = DefaultScreen(d);
+ Colormap cmap = DefaultColormap(d, scr);
+ XColor c;
+
+ hsl2rgb(&c.red, &c.green, &c.blue, hsl.h, hsl.s, hsl.l);
+ c.flags = DoRed|DoGreen|DoBlue;
+
+ XAllocColor(d, cmap, &c);
+
+ return c.pixel;
+}
+
+unsigned long *
+init_palette(Display *d, struct palette pal, int n)
+{
+ unsigned long *p;
+ float hstep, sstep, lstep;
+ int i;
+
+ p = calloc(n, sizeof(unsigned long));
+ assert(p);
+
+ hstep = (pal.to.h - pal.from.h) / (n - 1);
+ sstep = (pal.to.s - pal.from.s) / (n - 1);
+ lstep = (pal.to.l - pal.from.l) / (n - 1);
+
+ for (i = 0; i < n; i++) {
+ p[i] = hslcolor(d, pal.from);
+ pal.from.h += hstep;
+ pal.from.s += sstep;
+ pal.from.l += lstep;
+ }
+
+ return p;
+}
+
+
+static void
+blit(Display *d, Drawable p, GC gc, XRectangle r)
+{
+ XCopyArea(d, p, p, gc, 0, 0, r.width, r.height - 1, 0, 1);
+}
+
+static void
+clear(Display *d, Drawable p, GC gc, XRectangle r)
+{
+ XSetForeground(d, gc, BlackPixel(d, DefaultScreen(d)));
+ XFillRectangle(d, p, gc, 0, 0, r.width, r.height);
+}
+
+static void
+copy(Display *d, Drawable from, Drawable to, GC gc, XRectangle r, Drawable mask)
+{
+ XSetClipMask(d, gc, mask);
+ XCopyArea(d, from, to, gc, 0, 0, r.width, r.height, 0, 0);
+ XSetClipMask(d, gc, None);
+}
+
+void
+draw_panel(Display *d, struct panel *p)
+{
+ int i, v, x;
+
+ /* blit waterfall */
+ blit(d, p->wf->pix, p->wf->gc, p->wf->geo);
+ /* blit shadow mask */
+ blit(d, p->shadow->mask, p->shadow->gc, p->shadow->geo);
+
+ /* clear spectrogram */
+ clear(d, p->sp->pix, p->sp->gc, p->sp->geo);
+ /* clear mask */
+ clear(d, p->bg->mask, p->bg->gc, p->bg->geo);
+
+ for (i = 0; i < p->sp->geo.width; i++) {
+ /* limit maxval */
+ v = p->data[i] >= p->maxval ? p->maxval - 1 : p->data[i];
+ x = p->mirror ? p->sp->geo.width - i - 1 : i;
+
+ /* draw waterfall */
+ XSetForeground(d, p->wf->gc, p->palette[v]);
+ XDrawPoint(d, p->wf->pix, p->wf->gc, x, 0);
+
+ /* draw spectrogram */
+ XSetForeground(d, p->bg->gc, 1);
+ XDrawLine(d, p->bg->mask, p->bg->gc,
+ x, p->bg->geo.height - v,
+ x, p->bg->geo.height);
+ }
+
+ /* copy mask to shadow mask */
+ copy(d, p->bg->mask, p->shadow->mask, p->shadow->gc, p->shadow->geo,
+ p->bg->mask);
+ /* shadow to buffer */
+ copy(d, p->shadow->pix, p->sp->pix, p->sp->gc, p->sp->geo,
+ p->shadow->mask);
+ /* spectrogram to buffer */
+ copy(d, p->bg->pix, p->sp->pix, p->sp->gc, p->sp->geo,
+ p->bg->mask);
+}
+
+static void
+flip(Display *d, struct subwin *p)
+{
+ XCopyArea(d, p->pix, p->win, p->gc,
+ 0, 0, p->geo.width, p->geo.height, 0, 0);
+}
+
+void
+flip_panel(Display *d, struct panel *p)
+{
+ /* flip spectrogram */
+ flip(d, p->sp);
+ /* flip waterfall */
+ flip(d, p->wf);
+}
+
+static void
+draw_background(Display *d, Pixmap pix, GC gc, XRectangle r, unsigned long *pal)
+{
+ int i, x, y;
+
+ x = r.width - 1;
+ for (i = 0; i < r.height; i++) {
+ y = r.height - i - 1;
+ XSetForeground(d, gc, pal[i]);
+ XDrawLine(d, pix, gc, 0, y, x, y);
+ }
+}
+
+static struct background *
+init_background(Display *d, Drawable parent, XRectangle r)
+{
+ struct background *p;
+ int scr = DefaultScreen(d);
+ int planes = DisplayPlanes(d, scr);
+ int black = BlackPixel(d, scr);
+
+ p = malloc(sizeof(struct subwin));
+ assert(p);
+
+ p->pix = XCreatePixmap(d, parent, r.width, r.height, planes);
+ p->mask = XCreatePixmap(d, parent, r.width, r.height, 1);
+ p->gc = XCreateGC(d, p->mask, 0, NULL);
+ p->geo = r;
+
+ /* clear */
+ XSetForeground(d, p->gc, black);
+ XFillRectangle(d, p->mask, p->gc, 0, 0, r.width, r.height);
+
+ return p;
+}
+
+static struct subwin *
+init_subwin(Display *d, Drawable parent, XRectangle r)
+{
+ struct subwin *p;
+ int scr = DefaultScreen(d);
+ int white = WhitePixel(d, scr);
+ int black = BlackPixel(d, scr);
+ int planes = DisplayPlanes(d, scr);
+
+ p = malloc(sizeof(struct subwin));
+ assert(p);
+
+ p->win = XCreateSimpleWindow(d, parent, r.x, r.y,
+ r.width, r.height, 0, white, black);
+ p->pix = XCreatePixmap(d, p->win, r.width, r.height, planes);
+ p->gc = XCreateGC(d, p->pix, 0, NULL);
+ p->geo = r;
+
+ /* clear */
+ XSetForeground(d, p->gc, black);
+ XFillRectangle(d, p->pix, p->gc, 0, 0, r.width, r.height);
+
+ XMapWindow(d, p->win);
+
+ return p;
+}
+
+struct panel *
+init_panel(Display *d, Window win, XRectangle r, enum mirror m)
+{
+ struct panel *p;
+ int scr = DefaultScreen(d);
+ unsigned long white = WhitePixel(d, scr);
+ unsigned long gray = hslcolor(d, hsl_gray);
+ unsigned long *palette;
+ unsigned int maxval = r.height / 4;
+ XRectangle geo;
+
+ p = malloc(sizeof(struct panel));
+ assert(p);
+
+ p->data = calloc(2 * r.width, sizeof(double));
+ assert(p->data);
+
+ /* main panel window */
+ p->win = XCreateSimpleWindow(d, win,
+ r.x, r.y, r.width, r.height,
+ 0, white, gray);
+
+ /* sperctrogram window and its bitmasks */
+ geo.x = 0;
+ geo.y = 0;
+ geo.width = r.width;
+ geo.height = maxval;
+ p->sp = init_subwin(d, p->win, geo);
+
+ p->bg = init_background(d, p->sp->win, geo);
+ palette = init_palette(d, p_spectr, maxval);
+ draw_background(d, p->bg->pix, p->sp->gc, p->bg->geo, palette);
+ free(palette);
+
+ p->shadow = init_background(d, p->sp->win, geo);
+ palette = init_palette(d, p_shadow, maxval);
+ draw_background(d, p->shadow->pix, p->sp->gc, p->shadow->geo, palette);
+ free(palette);
+
+ p->palette = init_palette(d, p_waterfall, maxval);
+ p->maxval = maxval;
+ p->mirror = m;
+
+ /* waterfall window and double buffer */
+ geo.x = 0;
+ geo.y = p->sp->geo.height + VGAP;
+ geo.width = r.width;
+ geo.height = r.height - maxval;
+ p->wf = init_subwin(d, p->win, geo);
+
+ XMapWindow(d, p->win);
+
+ return p;
+}
+
+static void
+free_background(Display *d, struct background *p)
+{
+ XFreePixmap(d, p->pix);
+ XFreePixmap(d, p->mask);
+ XFreeGC(d, p->gc);
+}
+
+static void
+free_subwin(Display *d, struct subwin *p)
+{
+ XFreePixmap(d, p->pix);
+ XFreeGC(d, p->gc);
+ XUnmapWindow(d, p->win);
+ XDestroyWindow(d, p->win);
+}
+
+void
+free_panel(Display *d, struct panel *p)
+{
+ free_background(d, p->bg);
+ free_background(d, p->shadow);
+ free_subwin(d, p->sp);
+ free_subwin(d, p->wf);
+ XUnmapWindow(d, p->win);
+ XDestroyWindow(d, p->win);
+ free(p->palette);
+ free(p->data);
+ free(p);
+}
+
+void
+toggle_mirror(struct panel *p)
+{
+ p->mirror ^= 1;
+}
+
+double *
+dataptr(struct panel *p)
+{
+ return p->data;
+}
diff --git a/widget.h b/widget.h
new file mode 100644
index 0000000..002db22
--- /dev/null
+++ b/widget.h
@@ -0,0 +1,71 @@
+/* $Id$ */
+/*
+ * Copyright (c) 2010 Dimitri Sokolyuk <demon@dim13.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef _WIDGET_H
+#define _WIDGET_H
+
+#define HGAP 4
+#define VGAP 1
+
+struct background {
+ Pixmap pix;
+ Pixmap mask;
+ GC gc;
+ XRectangle geo;
+};
+
+struct subwin {
+ Window win;
+ Pixmap pix; /* buffer */
+ GC gc;
+ XRectangle geo;
+};
+
+struct panel {
+ Window win; /* container */
+ struct subwin *wf;
+ struct subwin *sp;
+ struct background *bg;
+ struct background *shadow;
+ int mirror;
+ int maxval;
+ double *data;
+ unsigned long *palette;
+};
+
+struct hsl {
+ float h, s, l;
+};
+
+struct palette {
+ struct hsl from, to;
+};
+
+enum mirror { LTR, RTL };
+
+__BEGIN_DECLS
+unsigned long hslcolor(Display *, struct hsl);
+unsigned long *init_palette(Display *, struct palette, int);
+void draw_panel(Display *, struct panel *);
+void flip_panel(Display *, struct panel *);
+struct panel *init_panel(Display *, Window, XRectangle, enum mirror);
+void free_panel(Display *, struct panel *);
+void toggle_mirror(struct panel *);
+double *dataptr(struct panel *);
+__END_DECLS
+
+#endif