/* 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; }