How to use XLib to implement animation

Animation Example

The mainframe of following example is same as the one given before. The difference is marked in red.

#include <X11/Xlib.h>

#include <X11/Xutil.h>

#include <stdio.h>

#include <unistd.h>

#include <math.h>

 

#define WIN_WIDTH   640

#define WIN_HEIGHT  480

 

unsigned long GetColor( Display* dis, char* color_name )

{

    Colormap cmap;

    XColor near_color, true_color;

 

    cmap = DefaultColormap( dis, 0 );

    XAllocNamedColor( dis, cmap, color_name, &near_color, &true_color );

    return( near_color.pixel );

}

 

int main( void )

{

    Display* dis;

    Window win;

    XSetWindowAttributes att;

    GC gc;

    XEvent ev;

 

    int t;

 

    dis = XOpenDisplay( NULL );

    win = XCreateSimpleWindow( dis, RootWindow(dis,0), 100, 100,

      WIN_WIDTH, WIN_HEIGHT, 5, WhitePixel(dis,0), BlackPixel(dis,0) );

 

    att.backing_store = WhenMapped;

    XChangeWindowAttributes( dis, win, CWBackingStore, &att );

 

    XSelectInput( dis, win, ExposureMask );

    XMapWindow( dis, win );

 

    do{

        XNextEvent( dis, &ev);

    }while( ev.type != Expose );

 

    gc = XCreateGC( dis, DefaultRootWindow(dis), 0, 0 );

    XSetFunction( dis, gc, GXxor );

   

    for (int t = 0; t < 100; t++)

    {

           XSetForeground( dis, gc, BlackPixel(dis, 0)^GetColor( dis, "red"));

           XFillArc( dis, win, gc, t*5+80, t*3+40, 80, 40, 0, 360*64);

           XSetForeground( dis, gc, BlackPixel(dis, 0)^GetColor( dis, "red"));

        usleep(200000);

           XFillArc( dis, win, gc, t*5+80, t*3+40, 80, 40, 0, 360*64);

    }

      

    XDestroyWindow( dis , win );

    XCloseDisplay( dis );

    return(0);

}

How to implement animation

Suppose your background color is bkColor and your foreground color (used to draw graphics) is frColor. In the above example, bkColor is BlackPixel(dis,0) and frColor is GetColor(dis, “red”), which means the background is black and foreground is red. “^” means “exclusive or” operation. The steps of implementing animation are:

1.         Set your foreground color with color bkColor^frColor: XSetForeground( dis, gc, bkColor^frColor)

2.         Draw your graphics;

3.         Set your foreground with color bkColor^frColor again. This setting is necessary. If you don’t set the color again, all that you draw in 2 will not be displayed.

4.         Delay for a few seconds.

5.         Draw the graphics you draw in 2 again. After doing this, the graphics in 2 will be erased.

 

Why it works

If the background color is set to be bkColor and the foreground color is set to be frColor, then draw a object on the screen using functions of XLib (such as XDrawLIne). The object will be displayed with color bkColor^frColor.

Additionally exclusive operator has an important property: (a ^ a ^ b) = b. So when we set foreground color to be bkColor^frColor, the object will be in color bkColor^(bkColor^frColor) = frColor.

For example, we draw a filled rectangle. We set the foreground color to be bkColor^frColor, then the rectangle will be in frColor color. The background color of region in the rectangle is frColor now. We set the foreground color with bkColor^frColor and draw the rectangle again, then the background color of region in the rectangle will be bkColor, which seems that the rectangle is erased.

About Colors

You can get appropriate color with function GetColor(dis,”colorname”). This function is not provided by XLib, but the implementation is given in the above example. All the names of colors you can use are listed in file /usr/X/lib/X11/rgb.txt.