/*
X11 underwaved text example by
Usage: gcc -lX11 underwave.c && ./a.out
Press ESC to quit, any other key to change the strings
*/
#include
#include
#include
#include
#include
#include
#define RAND(min,max) (rand()%((max)-(min))+(min))
#define FONT_NAME "-*-fixed-*-*-*-*-13-*-*-*-*-*-iso8859-*"
#define WAVE_COLOR "red"
#define WAVE_HEIGHT 2
#define WAVE_THICK 1
Window win;
Display* dpy;
GC gc;
int screen;
int width, height;
XFontStruct* font_info;
char* font_name = FONT_NAME;
int font_height;
int seed = 42;
unsigned long undercolor, black;
void init (int w, int h)
{
XColor color;
Colormap cmap;
unsigned int line_width = WAVE_THICK;
int line_style = LineSolid;
int cap_style = CapButt;
int join_style = JoinBevel;
width = w, height = h;
dpy = XOpenDisplay(NULL);
if(!dpy)
puts("err: XOpenDisplay"), exit(1);
screen = XDefaultScreen(dpy);
win = XCreateSimpleWindow(dpy, RootWindow(dpy, screen),
100, 100, width, height, 0,
BlackPixel(dpy, screen),
WhitePixel(dpy, screen));
cmap = XDefaultColormap(dpy, screen);
black = BlackPixel(dpy, screen);
XAllocNamedColor(dpy, cmap, WAVE_COLOR, &color, &color);
undercolor = color.pixel;
gc = XCreateGC(dpy, win, 0, NULL);
XSetForeground(dpy, gc, BlackPixel(dpy, screen));
XSetBackground(dpy, gc, WhitePixel(dpy, screen));
XSetLineAttributes(dpy, gc, line_width, line_style, cap_style, join_style);
font_info = XLoadQueryFont(dpy, font_name);
XSetFont(dpy, gc, font_info->fid);
font_height = font_info->ascent + font_info->descent;
}
void draw_wave (int x0, int y0, int w)
{
int dx = WAVE_HEIGHT;
int dy = dx/2;
int x1, y1, x2, y2, i, times = w/dx;
for(i = 0; i < times; i++) {
x1 = x0 + i*dx;
y1 = y0 + (i%2 ? 1 : -1) * dy;
x2 = x0 + (i+1)*dx;
y2 = y0 + ((i+1)%2 ? 1 : -1) * dy;
XDrawLine(dpy, win, gc, x1, y1, x2, y2);
}
}
void draw_underwave_string (char* str, int y)
{
int len = strlen(str);
int w = XTextWidth(font_info, str, len);
int x = (width-w)/2;
XSetForeground(dpy, gc, black);
XDrawString(dpy, win, gc, x, y+font_info->ascent, str, len);
XSetForeground(dpy, gc, undercolor);
draw_wave(x, y+font_height, w);
}
void draw (void)
{
char buf[256];
int i, j, y, n = 20;
srand(seed);
XClearWindow(dpy, win);
for(i = 1; i <= n; i++) {
y = (height-font_height*1.5*n)/2+font_height*1.5*i;
/* random ascii string */
memset(buf, 0, sizeof buf);
for(j = 0; j < i; j++)
buf[j] = RAND(32, 126);
buf[j] = 0;
draw_underwave_string(buf, y);
}
}
int main (void)
{
int done = 0;
XEvent e;
int mask = ExposureMask | KeyPressMask | StructureNotifyMask;
init(300, 300);
XSelectInput(dpy, win, mask);
XMapWindow(dpy, win);
while (!done) {
XNextEvent(dpy, &e);
switch (e.type) {
case Expose:
draw();
break;
case ConfigureNotify:
width = e.xconfigure.width;
height = e.xconfigure.height;
draw();
break;
case KeyPress:
if(XLookupKeysym(&e.xkey, 0) == XK_Escape)
done = 1;
else {
seed = time(NULL)+rand();
draw();
}
break;
}
}
XFreeGC(dpy, gc);
XCloseDisplay(dpy);
return 0;
}